Commit 3b025def authored by jehan's avatar jehan
Browse files

first registration with authentication

parent 9e6f05e4
......@@ -40,7 +40,9 @@ liblinphone_la_SOURCES=\
conference.c \
linphone_tunnel.cc
if USE_BELLESIP
liblinphone_la_SOURCES+= sal_bellesip.c
liblinphone_la_SOURCES+= bellesip_sal/sal_address_impl.c \
bellesip_sal/sal_impl.c \
bellesip_sal/sal_op_impl.c
else
liblinphone_la_SOURCES+= sal_eXosip2.c sal_eXosip2.h\
sal_eXosip2_sdp.c \
......
/*
linphone
Copyright (C) 2012 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "sal_impl.h"
/**/
/* Address manipulation API*/
SalAddress * sal_address_new(const char *uri){
belle_sip_header_address_t* result;
if (uri) {
return (SalAddress *)belle_sip_header_address_parse (uri);
} else {
result = belle_sip_header_address_new();
belle_sip_header_address_set_uri(result,belle_sip_uri_new());
return (SalAddress *)result;
}
}
SalAddress * sal_address_clone(const SalAddress *addr){
return (SalAddress *) belle_sip_object_clone(BELLE_SIP_OBJECT(addr));
}
const char *sal_address_get_scheme(const SalAddress *addr){
belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);
belle_sip_uri_t* uri = belle_sip_header_address_get_uri(header_addr);
if (uri) {
if (belle_sip_uri_is_secure(uri)) return "sips";
else return "sip";
} else
return NULL;
}
const char *sal_address_get_display_name(const SalAddress* addr){
belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);
return belle_sip_header_address_get_displayname(header_addr);
}
const char *sal_address_get_display_name_unquoted(const SalAddress *addr){
return sal_address_get_display_name(addr);
}
#define SAL_ADDRESS_GET(addr,param) \
belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);\
belle_sip_uri_t* uri = belle_sip_header_address_get_uri(header_addr);\
if (uri) {\
return belle_sip_uri_get_##param(uri);\
} else\
return NULL;
#define SAL_ADDRESS_SET(addr,param,value) \
belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);\
belle_sip_uri_t* uri = belle_sip_header_address_get_uri(header_addr);\
belle_sip_uri_set_##param(uri,value);
const char *sal_address_get_username(const SalAddress *addr){
SAL_ADDRESS_GET(addr,user)
}
const char *sal_address_get_domain(const SalAddress *addr){
SAL_ADDRESS_GET(addr,host)
}
const char * sal_address_get_port(const SalAddress *addr){
ms_fatal("sal_address_get_port not implemented yet");
return NULL;
}
int sal_address_get_port_int(const SalAddress *addr){
belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);
belle_sip_uri_t* uri = belle_sip_header_address_get_uri(header_addr);
if (uri) {
return belle_sip_uri_get_port(uri);
} else
return -1;
}
SalTransport sal_address_get_transport(const SalAddress* addr){
belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);
belle_sip_uri_t* uri = belle_sip_header_address_get_uri(header_addr);
if (uri) {
return sal_transport_parse(belle_sip_uri_get_transport_param(uri));
} else
return SalTransportUDP;
};
void sal_address_set_display_name(SalAddress *addr, const char *display_name){
belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);
belle_sip_header_address_set_displayname(header_addr,display_name);
}
void sal_address_set_username(SalAddress *addr, const char *username){
SAL_ADDRESS_SET(addr,user,username);
}
void sal_address_set_domain(SalAddress *addr, const char *host){
SAL_ADDRESS_SET(addr,host,host);
}
void sal_address_set_port(SalAddress *addr, const char *port){
SAL_ADDRESS_SET(addr,port,atoi(port));
}
void sal_address_set_port_int(SalAddress *addr, int port){
SAL_ADDRESS_SET(addr,port,port);
}
void sal_address_clean(SalAddress *addr){
belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);
belle_sip_header_address_set_displayname(header_addr,NULL);
belle_sip_object_unref(belle_sip_header_address_get_uri(header_addr));
belle_sip_header_address_set_uri(header_addr,belle_sip_uri_new());
return ;
}
char *sal_address_as_string(const SalAddress *addr){
return belle_sip_object_to_string(BELLE_SIP_OBJECT(addr));
}
char *sal_address_as_string_uri_only(const SalAddress *addr){
belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);
belle_sip_uri_t* uri = belle_sip_header_address_get_uri(header_addr);
return belle_sip_object_to_string(BELLE_SIP_OBJECT(uri));
}
void sal_address_destroy(SalAddress *addr){
belle_sip_header_address_t* header_addr = BELLE_SIP_HEADER_ADDRESS(addr);
belle_sip_object_unref(header_addr);
return ;
}
void sal_address_set_param(SalAddress *addr,const char* name,const char* value){
belle_sip_parameters_t* parameters = BELLE_SIP_PARAMETERS(addr);
belle_sip_parameters_set_parameter(parameters,name,value);
return ;
}
void sal_address_set_transport(SalAddress* addr,SalTransport transport){
SAL_ADDRESS_SET(addr,transport_param,sal_transport_to_string(transport));
}
/*
linphone
Copyright (C) 2012 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "sal_impl.h"
void sal_enable_logs(){
belle_sip_set_log_level(BELLE_SIP_LOG_MESSAGE);
}
void sal_disable_logs() {
belle_sip_set_log_level(BELLE_SIP_LOG_ERROR);
}
static void process_dialog_terminated(void *user_ctx, const belle_sip_dialog_terminated_event_t *event){
ms_error("process_dialog_terminated not implemented yet");
}
static void process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){
ms_error("process_io_error not implemented yet");
}
static void process_request_event(void *user_ctx, const belle_sip_request_event_t *event) {
ms_error("process_request_event not implemented yet");
}
static void process_response_event(void *user_ctx, const belle_sip_response_event_t *event){
belle_sip_client_transaction_t* client_transaction = belle_sip_response_event_get_client_transaction(event);
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_address_t* contact_address;
belle_sip_header_via_t* via_header;
belle_sip_uri_t* contact_uri;
unsigned int contact_port;
const char* received;
int rport;
bool_t contact_updated=FALSE;
char* new_contact;
if (op->callbacks.process_response_event) {
/*Fix contact if needed*/
via_header= (belle_sip_header_via_t*)belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_VIA);
received = belle_sip_header_via_get_received(via_header);
rport = belle_sip_header_via_get_rport(via_header);
if (received!=NULL || rport>0) {
if (sal_op_get_contact(op)){
contact_address = BELLE_SIP_HEADER_ADDRESS(sal_address_clone(sal_op_get_contact_address(op)));
contact_uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(contact_address));
if (received && strcmp(received,belle_sip_uri_get_host(contact_uri))!=0) {
/*need to update host*/
belle_sip_uri_set_host(contact_uri,received);
contact_updated=TRUE;
}
contact_port = belle_sip_uri_get_port(contact_uri);
if (rport>0 && rport!=contact_port && (contact_port+rport)!=5060) {
/*need to update port*/
belle_sip_uri_set_port(contact_uri,rport);
contact_updated=TRUE;
}
if (contact_updated) {
new_contact=belle_sip_object_to_string(BELLE_SIP_OBJECT(contact_address));
ms_message("Updating contact from [%s] to [%s] for [%p]",sal_op_get_contact(op),new_contact,op);
sal_op_set_contact(op,new_contact);
belle_sip_free(new_contact);
}
belle_sip_object_unref(contact_address);
}
}
op->callbacks.process_response_event(op,event);
} else {
ms_error("Unhandled event response [%p]",event);
}
}
static void process_timeout(void *user_ctx, const belle_sip_timeout_event_t *event) {
/* belle_sip_client_transaction_t* client_transaction = belle_sip_timeout_event_get_client_transaction(event);
SalOp* op = (SalOp*)belle_sip_transaction_get_application_data(BELLE_SIP_TRANSACTION(client_transaction));
if (op->callbacks.process_timeout) {
op->callbacks.process_timeout(op,event);
} else*/ {
ms_error("Unhandled event timeout [%p]",event);
}
}
static void process_transaction_terminated(void *user_ctx, const belle_sip_transaction_terminated_event_t *event) {
/* belle_sip_client_transaction_t* client_transaction = belle_sip_transaction_terminated_event_get_client_transaction(event);
SalOp* op = (SalOp*)belle_sip_transaction_get_application_data(client_transaction);
if (op->calbacks.process_transaction_terminated) {
op->calbacks.process_transaction_terminated(op,event);
} else */{
ms_error("Unhandled transaction terminated [%p]",event);
}
}
Sal * sal_init(){
Sal * sal=ms_new0(Sal,1);
sal->stack = belle_sip_stack_new(NULL);
sal->prov = belle_sip_stack_create_provider(sal->stack,NULL);
sal->listener_callbacks.process_dialog_terminated=process_dialog_terminated;
sal->listener_callbacks.process_io_error=process_io_error;
sal->listener_callbacks.process_request_event=process_request_event;
sal->listener_callbacks.process_response_event=process_response_event;
sal->listener_callbacks.process_timeout=process_timeout;
sal->listener_callbacks.process_transaction_terminated=process_transaction_terminated;
belle_sip_provider_add_sip_listener(sal->prov,belle_sip_listener_create_from_callbacks(&sal->listener_callbacks,sal));
return sal;
}
void sal_set_user_pointer(Sal *sal, void *user_data){
sal->up=user_data;
}
void *sal_get_user_pointer(const Sal *sal){
return sal->up;
}
static void unimplemented_stub(){
ms_warning("Unimplemented SAL callback");
}
void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
memcpy(&ctx->callbacks,cbs,sizeof(*cbs));
if (ctx->callbacks.call_received==NULL)
ctx->callbacks.call_received=(SalOnCallReceived)unimplemented_stub;
if (ctx->callbacks.call_ringing==NULL)
ctx->callbacks.call_ringing=(SalOnCallRinging)unimplemented_stub;
if (ctx->callbacks.call_accepted==NULL)
ctx->callbacks.call_accepted=(SalOnCallAccepted)unimplemented_stub;
if (ctx->callbacks.call_failure==NULL)
ctx->callbacks.call_failure=(SalOnCallFailure)unimplemented_stub;
if (ctx->callbacks.call_terminated==NULL)
ctx->callbacks.call_terminated=(SalOnCallTerminated)unimplemented_stub;
if (ctx->callbacks.call_released==NULL)
ctx->callbacks.call_released=(SalOnCallReleased)unimplemented_stub;
if (ctx->callbacks.call_updating==NULL)
ctx->callbacks.call_updating=(SalOnCallUpdating)unimplemented_stub;
if (ctx->callbacks.auth_requested_legacy==NULL)
ctx->callbacks.auth_requested_legacy=(SalOnAuthRequestedLegacy)unimplemented_stub;
if (ctx->callbacks.auth_success==NULL)
ctx->callbacks.auth_success=(SalOnAuthSuccess)unimplemented_stub;
if (ctx->callbacks.register_success==NULL)
ctx->callbacks.register_success=(SalOnRegisterSuccess)unimplemented_stub;
if (ctx->callbacks.register_failure==NULL)
ctx->callbacks.register_failure=(SalOnRegisterFailure)unimplemented_stub;
if (ctx->callbacks.dtmf_received==NULL)
ctx->callbacks.dtmf_received=(SalOnDtmfReceived)unimplemented_stub;
if (ctx->callbacks.notify==NULL)
ctx->callbacks.notify=(SalOnNotify)unimplemented_stub;
if (ctx->callbacks.notify_presence==NULL)
ctx->callbacks.notify_presence=(SalOnNotifyPresence)unimplemented_stub;
if (ctx->callbacks.subscribe_received==NULL)
ctx->callbacks.subscribe_received=(SalOnSubscribeReceived)unimplemented_stub;
if (ctx->callbacks.text_received==NULL)
ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
if (ctx->callbacks.ping_reply==NULL)
ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
if (ctx->callbacks.auth_requested==NULL)
ctx->callbacks.auth_requested=(SalOnAuthRequested)unimplemented_stub;
}
void sal_uninit(Sal* sal){
belle_sip_object_unref(sal->prov);
belle_sip_object_unref(sal->stack);
ms_free(sal);
return ;
};
int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){
int result;
belle_sip_listening_point_t* lp = belle_sip_stack_create_listening_point(ctx->stack,addr,port,sal_transport_to_string(tr));
if (lp) {
result = belle_sip_provider_add_listening_point(ctx->prov,lp);
belle_sip_object_unref(lp);
} else {
return -1;
}
return result;
}
static void remove_listening_point(belle_sip_listening_point_t* lp,belle_sip_provider_t* prov) {
belle_sip_provider_remove_listening_point(prov,lp);
}
int sal_unlisten_ports(Sal *ctx){
const belle_sip_list_t * lps = belle_sip_provider_get_listening_points(ctx->prov);
belle_sip_list_t * tmp_list = belle_sip_list_copy(lps);
belle_sip_list_for_each2 (tmp_list,(void (*)(void*,void*))remove_listening_point,ctx->prov);
belle_sip_list_free(tmp_list);
ms_message("sal_unlisten_ports done");
return 0;
}
ortp_socket_t sal_get_socket(Sal *ctx){
ms_fatal("sal_get_socket not implemented yet");
return -1;
}
void sal_set_user_agent(Sal *ctx, const char *user_agent){
ms_error("sal_set_user_agent not implemented yet");
return ;
}
/*keepalive period in ms*/
void sal_set_keepalive_period(Sal *ctx,unsigned int value){
ms_error("sal_set_keepalive_period not implemented yet");
return ;
}
/**
* returns keepalive period in ms
* 0 desactiaved
* */
unsigned int sal_get_keepalive_period(Sal *ctx){
ms_fatal("sal_get_keepalive_period not implemented yet");
return -1;
}
void sal_use_session_timers(Sal *ctx, int expires){
ms_error("sal_use_session_timers not implemented yet");
return ;
}
void sal_use_double_registrations(Sal *ctx, bool_t enabled){
ms_error("sal_use_double_registrations not implemented yet");
return ;
}
void sal_reuse_authorization(Sal *ctx, bool_t enabled){
ms_error("sal_reuse_authorization not implemented yet");
return ;
}
void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec){
ms_error("sal_use_one_matching_codec_policy not implemented yet");
return ;
}
void sal_use_rport(Sal *ctx, bool_t use_rports){
ms_error("sal_use_rport not implemented yet");
return ;
}
void sal_use_101(Sal *ctx, bool_t use_101){
ms_error("sal_use_101 not implemented yet");
return ;
}
void sal_set_root_ca(Sal* ctx, const char* rootCa){
ms_error("sal_set_root_ca not implemented yet");
return ;
}
void sal_verify_server_certificates(Sal *ctx, bool_t verify){
ms_error("sal_verify_server_certificates not implemented yet");
return ;
}
int sal_iterate(Sal *sal){
/*FIXME should be zero*/
belle_sip_stack_sleep(sal->stack,0);
return 0;
}
MSList * sal_get_pending_auths(Sal *sal){
return ms_list_copy(sal->pending_auths);
}
#define payload_type_set_number(pt,n) (pt)->user_data=(void*)((long)n);
#define payload_type_get_number(pt) ((int)(long)(pt)->user_data)
/*misc*/
void sal_get_default_local_ip(Sal *sal, int address_family, char *ip, size_t iplen){
ms_fatal("sal_get_default_local_ip not implemented yet");
return ;
}
/*
linphone
Copyright (C) 2012 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef SAL_IMPL_H_
#define SAL_IMPL_H_
#include "sal.h"
#include "belle-sip/belle-sip.h"
struct Sal{
SalCallbacks callbacks;
MSList *pending_auths;/*MSList of SalOp */
belle_sip_listener_callbacks_t listener_callbacks;
belle_sip_stack_t* stack;
belle_sip_provider_t *prov;
void *up; /*user pointer*/
};
struct SalOp{
SalOpBase base;
belle_sip_listener_callbacks_t callbacks;
belle_sip_request_t* register_request;
belle_sip_response_t* register_response;
SalAuthInfo auth_info;
unsigned long int registration_refresh_timer;
};
#endif /* SAL_IMPL_H_ */
......@@ -600,7 +600,7 @@ static void call_released(SalOp *op){
}else ms_error("call_released() for already destroyed call ?");
}
static void auth_requested(SalOp *h, const char *realm, const char *username){
static void auth_requested_legacy(SalOp *h, const char *realm, const char *username){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(h));
LinphoneAuthInfo *ai=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,realm,username);
LinphoneCall *call=is_a_linphone_call(sal_op_get_user_pointer(h));
......@@ -794,7 +794,19 @@ static void ping_reply(SalOp *op){
ms_warning("ping reply without call attached...");
}
}
static bool_t auth_requested(SalOp*op, SalAuthInfo* sai) {
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
LinphoneAuthInfo *ai=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,sai->realm,sai->username);
if (ai) {
sai->userid=ai->userid?ai->userid:ai->username;
sai->password=ai->passwd;
ai->usecount++;
ai->last_use_time=ms_time(NULL);
return TRUE;
} else {
return FALSE;
}
}
SalCallbacks linphone_sal_callbacks={
call_received,
call_ringing,
......@@ -804,7 +816,7 @@ SalCallbacks linphone_sal_callbacks={
call_terminated,
call_failure,
call_released,
auth_requested,
auth_requested_legacy,
auth_success,
register_success,
register_failure,
......@@ -816,7 +828,8 @@ SalCallbacks linphone_sal_callbacks={
notify_presence,
subscribe_received,
subscribe_closed,
ping_reply
ping_reply,
auth_requested
};
......@@ -1621,13 +1621,13 @@ void linphone_core_enable_ipv6(LinphoneCore *lc, bool_t val){
static void monitor_network_state(LinphoneCore *lc, time_t curtime){
static time_t last_check=0;
static bool_t last_status=FALSE;
static time_t last_check=0; /*shared beetwen multi linphonecore*/
bool_t last_status=linphone_core_is_network_reachabled(lc);
char result[LINPHONE_IPADDR_SIZE];
bool_t new_status=last_status;
/* only do the network up checking every five seconds */
if (last_check==0 || (curtime-last_check)>=5){
if (lc->netup_time==0 || (curtime-last_check)>=5){
linphone_core_get_local_ip_for(lc->sip_conf.ipv6_enabled ? AF_INET6 : AF_INET,NULL,result);
if (strcmp(result,"::1")!=0 && strcmp(result,"127.0.0.1")!=0){
new_status=TRUE;
......@@ -4144,6 +4144,7 @@ void sip_config_uninit(LinphoneCore *lc)
MSList *elem;
int i;
sip_config_t *config=&lc->sip_conf;
bool_t all_unregistered=FALSE;
lp_config_set_int(lc->config,"sip","guess_hostname",config->guess_hostname);
lp_config_set_string(lc->config,"sip","contact",config->contact);
......@@ -4156,13 +4157,17 @@ void sip_config_uninit(LinphoneCore *lc)
for(elem=config->proxies,i=0;elem!=NULL;elem=ms_list_next(elem),i++){
for(elem=config->proxies;elem!=NULL;elem=ms_list_next(elem)){
LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)(elem->data);
linphone_proxy_config_edit(cfg); /* to unregister */
}
for (i=0;i<20;i++){
for (i=0;i<20&&!all_unregistered;i++){
sal_iterate(lc->sal);
for(elem=config->proxies;elem!=NULL;elem=ms_list_next(elem)){
LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)(elem->data);
all_unregistered|=!linphone_proxy_config_is_registered(cfg);
}
#ifndef WIN32
usleep(100000);
#else
......
......@@ -237,7 +237,7 @@ 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 != LinphoneRegistrationNone && obj->state != LinphoneRegistrationCleared) {
if (obj->state == LinphoneRegistrationOk) {
sal_unregister(obj->op);
}
}
......
......@@ -203,6 +203,14 @@ bool_t sal_media_description_equals(const SalMediaDescription *md1, const SalMed
}
return TRUE;
}
static void assign_address(SalAddress** address, const char *value){
if (*address){
sal_address_destroy(*address);
*address=NULL;
}
if (value)
*address=sal_address_new(value);
}
static void assign_string(char **str, const char *arg){
if (*str){
......@@ -212,9 +220,22 @@ static void assign_string(char **str, const char *arg){
if (arg)
*str=ms_strdup(arg);
}
void sal_op_set_contact_address(SalOp *op, const SalAddress *address){
char* address_string=sal_address_as_string(address); /*can probably be optimized*/
sal_op_set_contact(op,address_string);