Commit bffae8bd authored by jehan's avatar jehan

transfer full control of registration to refresher

parent edf037fa
......@@ -37,6 +37,7 @@
</folderInfo>
<sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="coreapi"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="gtk"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="tester"/>
</sourceEntries>
</configuration>
......
......@@ -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";
}
}
......@@ -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_ */
......@@ -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 {
......
......@@ -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));
......
......@@ -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;
}
......@@ -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 */
......
......@@ -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){
......
......@@ -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;
}
......
......@@ -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);
}
}
......
......@@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <sys/stat.h>
#include <sys/types.h>
#endif
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
extern gchar *linphone_logfile;
......
......@@ -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);
......
......@@ -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);
}
......
......@@ -8,6 +8,7 @@ AM_CPPFLAGS=\
COMMON_CFLAGS=\
-DIN_LINPHONE \
$(ORTP_CFLAGS) \
$(MEDIASTREAMER_CFLAGS) \
$(STRICT_OPTIONS) \
$(LIBXML2_CFLAGS)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment