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)