diff --git a/.cproject b/.cproject
index ed10f0f5e..d4a5780c3 100644
--- a/.cproject
+++ b/.cproject
@@ -37,6 +37,7 @@
+
diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c
index 5dcfeac3b..a4f4aac96 100644
--- a/coreapi/bellesip_sal/sal_impl.c
+++ b/coreapi/bellesip_sal/sal_impl.c
@@ -56,7 +56,7 @@ void sal_enable_logs(){
void sal_disable_logs() {
belle_sip_set_log_level(BELLE_SIP_LOG_ERROR);
}
-static void sal_add_pending_auth(Sal *sal, SalOp *op){
+void sal_add_pending_auth(Sal *sal, SalOp *op){
if (ms_list_find(sal->pending_auths,op)==NULL){
sal->pending_auths=ms_list_append(sal->pending_auths,sal_op_ref(op));
}
@@ -99,9 +99,7 @@ void sal_process_authentication(SalOp *op) {
}
if (op->auth_info) sal_auth_info_delete(op->auth_info);
auth_event=(belle_sip_auth_event_t*)(auth_list->data);
- op->auth_info=sal_auth_info_new();
- op->auth_info->realm = ms_strdup(belle_sip_auth_event_get_realm(auth_event)) ;
- op->auth_info->username = ms_strdup(belle_sip_auth_event_get_username(auth_event)) ;
+ op->auth_info=sal_auth_info_create(auth_event);
belle_sip_list_free_with_data(auth_list,(void (*)(void*))belle_sip_auth_event_destroy);
}
@@ -640,3 +638,20 @@ void sal_set_dns_timeout(Sal* sal,int timeout) {
int sal_get_dns_timeout(const Sal* sal) {
return belle_sip_stack_get_dns_timeout(sal->stack);
}
+
+SalAuthInfo* sal_auth_info_create(belle_sip_auth_event_t* event) {
+ SalAuthInfo* auth_info = sal_auth_info_new();
+ auth_info->realm = ms_strdup(belle_sip_auth_event_get_realm(event)) ;
+ auth_info->username = ms_strdup(belle_sip_auth_event_get_username(event)) ;
+ return auth_info;
+}
+const char* sal_op_type_to_string(const SalOpType_t type) {
+ switch(type) {
+ case SalOpRegister: return "SalOpRegister";
+ case SalOpCall: return "SalOpCall";
+ case SalOpMessage: return "SalOpMessage";
+ case SalOpPresence: return "SalOpPresence";
+ default:
+ return "SalOpUnknown";
+ }
+}
diff --git a/coreapi/bellesip_sal/sal_impl.h b/coreapi/bellesip_sal/sal_impl.h
index 56b5bd514..cb5459864 100644
--- a/coreapi/bellesip_sal/sal_impl.h
+++ b/coreapi/bellesip_sal/sal_impl.h
@@ -55,13 +55,21 @@ typedef enum SalOpDir {
SalOpDirIncoming=0
,SalOpDirOutgoing
}SalOpDir_t;
+typedef enum SalOpType {
+ SalOpUnknown,
+ SalOpRegister,
+ SalOpCall,
+ SalOpMessage,
+ SalOpPresence
+}SalOpType_t;
+const char* sal_op_type_to_string(const SalOpType_t type);
struct SalOp{
SalOpBase base;
belle_sip_listener_callbacks_t callbacks;
belle_sip_client_transaction_t *pending_auth_transaction;
belle_sip_server_transaction_t* pending_server_trans;
- belle_sip_client_transaction_t* pending_inv_client_trans;
+ belle_sip_client_transaction_t* pending_client_trans;
SalAuthInfo* auth_info;
belle_sip_refresher_t* registration_refresher;
bool_t sdp_offering;
@@ -76,6 +84,7 @@ struct SalOp{
SalOpDir_t dir;
belle_sip_refresher_t* refresher;
int ref;
+ SalOpType_t type;
};
belle_sdp_session_description_t * media_description_to_sdp(const SalMediaDescription *sal);
@@ -108,4 +117,7 @@ void sal_op_message_fill_cbs(SalOp*op);
/*call transfert*/
void sal_op_process_refer(SalOp *op, const belle_sip_request_event_t *event);
void sal_op_call_process_notify(SalOp *op, const belle_sip_request_event_t *event);
+/*create SalAuthInfo by copying username and realm from suth event*/
+SalAuthInfo* sal_auth_info_create(belle_sip_auth_event_t* event) ;
+void sal_add_pending_auth(Sal *sal, SalOp *op);
#endif /* SAL_IMPL_H_ */
diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c
index 7f360710f..0bf1f2440 100644
--- a/coreapi/bellesip_sal/sal_op_call.c
+++ b/coreapi/bellesip_sal/sal_op_call.c
@@ -183,7 +183,7 @@ static void handle_sdp_from_response(SalOp* op,belle_sip_response_t* response) {
static void cancelling_invite(SalOp* op ){
belle_sip_request_t* cancel;
ms_message("Cancelling INVITE requets from [%s] to [%s] ",sal_op_get_from(op), sal_op_get_to(op));
- cancel = belle_sip_client_transaction_create_cancel(op->pending_inv_client_trans);
+ cancel = belle_sip_client_transaction_create_cancel(op->pending_client_trans);
sal_op_send_request(op,cancel);
op->state=SalOpStateTerminating;
}
@@ -527,6 +527,7 @@ static void sal_op_fill_invite(SalOp *op, belle_sip_request_t* invite) {
int sal_call(SalOp *op, const char *from, const char *to){
belle_sip_request_t* invite;
op->dir=SalOpDirOutgoing;
+
sal_op_set_from(op,from);
sal_op_set_to(op,to);
@@ -553,6 +554,7 @@ void sal_op_call_fill_cbs(SalOp*op) {
op->callbacks.process_transaction_terminated=call_process_transaction_terminated;
op->callbacks.process_request_event=process_request_event;
op->callbacks.process_dialog_terminated=process_dialog_terminated;
+ op->type=SalOpCall;
}
static void handle_offer_answer_response(SalOp* op, belle_sip_response_t* response) {
if (op->base.local_media){
@@ -702,8 +704,8 @@ int sal_call_terminate(SalOp *op){
if (op->dir == SalOpDirIncoming) {
sal_call_decline(op, SalReasonDeclined,NULL);
op->state=SalOpStateTerminated;
- } else if (op->pending_inv_client_trans
- && belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(op->pending_inv_client_trans)) == BELLE_SIP_TRANSACTION_PROCEEDING){
+ } else if (op->pending_client_trans
+ && belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(op->pending_client_trans)) == BELLE_SIP_TRANSACTION_PROCEEDING){
cancelling_invite(op);
break;
} else {
diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c
index 2f9b8484d..e42c827f1 100644
--- a/coreapi/bellesip_sal/sal_op_impl.c
+++ b/coreapi/bellesip_sal/sal_op_impl.c
@@ -23,33 +23,43 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
SalOp * sal_op_new(Sal *sal){
SalOp *op=ms_new0(SalOp,1);
__sal_op_init(op,sal);
+ op->type=SalOpUnknown;
sal_op_ref(op);
return op;
}
void sal_op_release(SalOp *op){
op->state=SalOpStateTerminated;
+ sal_op_set_user_pointer(op,NULL);/*mandatory because releasing op doesn not mean freeing op. Make sure back pointer will not be used later*/
+ if (op->registration_refresher) belle_sip_refresher_stop(op->registration_refresher);
+ if (op->refresher) belle_sip_refresher_stop(op->refresher);
sal_op_unref(op);
}
void sal_op_release_impl(SalOp *op){
- ms_message("Destroying op [%p]",op);
+ ms_message("Destroying op [%p] of type [%s]",op,sal_op_type_to_string(op->type));
if (op->pending_auth_transaction) belle_sip_object_unref(op->pending_auth_transaction);
if (op->auth_info) sal_auth_info_delete(op->auth_info);
if (op->sdp_answer) belle_sip_object_unref(op->sdp_answer);
if (op->registration_refresher) {
belle_sip_refresher_stop(op->registration_refresher);
belle_sip_object_unref(op->registration_refresher);
+ op->registration_refresher=NULL;
}
if(op->replaces) belle_sip_object_unref(op->replaces);
if(op->referred_by) belle_sip_object_unref(op->referred_by);
- if (op->pending_inv_client_trans) belle_sip_object_unref(op->pending_inv_client_trans);
+ if (op->pending_client_trans) belle_sip_object_unref(op->pending_client_trans);
__sal_op_free(op);
return ;
}
void sal_op_authenticate(SalOp *op, const SalAuthInfo *info){
- /*for sure auth info will be accesible from the provider*/
- sal_process_authentication(op);
+ if (op->type == SalOpRegister) {
+ /*Registration authenticate is just about registering again*/
+ sal_register_refresh(op,-1);
+ }else {
+ /*for sure auth info will be accesible from the provider*/
+ sal_process_authentication(op);
+ }
return ;
}
@@ -165,10 +175,10 @@ static int _sal_op_send_request_with_contact(SalOp* op, belle_sip_request_t* req
client_transaction = belle_sip_provider_create_client_transaction(prov,request);
belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(client_transaction),sal_op_ref(op));
- if ( strcmp("INVITE",belle_sip_request_get_method(request))==0) {
- if (op->pending_inv_client_trans) belle_sip_object_unref(op->pending_inv_client_trans);
- op->pending_inv_client_trans=client_transaction; /*update pending inv for being able to cancel*/
- belle_sip_object_ref(op->pending_inv_client_trans);
+ if ( strcmp("INVITE",belle_sip_request_get_method(request))==0 || strcmp("REGISTER",belle_sip_request_get_method(request))==0) {
+ if (op->pending_client_trans) belle_sip_object_unref(op->pending_client_trans);
+ op->pending_client_trans=client_transaction; /*update pending inv for being able to cancel*/
+ belle_sip_object_ref(op->pending_client_trans);
}
if (add_contact) {
contact = sal_op_create_contact(op,belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(request),belle_sip_header_from_t));
diff --git a/coreapi/bellesip_sal/sal_op_message.c b/coreapi/bellesip_sal/sal_op_message.c
index 826246a28..a1e8a3e54 100644
--- a/coreapi/bellesip_sal/sal_op_message.c
+++ b/coreapi/bellesip_sal/sal_op_message.c
@@ -151,4 +151,5 @@ void sal_op_message_fill_cbs(SalOp*op) {
op->callbacks.process_response_event=process_response_event;
op->callbacks.process_timeout=process_timeout;
op->callbacks.process_request_event=process_request_event;
+ op->type=SalOpMessage;
}
diff --git a/coreapi/bellesip_sal/sal_op_presence.c b/coreapi/bellesip_sal/sal_op_presence.c
index fe0597c20..dd5e7917c 100644
--- a/coreapi/bellesip_sal/sal_op_presence.c
+++ b/coreapi/bellesip_sal/sal_op_presence.c
@@ -573,6 +573,7 @@ void sal_op_presence_fill_cbs(SalOp*op) {
op->callbacks.process_transaction_terminated=presence_process_transaction_terminated;
op->callbacks.process_request_event=presence_process_request_event;
op->callbacks.process_dialog_terminated=presence_process_dialog_terminated;
+ op->type=SalOpPresence;
}
/*presence publish */
diff --git a/coreapi/bellesip_sal/sal_op_registration.c b/coreapi/bellesip_sal/sal_op_registration.c
index 5ae44d93e..20b753330 100644
--- a/coreapi/bellesip_sal/sal_op_registration.c
+++ b/coreapi/bellesip_sal/sal_op_registration.c
@@ -19,15 +19,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "sal_impl.h"
-
-static void register_process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){
- SalOp* op = (SalOp*)user_ctx;
- ms_error("register_process_io_error io error reported for [%s]",sal_op_get_proxy(op));
- if (op->registration_refresher) {
- op->base.root->callbacks.register_failure(op,SalErrorFailure,SalErrorFailure,"io error");
- }
-}
-
static void register_refresher_listener ( const belle_sip_refresher_t* refresher
,void* user_pointer
,unsigned int status_code
@@ -35,79 +26,49 @@ static void register_refresher_listener ( const belle_sip_refresher_t* refresher
SalOp* op = (SalOp*)user_pointer;
SalError sal_err;
SalReason sal_reason;
+ belle_sip_response_t* response=belle_sip_transaction_get_response(BELLE_SIP_TRANSACTION(belle_sip_refresher_get_transaction(refresher)));
ms_message("Register refresher [%i] reason [%s] for proxy [%s]",status_code,reason_phrase,sal_op_get_proxy(op));
- if(status_code ==200) {
- op->base.root->callbacks.register_success(op,belle_sip_refresher_get_expires(op->registration_refresher)>0);
- } else if (status_code>=400) {
- sal_compute_sal_errors_from_code(status_code,&sal_err,&sal_reason);
- op->base.root->callbacks.register_failure(op,sal_err,sal_reason,reason_phrase);
- } else {
- ms_warning("Register refresher know what to do with this status code");
+ /*fix contact if needed*/
+ if (op->base.root->nat_helper_enabled && belle_sip_refresher_get_nated_contact(refresher)) {
+ belle_sip_header_address_t* contact_address = BELLE_SIP_HEADER_ADDRESS(belle_sip_object_clone(BELLE_SIP_OBJECT(belle_sip_refresher_get_nated_contact(refresher))));
+ sal_op_set_contact_address(op,(SalAddress*)contact_address);
+ belle_sip_object_unref(contact_address);
}
-}
-
-static void register_response_event(void *user_ctx, const belle_sip_response_event_t *event){
- belle_sip_client_transaction_t* client_transaction = belle_sip_response_event_get_client_transaction(event);
- SalOp* op = (SalOp*)belle_sip_transaction_get_application_data(BELLE_SIP_TRANSACTION(client_transaction));
- belle_sip_response_t* response = belle_sip_response_event_get_response(event);
- belle_sip_header_service_route_t* service_route;
- belle_sip_header_address_t* service_route_address=NULL;
-
- int response_code = belle_sip_response_get_status_code(response);
- if (response_code<200) return;/*nothing to do*/
-
-
- switch (response_code) {
- case 200: {
-
+ if(status_code ==200) {
/*check service route rfc3608*/
+ belle_sip_header_service_route_t* service_route;
+ belle_sip_header_address_t* service_route_address=NULL;
if ((service_route=belle_sip_message_get_header_by_type(response,belle_sip_header_service_route_t))) {
service_route_address=belle_sip_header_address_create(NULL,belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(service_route)));
}
sal_op_set_service_route(op,(const SalAddress*)service_route_address);
if (service_route_address) belle_sip_object_unref(service_route_address);
-
- op->base.root->callbacks.register_success(op,TRUE);
-
- if (/*expires>0 &&*/ !op->registration_refresher) {
- op->registration_refresher = belle_sip_client_transaction_create_refresher(client_transaction);
- belle_sip_refresher_set_listener(op->registration_refresher,register_refresher_listener,op);
- }
-
- break;
- }
-
- default:{
-
+ op->base.root->callbacks.register_success(op,belle_sip_refresher_get_expires(op->registration_refresher)>0);
+ } else if (status_code>=400) {
/* from rfc3608, 6.1.
- If the UA refreshes the registration, the stored value of the Service-
- Route is updated according to the Service-Route header field of the
- latest 200 class response. If there is no Service-Route header field
- in the response, the UA clears any service route for that address-
- of-record previously stored by the UA. If the re-registration
- request is refused or if an existing registration expires and the UA
- chooses not to re-register, the UA SHOULD discard any stored service
- route for that address-of-record. */
+ If the UA refreshes the registration, the stored value of the Service-
+ Route is updated according to the Service-Route header field of the
+ latest 200 class response. If there is no Service-Route header field
+ in the response, the UA clears any service route for that address-
+ of-record previously stored by the UA. If the re-registration
+ request is refused or if an existing registration expires and the UA
+ chooses not to re-register, the UA SHOULD discard any stored service
+ route for that address-of-record. */
sal_op_set_service_route(op,NULL);
- ms_error("Unexpected answer [%s] for registration request bound to [%s]",belle_sip_response_get_reason_phrase(response),op->base.from);
- op->base.root->callbacks.register_failure(op,SalErrorFailure,SalReasonUnknown,belle_sip_response_get_reason_phrase(response));
- break;
- }
-}
-}
-static void register_process_timeout(void *user_ctx, const belle_sip_timeout_event_t *event) {
- SalOp* op = (SalOp*)user_ctx;
- ms_error("register_process_timeout timeout error reported for [%s]",sal_op_get_proxy(op));
- if (!op->registration_refresher) {
- op->base.root->callbacks.register_failure(op,SalErrorNoResponse,SalReasonUnknown,"Request Timeout");
+ sal_compute_sal_errors_from_code(status_code,&sal_err,&sal_reason);
+ if (belle_sip_refresher_get_auth_events(refresher) && (status_code == 401 || status_code==407)) {
+ /*add pending auth*/
+ sal_add_pending_auth(op->base.root,op);
+ if (op->auth_info) sal_auth_info_delete(op->auth_info);
+ /*only take first one for now*/
+ op->auth_info=sal_auth_info_create((belle_sip_auth_event_t*)(belle_sip_refresher_get_auth_events(refresher)->data));
+ }
+ op->base.root->callbacks.register_failure(op,sal_err,sal_reason,reason_phrase);
} else {
- /*refresher will report error*/
+ ms_warning("Register refresher know what to do with this status code");
}
}
-static void register_process_transaction_terminated(void *user_ctx, const belle_sip_transaction_terminated_event_t *event) {
- /*ms_error("register_process_transaction_terminated not implemented yet");*/
-}
@@ -126,19 +87,30 @@ static int send_register_request_with_expires(SalOp* op, belle_sip_request_t* re
int sal_register(SalOp *op, const char *proxy, const char *from, int expires){
belle_sip_request_t *req;
belle_sip_uri_t* req_uri;
+ op->type=SalOpRegister;
sal_op_set_from(op,from);
sal_op_set_to(op,from);
sal_op_set_route(op,proxy);
- op->callbacks.process_io_error=register_process_io_error;
- op->callbacks.process_response_event=register_response_event;
- op->callbacks.process_timeout=register_process_timeout;
- op->callbacks.process_transaction_terminated=register_process_transaction_terminated;
-
req = sal_op_build_request(op,"REGISTER");
req_uri = belle_sip_request_get_uri(req);
belle_sip_uri_set_user(req_uri,NULL); /*remove userinfo if any*/
- return send_register_request_with_expires(op,req,expires);
+ if (send_register_request_with_expires(op,req,expires)) {
+ return -1;
+ } else {
+ if (op->registration_refresher) {
+ belle_sip_refresher_stop(op->registration_refresher);
+ belle_sip_object_unref(op->registration_refresher);
+ }
+ if ((op->registration_refresher = belle_sip_client_transaction_create_refresher(op->pending_client_trans))) {
+ belle_sip_refresher_enable_nat_helper(op->registration_refresher,op->base.root->nat_helper_enabled);
+ belle_sip_refresher_set_listener(op->registration_refresher,register_refresher_listener,op);
+ return 0;
+ } else {
+ return -1;
+ }
+
+ }
}
int sal_register_refresh(SalOp *op, int expires){
diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c
index d4bfd43dc..7323573d4 100644
--- a/coreapi/callbacks.c
+++ b/coreapi/callbacks.c
@@ -726,7 +726,7 @@ static void register_success(SalOp *op, bool_t registered){
LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)sal_op_get_user_pointer(op);
char *msg;
- if (cfg->deletion_date!=0){
+ if (!cfg || cfg->deletion_date!=0){
ms_message("Registration success for removed proxy config, ignored");
return;
}
diff --git a/coreapi/proxy.c b/coreapi/proxy.c
index 8995fd069..e655bf9d7 100644
--- a/coreapi/proxy.c
+++ b/coreapi/proxy.c
@@ -246,7 +246,8 @@ void linphone_proxy_config_enable_publish(LinphoneProxyConfig *obj, bool_t val){
void linphone_proxy_config_edit(LinphoneProxyConfig *obj){
if (obj->reg_sendregister){
/* unregister */
- if (obj->state == LinphoneRegistrationOk) {
+ if (obj->state == LinphoneRegistrationOk
+ || obj->state == LinphoneRegistrationProgress) {
sal_unregister(obj->op);
}
}
diff --git a/gtk/logging.c b/gtk/logging.c
index 15bef85e0..26027251f 100644
--- a/gtk/logging.c
+++ b/gtk/logging.c
@@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include
#include
#endif
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
extern gchar *linphone_logfile;
diff --git a/include/sal/sal.h b/include/sal/sal.h
index 0f78a4c8d..37068c4cd 100644
--- a/include/sal/sal.h
+++ b/include/sal/sal.h
@@ -478,6 +478,7 @@ int sal_call_notify_refer_state(SalOp *h, SalOp *newcall);
/*Registration*/
int sal_register(SalOp *op, const char *proxy, const char *from, int expires);
+/*refresh a register, -1 mean use the last known value*/
int sal_register_refresh(SalOp *op, int expires);
int sal_unregister(SalOp *h);
diff --git a/tester/register_tester.c b/tester/register_tester.c
index 3d2afa1d0..fc74fe74f 100644
--- a/tester/register_tester.c
+++ b/tester/register_tester.c
@@ -95,7 +95,7 @@ static void register_with_refresh_base_2(LinphoneCore* lc, bool_t refresh,const
CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationNone,0);
CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationProgress,1);
CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationOk,1+(refresh!=0));
- CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,0);
+ CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,late_auth_info?1:0);
CU_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationCleared,0);
}
diff --git a/tools/Makefile.am b/tools/Makefile.am
index a93d809f1..8757ab27f 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -8,6 +8,7 @@ AM_CPPFLAGS=\
COMMON_CFLAGS=\
-DIN_LINPHONE \
$(ORTP_CFLAGS) \
+ $(MEDIASTREAMER_CFLAGS) \
$(STRICT_OPTIONS) \
$(LIBXML2_CFLAGS)