From 6672dec459b7a007a6beffab76831d76b050a7a4 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 4 Jun 2010 17:42:12 +0200 Subject: [PATCH] add support in the api for multi transport find best contact at first register. multi-transport does not work because it is not implemented in eXosip --- coreapi/linphonecore.c | 131 ++++++++++++++++++++++++++++------------- coreapi/linphonecore.h | 15 ++++- coreapi/private.h | 8 +-- coreapi/proxy.c | 25 ++++++++ coreapi/sal.h | 1 + coreapi/sal_eXosip2.c | 15 +++-- coreapi/sal_eXosip2.h | 1 + mediastreamer2 | 2 +- 8 files changed, 146 insertions(+), 52 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 83d4c84a..778494aa 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -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); diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index d1b2571d..34a3483e 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -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); diff --git a/coreapi/private.h b/coreapi/private.h index e14e1644..cd3abd3c 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -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; diff --git a/coreapi/proxy.c b/coreapi/proxy.c index bf4e0613..80eb5d52 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -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); diff --git a/coreapi/sal.h b/coreapi/sal.h index 6cb1fd42..9790b8c7 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -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*/ diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index bc097f94..fa6fb5f1 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -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); } diff --git a/coreapi/sal_eXosip2.h b/coreapi/sal_eXosip2.h index 0df6023a..5f2c681d 100644 --- a/coreapi/sal_eXosip2.h +++ b/coreapi/sal_eXosip2.h @@ -38,6 +38,7 @@ struct Sal{ MSList *other_transactions; /*MSList of SalOp */ int running; int session_expires; + int keepalive_period; void *up; }; diff --git a/mediastreamer2 b/mediastreamer2 index 2c650630..a6484a84 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 2c65063096918cce1dfcc6f01c0cbf43c3232dc0 +Subproject commit a6484a8463b62a60d03ef8358b2e305408f3b011 -- 2.39.2