]> sjero.net Git - linphone/commitdiff
add support in the api for multi transport
authorSimon Morlat <simon.morlat@linphone.org>
Fri, 4 Jun 2010 15:42:12 +0000 (17:42 +0200)
committerSimon Morlat <simon.morlat@linphone.org>
Fri, 4 Jun 2010 15:42:12 +0000 (17:42 +0200)
find best contact at first register.

multi-transport does not work because it is not implemented in eXosip

coreapi/linphonecore.c
coreapi/linphonecore.h
coreapi/private.h
coreapi/proxy.c
coreapi/sal.h
coreapi/sal_eXosip2.c
coreapi/sal_eXosip2.h
mediastreamer2

index 83d4c84a8eea215dfde81e660a0fb8ab4f98440c..778494aa3fa067c5161c4d318b2317976e184b63 100644 (file)
@@ -628,14 +628,14 @@ static void sip_config_read(LinphoneCore *lc)
 {
        char *contact;
        const char *tmpstr;
-       int port;
+       LCSipTransports tr;
        int i,tmp;
        int ipv6;
-       port=lp_config_get_int(lc->config,"sip","use_info",0);
-       linphone_core_set_use_info_for_dtmf(lc,port);
+       tmp=lp_config_get_int(lc->config,"sip","use_info",0);
+       linphone_core_set_use_info_for_dtmf(lc,tmp);
 
-       port=lp_config_get_int(lc->config,"sip","use_rfc2833",0);
-       linphone_core_set_use_rfc2833_for_dtmf(lc,port);
+       tmp=lp_config_get_int(lc->config,"sip","use_rfc2833",0);
+       linphone_core_set_use_rfc2833_for_dtmf(lc,tmp);
 
        ipv6=lp_config_get_int(lc->config,"sip","use_ipv6",-1);
        if (ipv6==-1){
@@ -645,19 +645,12 @@ static void sip_config_read(LinphoneCore *lc)
                }
        }
        linphone_core_enable_ipv6(lc,ipv6);
-       port=lp_config_get_int(lc->config,"sip","sip_port",5060);
+       memset(&tr,0,sizeof(tr));
+       tr.udp_port=lp_config_get_int(lc->config,"sip","sip_port",5060);
+       tr.tcp_port=lp_config_get_int(lc->config,"sip","sip_tcp_port",0);
 
-       tmpstr=lp_config_get_string(lc->config,"sip","transport","udp");
-       if (strcmp("udp",tmpstr) == 0 ) {
-               lc->sip_conf.transport=SalTransportDatagram;
-       } else if (strcmp("tcp",tmpstr) == 0) {
-               lc->sip_conf.transport=SalTransportStream;
-       } else {
-               lc->sip_conf.transport=SalTransportDatagram;
-               ms_warning("unsupported transport, using udp");
-       }
-       /*start listening on port*/
-       linphone_core_set_sip_port(lc,port);
+       /*start listening on ports*/
+       linphone_core_set_sip_transports(lc,&tr);
 
        tmpstr=lp_config_get_string(lc->config,"sip","contact",NULL);
        if (tmpstr==NULL || linphone_core_set_primary_contact(lc,tmpstr)==-1) {
@@ -1237,7 +1230,7 @@ static void update_primary_contact(LinphoneCore *lc){
                lc->sip_conf.loopback_only=TRUE;
        }else lc->sip_conf.loopback_only=FALSE;
        linphone_address_set_domain(url,tmp);
-       linphone_address_set_port_int(url,lc->sip_conf.sip_port);
+       linphone_address_set_port_int(url,linphone_core_get_sip_port (lc));
        guessed=linphone_address_as_string(url);
        lc->sip_conf.guessed_contact=guessed;
        linphone_address_destroy(url);
@@ -1456,11 +1449,13 @@ void linphone_core_set_use_rfc2833_for_dtmf(LinphoneCore *lc,bool_t use_rfc2833)
 /**
  * Returns the UDP port used by SIP.
  *
+ * Deprecated: use linphone_core_get_sip_transports() instead.
  * @ingroup network_parameters
 **/
 int linphone_core_get_sip_port(LinphoneCore *lc)
 {
-       return lc->sip_conf.sip_port;
+       LCSipTransports *tr=&lc->sip_conf.transports;
+       return tr->udp_port>0 ? tr->udp_port : tr->tcp_port;
 }
 
 static char _ua_name[64]="Linphone";
@@ -1492,35 +1487,89 @@ void linphone_core_set_user_agent(const char *name, const char *ver){
        strncpy(_ua_version,ver,sizeof(_ua_version));
 }
 
-/**
- * Sets the UDP port to be used by SIP.
- *
- * @ingroup network_parameters
-**/
-void linphone_core_set_sip_port(LinphoneCore *lc,int port)
-{
+static void transport_error(LinphoneCore *lc, const char* transport, int port){
+       char *msg=ortp_strdup_printf("Could not start %s transport on port %i, maybe this port is already used.",transport,port);
+       ms_warning(msg);
+       if (lc->vtable.display_warning)
+               lc->vtable.display_warning(lc,msg);
+       ms_free(msg);
+}
+
+static bool_t transports_unchanged(const LCSipTransports * tr1, const LCSipTransports * tr2){
+       return
+               tr2->udp_port==tr1->udp_port &&
+               tr2->tcp_port==tr1->tcp_port &&
+               tr2->dtls_port==tr1->dtls_port &&
+               tr2->tls_port==tr1->tls_port;
+}
+
+static int apply_transports(LinphoneCore *lc){
+       Sal *sal=lc->sal;
        const char *anyaddr;
-       int err=0;
-       if (port==lc->sip_conf.sip_port) return;
-       lc->sip_conf.sip_port=port;
+       LCSipTransports *tr=&lc->sip_conf.transports;
 
-       if (lc->sal==NULL) return;
-       
        if (lc->sip_conf.ipv6_enabled)
                anyaddr="::0";
        else
                anyaddr="0.0.0.0";
 
-
-       err=sal_listen_port (lc->sal,anyaddr,port, lc->sip_conf.transport,FALSE);
-       if (err<0){
-               char *msg=ortp_strdup_printf("Port %i seems already in use ! Cannot initialize.",port);
-               ms_warning(msg);
-               lc->vtable.display_warning(lc,msg);
-               ms_free(msg);
-               return;
+       sal_unlisten_ports (sal);
+       if (tr->udp_port>0){
+               if (sal_listen_port (sal,anyaddr,tr->udp_port,SalTransportDatagram,FALSE)!=0){
+                       transport_error(lc,"UDP",tr->udp_port);
+                       return -1;
+               }
+       }
+       if (tr->tcp_port>0){
+               if (sal_listen_port (sal,anyaddr,tr->tcp_port,SalTransportStream,FALSE)!=0){
+                       transport_error(lc,"TCP",tr->tcp_port);
+               }
        }
        apply_user_agent(lc);
+       return 0;
+}
+
+/**
+ * Sets the ports to be used for each of transport (UDP or TCP)
+ *
+ * A zero value port for a given transport means the transport
+ * is not used.
+ *
+ * @ingroup network_parameters
+**/
+int linphone_core_set_sip_transports(LinphoneCore *lc, const LCSipTransports * tr){
+       
+       if (transports_unchanged(tr,&lc->sip_conf.transports))
+               return 0;
+       memcpy(&lc->sip_conf.transports,tr,sizeof(*tr));
+       
+       if (lc->sal==NULL) return 0;
+       return apply_transports(lc);
+}
+
+/**
+ * Retrieves the ports used for each transport (udp, tcp).
+ * A zero value port for a given transport means the transport
+ * is not used.
+ * @ingroup network_parameters
+**/
+int linphone_core_get_sip_transport(LinphoneCore *lc, LCSipTransports *tr){
+       memcpy(tr,&lc->sip_conf.transports,sizeof(*tr));
+       return 0;
+}
+
+/**
+ * Sets the UDP port to be used by SIP.
+ *
+ * Deprecated: use linphone_core_set_sip_transports() instead.
+ * @ingroup network_parameters
+**/
+void linphone_core_set_sip_port(LinphoneCore *lc,int port)
+{
+       LCSipTransports tr;
+       memset(&tr,0,sizeof(tr));
+       tr.udp_port=port;
+       linphone_core_set_sip_transports (lc,&tr);
 }
 
 /**
@@ -1547,7 +1596,7 @@ void linphone_core_enable_ipv6(LinphoneCore *lc, bool_t val){
                lc->sip_conf.ipv6_enabled=val;
                if (lc->sal){
                        /* we need to restart eXosip */
-                       linphone_core_set_sip_port(lc, lc->sip_conf.sip_port);
+                       apply_transports(lc);
                }
        }
 }
@@ -3478,7 +3527,7 @@ void sip_config_uninit(LinphoneCore *lc)
        MSList *elem;
        int i;
        sip_config_t *config=&lc->sip_conf;
-       lp_config_set_int(lc->config,"sip","sip_port",config->sip_port);
+       lp_config_set_int(lc->config,"sip","sip_port",config->transports.udp_port);
        lp_config_set_int(lc->config,"sip","guess_hostname",config->guess_hostname);
        lp_config_set_string(lc->config,"sip","contact",config->contact);
        lp_config_set_int(lc->config,"sip","inc_timeout",config->inc_timeout);
index d1b2571d074c9152f043ce1f4bcd382bee9c412a..34a3483ea3fd62aa9ea5244e62cd0163faef56b7 100644 (file)
@@ -44,6 +44,15 @@ struct SalOp;
 struct _LpConfig;
 
 
+struct _LCSipTransports{
+       int udp_port;
+       int tcp_port;
+       int dtls_port;
+       int tls_port;
+};
+
+typedef struct _LCSipTransports LCSipTransports;
+
 /**
  * Object that represents a SIP address.
  *
@@ -609,9 +618,13 @@ void linphone_core_set_use_rfc2833_for_dtmf(LinphoneCore *lc,bool_t use_rfc2833)
 
 bool_t linphone_core_get_use_rfc2833_for_dtmf(LinphoneCore *lc);
 
+void linphone_core_set_sip_port(LinphoneCore *lc, int port);
+
 int linphone_core_get_sip_port(LinphoneCore *lc);
 
-void linphone_core_set_sip_port(LinphoneCore *lc,int port);
+int linphone_core_set_sip_transports(LinphoneCore *lc, const LCSipTransports *transports);
+
+int linphone_core_get_sip_transports(LinphoneCore *lc, LCSipTransports *transports);
 
 ortp_socket_t linphone_core_get_sip_socket(LinphoneCore *lc);
 
index e14e1644f650acc01c17f9c4e297d32c55a49a13..cd3abd3c94660129bac8c7752a25bb083f05ad98 100644 (file)
@@ -247,10 +247,11 @@ typedef struct sip_config
 {
        char *contact;
        char *guessed_contact;
-       int sip_port;
        MSList *proxies;
        MSList *deleted_proxies;
        int inc_timeout;        /*timeout after an un-answered incoming call is rejected*/
+       unsigned int keepalive_period; /* interval in ms between keep alive messages sent to the proxy server*/
+       LCSipTransports transports;
        bool_t use_info;
        bool_t use_rfc2833;     /*force RFC2833 to be sent*/
        bool_t guess_hostname;
@@ -261,9 +262,6 @@ typedef struct sip_config
        bool_t register_only_when_network_is_up;
        bool_t ping_with_options;
        bool_t auto_net_state_mon;
-       unsigned int keepalive_period; /* interval in ms between keep alive messages sent to the proxy server*/
-       SalTransport transport;
-
 } sip_config_t;
 
 typedef struct rtp_config
@@ -273,7 +271,7 @@ typedef struct rtp_config
        int audio_jitt_comp;  /*jitter compensation*/
        int video_jitt_comp;  /*jitter compensation*/
        int nortp_timeout;
-        bool_t rtp_no_xmit_on_audio_mute;                              
+       bool_t rtp_no_xmit_on_audio_mute;                              
                               /* stop rtp xmit when audio muted */
 }rtp_config_t;
 
index bf4e0613a9929594346bd0c7555e3105beb6d7a2..80eb5d522e66f672babc13fe953bd0acfa876c20 100644 (file)
@@ -230,14 +230,39 @@ void linphone_proxy_config_apply(LinphoneProxyConfig *obj,LinphoneCore *lc)
        linphone_proxy_config_done(obj);
 }
 
+static char *guess_contact_for_register(LinphoneProxyConfig *obj){
+       LinphoneAddress *proxy=linphone_address_new(obj->reg_proxy);
+       char *ret=NULL;
+       const char *host;
+       if (proxy==NULL) return NULL;
+       host=linphone_address_get_domain (proxy);
+       if (host!=NULL){
+               LinphoneAddress *contact;
+               char localip[LINPHONE_IPADDR_SIZE];
+               
+               linphone_core_get_local_ip(obj->lc,host,localip);
+               contact=linphone_address_new(obj->reg_identity);
+               linphone_address_set_domain (contact,localip);
+               linphone_address_set_port_int(contact,linphone_core_get_sip_port(obj->lc));
+               ret=linphone_address_as_string_uri_only (contact);
+               linphone_address_destroy(contact);
+       }
+       linphone_address_destroy (proxy);
+       return ret;
+}
+
 static void linphone_proxy_config_register(LinphoneProxyConfig *obj){
        const char *id_str;
        if (obj->reg_identity!=NULL) id_str=obj->reg_identity;
        else id_str=linphone_core_get_primary_contact(obj->lc);
        if (obj->reg_sendregister){
+               char *contact;
                if (obj->op)
                        sal_op_release(obj->op);
                obj->op=sal_op_new(obj->lc->sal);
+               contact=guess_contact_for_register(obj);
+               sal_op_set_contact(obj->op,contact);
+               ms_free(contact);
                sal_op_set_user_pointer(obj->op,obj);
                if (!sal_register(obj->op,obj->reg_proxy,obj->reg_identity,obj->expires)) {
                        gstate_new_state(obj->lc,GSTATE_REG_PENDING,NULL);
index 6cb1fd4268366f71f133145da9dea13a75f72749..9790b8c711a740c34966cf21a340c00c7161a312 100644 (file)
@@ -225,6 +225,7 @@ typedef struct SalAuthInfo{
 
 void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs);
 int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure);
+int sal_unlisten_ports(Sal *ctx);
 ortp_socket_t sal_get_socket(Sal *ctx);
 void sal_set_user_agent(Sal *ctx, const char *user_agent);
 /*keepalive period in ms*/
index bc097f94a6bd0efce794c140362ec072dc14d639..fa6fb5f11ff6571d4399e5ecd1240458e9e0ab1e 100644 (file)
@@ -251,6 +251,7 @@ Sal * sal_init(){
        }
        eXosip_init();
        sal=ms_new0(Sal,1);
+       sal->keepalive_period=30;
        return sal;
 }
 
@@ -309,6 +310,14 @@ void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
                ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
 }
 
+int sal_unlisten_ports(Sal *ctx){
+       if (ctx->running){
+               eXosip_quit();
+               eXosip_init();
+       }
+       return 0;
+}
+
 int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){
        int err;
        bool_t ipv6;
@@ -325,10 +334,6 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i
                ms_warning("unexpected proto, using datagram");
        }
 
-       if (ctx->running){
-               eXosip_quit();
-               eXosip_init();
-       }
        err=0;
        eXosip_set_option(13,&err); /*13=EXOSIP_OPT_SRV_WITH_NAPTR, as it is an enum value, we can't use it unless we are sure of the
                                        version of eXosip, which is not the case*/
@@ -344,6 +349,7 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i
 #ifdef HAVE_EXOSIP_GET_SOCKET
        ms_message("Exosip has socket number %i",eXosip_get_socket(proto));
 #endif
+       eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &ctx->keepalive_period);
        ctx->running=TRUE;
        return err;
 }
@@ -1749,6 +1755,7 @@ void sal_address_destroy(SalAddress *u){
 }
 
 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
+       ctx->keepalive_period=value;
        eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &value);
 }
 
index 0df6023a63d9da8706703d56aa09dffc405297bd..5f2c681d1e72847f384e03fcb7e0ef361d1d1846 100644 (file)
@@ -38,6 +38,7 @@ struct Sal{
        MSList *other_transactions; /*MSList of SalOp */
        int running;
        int session_expires;
+       int keepalive_period;
        void *up;
 };
 
index 2c65063096918cce1dfcc6f01c0cbf43c3232dc0..a6484a8463b62a60d03ef8358b2e305408f3b011 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 2c65063096918cce1dfcc6f01c0cbf43c3232dc0
+Subproject commit a6484a8463b62a60d03ef8358b2e305408f3b011