diff --git a/configure.ac b/configure.ac index 858e11b61..9e6364c37 100644 --- a/configure.ac +++ b/configure.ac @@ -33,13 +33,12 @@ AM_INIT_AUTOMAKE AC_SUBST([LIBTOOL_DEPS]) m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],) AC_SUBST([docdir], [${datadir}/doc]) -AC_CONFIG_HEADER(config.h) +AC_CONFIG_HEADERS(config.h) AC_CONFIG_MACRO_DIR([m4]) AC_ISC_POSIX AC_PROG_CC AC_PROG_CXX AC_C_INLINE -AM_PROG_CC_STDC AC_HEADER_STDC AM_PROG_CC_C_O AC_CHECK_PROGS(MD5SUM,[md5sum md5]) diff --git a/console/linphonec.c b/console/linphonec.c index 6220a0599..fca5a9b86 100644 --- a/console/linphonec.c +++ b/console/linphonec.c @@ -895,22 +895,22 @@ linphonec_prompt_for_auth_final(LinphoneCore *lc) void print_usage (int exit_status) { - fprintf (stdout, "\n\ -usage: linphonec [-c file] [-s sipaddr] [-a] [-V] [-d level ] [-l logfile]\n\ - linphonec -v\n\ -\n\ - -b file specify path of readonly factory configuration file.\n\ - -c file specify path of configuration file.\n\ - -d level be verbose. 0 is no output. 6 is all output\n\ - -l logfile specify the log file for your SIP phone\n\ - -s sipaddress specify the sip call to do at startup\n\ - -a enable auto answering for incoming calls\n\ - -V enable video features globally (disabled by default)\n\ - -C enable video capture only (disabled by default)\n\ - -D enable video display only (disabled by default)\n\ - -S show general state messages (disabled by default)\n\ - --wid windowid force embedding of video window into provided windowid (disabled by default)\n\ - -v or --version display version and exits.\n"); + fprintf (stdout, "\n" +"usage: linphonec [-c file] [-s sipaddr] [-a] [-V] [-d level ] [-l logfile]\n" + "linphonec -v\n" +"\n" +" -b file specify path of readonly factory configuration file.\n" +" -c file specify path of configuration file.\n" +" -d level be verbose. 0 is no output. 6 is all output\n" +" -l logfile specify the log file for your SIP phone\n" +" -s sipaddress specify the sip call to do at startup\n" +" -a enable auto answering for incoming calls\n" +" -V enable video features globally (disabled by default)\n" +" -C enable video capture only (disabled by default)\n" +" -D enable video display only (disabled by default)\n" +" -S show general state messages (disabled by default)\n" +" --wid windowid force embedding of video window into provided windowid (disabled by default)\n" +" -v or --version display version and exits.\n"); exit(exit_status); } diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am index c5abd0360..eab65b147 100644 --- a/coreapi/Makefile.am +++ b/coreapi/Makefile.am @@ -57,6 +57,7 @@ if BUILD_WIZARD liblinphone_la_SOURCES+=sipwizard.c endif +liblinphone_la_SOURCES+=linphone_tunnel_config.c if BUILD_TUNNEL liblinphone_la_SOURCES+=linphone_tunnel.cc TunnelManager.cc TunnelManager.hh else diff --git a/coreapi/TunnelManager.cc b/coreapi/TunnelManager.cc index 8ce6da7e5..5b1b6dddb 100644 --- a/coreapi/TunnelManager.cc +++ b/coreapi/TunnelManager.cc @@ -107,6 +107,10 @@ void TunnelManager::addServer(const char *ip, int port,unsigned int udpMirrorPor } void TunnelManager::addServer(const char *ip, int port) { + if (ip == NULL) { + ip = ""; + ms_warning("Adding tunnel server with empty ip, it will not work!"); + } mServerAddrs.push_back(ServerAddr(ip,port)); if (mTunnelClient) mTunnelClient->addServer(ip,port); } diff --git a/coreapi/authentication.c b/coreapi/authentication.c index 1f7dfa91c..4b5d10fa8 100644 --- a/coreapi/authentication.c +++ b/coreapi/authentication.c @@ -131,7 +131,7 @@ void linphone_auth_info_write_config(LpConfig *config, LinphoneAuthInfo *obj, in sprintf(key,"auth_info_%i",pos); lp_config_clean_section(config,key); - if (obj==NULL){ + if (obj==NULL || lp_config_get_int(config, "sip", "store_auth_info", 1) == 0){ return; } if (obj->username!=NULL){ diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index f166bc49f..ab5fb780b 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -356,7 +356,7 @@ static void call_accepted(SalOp *op){ linphone_call_set_state(call,LinphoneCallConnected,"Connected"); if (call->referer) linphone_core_notify_refer_state(lc,call->referer,call); } - if (md && !sal_media_description_empty(md)){ + if (md && !sal_media_description_empty(md) && !linphone_core_incompatible_security(lc,md)){ if (sal_media_description_has_dir(md,SalStreamSendOnly) || sal_media_description_has_dir(md,SalStreamInactive)){ if (lc->vtable.display_status){ @@ -405,7 +405,7 @@ static void call_accepted(SalOp *op){ }else{ /*send a bye*/ ms_error("Incompatible SDP offer received in 200Ok, need to abort the call"); - linphone_core_abort_call(lc,call,_("Incompatible, check codecs...")); + linphone_core_abort_call(lc,call,_("Incompatible, check codecs or security settings...")); } } diff --git a/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java b/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java index 3e41dba00..a9134dc88 100644 --- a/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java +++ b/coreapi/help/java/org/linphone/core/tutorials/TutorialChatRoom.java @@ -20,19 +20,19 @@ package org.linphone.core.tutorials; import org.linphone.core.LinphoneAddress; import org.linphone.core.LinphoneCall; +import org.linphone.core.LinphoneCall.State; import org.linphone.core.LinphoneCallStats; import org.linphone.core.LinphoneChatMessage; import org.linphone.core.LinphoneChatRoom; import org.linphone.core.LinphoneCore; import org.linphone.core.LinphoneCore.EcCalibratorStatus; +import org.linphone.core.LinphoneCore.GlobalState; +import org.linphone.core.LinphoneCore.RegistrationState; import org.linphone.core.LinphoneCoreException; import org.linphone.core.LinphoneCoreFactory; import org.linphone.core.LinphoneCoreListener; import org.linphone.core.LinphoneFriend; import org.linphone.core.LinphoneProxyConfig; -import org.linphone.core.LinphoneCall.State; -import org.linphone.core.LinphoneCore.GlobalState; -import org.linphone.core.LinphoneCore.RegistrationState; /** @@ -50,7 +50,7 @@ import org.linphone.core.LinphoneCore.RegistrationState; * @author Guillaume Beraudo * */ -public class TutorialChatRoom implements LinphoneCoreListener { +public class TutorialChatRoom implements LinphoneCoreListener, LinphoneChatMessage.StateListener { private boolean running; private TutorialNotifier TutorialNotifier; @@ -83,7 +83,7 @@ public class TutorialChatRoom implements LinphoneCoreListener { public void dtmfReceived(LinphoneCore lc, LinphoneCall call, int dtmf) {} public void textReceived(LinphoneCore lc, LinphoneChatRoom cr,LinphoneAddress from, String message) { - write("Message ["+message+"] received from ["+from.asString()+"]"); + //Deprecated } @@ -118,7 +118,8 @@ public class TutorialChatRoom implements LinphoneCoreListener { LinphoneChatRoom chatRoom = lc.createChatRoom(destinationSipAddress); // Send message - chatRoom.sendMessage("Hello world"); + LinphoneChatMessage chatMessage = chatRoom.createLinphoneChatMessage("Hello world"); + chatRoom.sendMessage(chatMessage, this); // main loop for receiving notifications and doing background linphonecore work running = true; @@ -153,8 +154,13 @@ public class TutorialChatRoom implements LinphoneCoreListener { @Override public void messageReceived(LinphoneCore lc, LinphoneChatRoom cr, LinphoneChatMessage message) { - // TODO Auto-generated method stub - + write("Message [" + message.getMessage() + "] received from [" + message.getFrom().asString() + "]"); + } + + @Override + public void onLinphoneChatMessageStateChanged(LinphoneChatMessage msg, + org.linphone.core.LinphoneChatMessage.State state) { + write("Sent message [" + msg.getMessage() + "] new state is " + state.toString()); } diff --git a/coreapi/linphone_tunnel.cc b/coreapi/linphone_tunnel.cc index 18fabbbe9..f0de56694 100644 --- a/coreapi/linphone_tunnel.cc +++ b/coreapi/linphone_tunnel.cc @@ -29,58 +29,199 @@ #include "private.h" #include "lpconfig.h" - LinphoneTunnel* linphone_core_get_tunnel(LinphoneCore *lc){ return lc->tunnel; } -static inline belledonnecomm::TunnelManager *bcTunnel(LinphoneTunnel *tunnel){ - return (belledonnecomm::TunnelManager *)tunnel; -} - -static inline _LpConfig *config(LinphoneTunnel *tunnel){ - return ((belledonnecomm::TunnelManager *)tunnel)->getLinphoneCore()->config; -} +struct _LinphoneTunnel { + belledonnecomm::TunnelManager *manager; + MSList *config_list; +}; extern "C" LinphoneTunnel* linphone_core_tunnel_new(LinphoneCore *lc){ - LinphoneTunnel* tunnel= (LinphoneTunnel*) new belledonnecomm::TunnelManager(lc); + LinphoneTunnel* tunnel = ms_new0(LinphoneTunnel, 1); + tunnel->manager = new belledonnecomm::TunnelManager(lc); return tunnel; } +static inline belledonnecomm::TunnelManager *bcTunnel(LinphoneTunnel *tunnel){ + return tunnel->manager; +} + +static inline _LpConfig *config(LinphoneTunnel *tunnel){ + return tunnel->manager->getLinphoneCore()->config; +} + void linphone_tunnel_destroy(LinphoneTunnel *tunnel){ - delete bcTunnel(tunnel); + delete tunnel->manager; + ms_free(tunnel); } -static void add_server_to_config(LinphoneTunnel *tunnel, const char *host, int port){ - const char *orig=lp_config_get_string(config(tunnel),"tunnel","server_addresses", NULL); +static char *linphone_tunnel_config_to_string(const LinphoneTunnelConfig *tunnel_config) { + char *str = NULL; + if(linphone_tunnel_config_get_remote_udp_mirror_port(tunnel_config) != -1) { + str = ms_strdup_printf("%s:%d:%d:%d", + linphone_tunnel_config_get_host(tunnel_config), + linphone_tunnel_config_get_port(tunnel_config), + linphone_tunnel_config_get_remote_udp_mirror_port(tunnel_config), + linphone_tunnel_config_get_delay(tunnel_config)); + } else { + str = ms_strdup_printf("%s:%d", + linphone_tunnel_config_get_host(tunnel_config), + linphone_tunnel_config_get_port(tunnel_config)); + } + return str; +} + +static LinphoneTunnelConfig *linphone_tunnel_config_from_string(const char *str) { + LinphoneTunnelConfig *tunnel_config = NULL; + char * dstr = ms_strdup(str); + const char *host = NULL; + int port = -1; + int remote_udp_mirror_port = -1; + int delay = -1; + int pos = 0; + char *pch; + pch = strtok(dstr, ":"); + while(pch != NULL) { + switch(pos) { + case 0: + host = pch; + break; + case 1: + port = atoi(pch); + break; + case 2: + remote_udp_mirror_port = atoi(pch); + break; + case 3: + delay = atoi(pch); + break; + default: + // Abort + pos = 0; + break; + + } + ++pos; + pch = strtok(NULL, ":"); + } + if(pos >= 2) { + tunnel_config = linphone_tunnel_config_new(); + linphone_tunnel_config_set_host(tunnel_config, host); + linphone_tunnel_config_set_port(tunnel_config, port); + } + if(pos >= 3) { + linphone_tunnel_config_set_remote_udp_mirror_port(tunnel_config, remote_udp_mirror_port); + } + if(pos == 4) { + linphone_tunnel_config_set_delay(tunnel_config, delay); + } + ms_free(dstr); + return tunnel_config; +} + + +static void linphone_tunnel_save_config(LinphoneTunnel *tunnel) { + MSList *elem = tunnel->config_list; + char *tmp = NULL, *old_tmp = NULL, *tc_str = NULL; + while(elem != NULL) { + LinphoneTunnelConfig *tunnel_config = (LinphoneTunnelConfig *)elem->data; + tc_str = linphone_tunnel_config_to_string(tunnel_config); + if(tmp != NULL) { + old_tmp = tmp; + tmp = ms_strdup_printf("%s %s", old_tmp, tc_str); + ms_free(old_tmp); + ms_free(tc_str); + } else { + tmp = tc_str; + } + elem = elem->next; + } + lp_config_set_string(config(tunnel), "tunnel", "server_addresses", tmp); + if(tmp != NULL) { + ms_free(tmp); + } +} + + +static void linphone_tunnel_add_server_intern(LinphoneTunnel *tunnel, LinphoneTunnelConfig *tunnel_config) { + if(linphone_tunnel_config_get_remote_udp_mirror_port(tunnel_config) == -1) { + bcTunnel(tunnel)->addServer(linphone_tunnel_config_get_host(tunnel_config), + linphone_tunnel_config_get_port(tunnel_config)); + } else { + bcTunnel(tunnel)->addServer(linphone_tunnel_config_get_host(tunnel_config), + linphone_tunnel_config_get_port(tunnel_config), + linphone_tunnel_config_get_remote_udp_mirror_port(tunnel_config), + linphone_tunnel_config_get_delay(tunnel_config)); + } + tunnel->config_list = ms_list_append(tunnel->config_list, tunnel_config); +} + + +static void linphone_tunnel_load_config(LinphoneTunnel *tunnel){ + const char * confaddress = lp_config_get_string(config(tunnel), "tunnel", "server_addresses", NULL); char *tmp; - if (orig){ - tmp=ms_strdup_printf("%s %s:%i",orig,host,port); - }else tmp=ms_strdup_printf("%s:%i",host, port); - lp_config_set_string(config(tunnel),"tunnel","server_addresses",tmp); - ms_free(tmp); + const char *it; + LinphoneTunnelConfig *tunnel_config; + int adv; + if(confaddress != NULL) { + tmp = ms_strdup(confaddress); + it = confaddress; + while(confaddress[0] != '\0') { + int ret = sscanf(it,"%s%n", tmp, &adv); + if (ret >= 1){ + it += adv; + tunnel_config = linphone_tunnel_config_from_string(tmp); + if(tunnel_config != NULL) { + linphone_tunnel_add_server_intern(tunnel, tunnel_config); + } else { + ms_error("Tunnel server address incorrectly specified from config file: %s", tmp); + } + } else break; + } + ms_free(tmp); + } } -void linphone_tunnel_add_server(LinphoneTunnel *tunnel, const char *host, int port){ - bcTunnel(tunnel)->addServer(host, port); - add_server_to_config(tunnel,host,port); +static void linphone_tunnel_refresh_config(LinphoneTunnel *tunnel) { + MSList *old_list = tunnel->config_list; + tunnel->config_list = NULL; + bcTunnel(tunnel)->cleanServers(); + while(old_list != NULL) { + LinphoneTunnelConfig *tunnel_config = (LinphoneTunnelConfig *)old_list->data; + linphone_tunnel_add_server_intern(tunnel, tunnel_config); + old_list = old_list->next; + } } -void linphone_tunnel_add_server_and_mirror(LinphoneTunnel *tunnel, const char *host, int port, int remote_udp_mirror, int delay){ - bcTunnel(tunnel)->addServer(host, port, remote_udp_mirror, delay); - /*FIXME, udp-mirror feature not saved in config*/ - add_server_to_config(tunnel,host,port); +void linphone_tunnel_add_server(LinphoneTunnel *tunnel, LinphoneTunnelConfig *tunnel_config) { + linphone_tunnel_add_server_intern(tunnel, tunnel_config); + linphone_tunnel_save_config(tunnel); } -char *linphone_tunnel_get_servers(LinphoneTunnel *tunnel){ - const char *tmp=lp_config_get_string(config(tunnel),"tunnel","server_addresses",NULL); - if (tmp) return ms_strdup(tmp); - return NULL; +void linphone_tunnel_remove_server(LinphoneTunnel *tunnel, LinphoneTunnelConfig *tunnel_config) { + MSList *elem = ms_list_find(tunnel->config_list, tunnel_config); + if(elem != NULL) { + tunnel->config_list = ms_list_remove(tunnel->config_list, tunnel_config); + linphone_tunnel_config_destroy(tunnel_config); + linphone_tunnel_refresh_config(tunnel); + linphone_tunnel_save_config(tunnel); + } +} + +const MSList *linphone_tunnel_get_servers(LinphoneTunnel *tunnel){ + return tunnel->config_list; } void linphone_tunnel_clean_servers(LinphoneTunnel *tunnel){ bcTunnel(tunnel)->cleanServers(); - lp_config_set_string(config(tunnel),"tunnel","server_addresses",NULL); + + /* Free the list */ + ms_list_for_each(tunnel->config_list, (void (*)(void *))linphone_tunnel_config_destroy); + tunnel->config_list = ms_list_free(tunnel->config_list); + + linphone_tunnel_save_config(tunnel); } void linphone_tunnel_enable(LinphoneTunnel *tunnel, bool_t enabled){ @@ -169,28 +310,6 @@ void linphone_tunnel_auto_detect(LinphoneTunnel *tunnel){ bcTunnel(tunnel)->autoDetect(); } -static void tunnel_add_servers_from_config(LinphoneTunnel *tunnel, const char* confaddress){ - char *tmp=(char*)ms_malloc0(strlen(confaddress)+1); - const char *it=confaddress; - int adv; - do{ - int ret=sscanf(it,"%s%n",tmp,&adv); - if (ret>=1){ - it+=adv; - char *port=strchr(tmp,':'); - if (!port){ - ms_error("Tunnel server addresses incorrectly specified from config file: %s",it); - break; - }else{ - *port='\0'; - port++; - bcTunnel(tunnel)->addServer(tmp, atoi(port)); - } - }else break; - }while(1); - ms_free(tmp); -} - static void my_ortp_logv(OrtpLogLevel level, const char *fmt, va_list args){ ortp_logv(level,fmt,args); } @@ -201,10 +320,8 @@ static void my_ortp_logv(OrtpLogLevel level, const char *fmt, va_list args){ */ void linphone_tunnel_configure(LinphoneTunnel *tunnel){ bool_t enabled=(bool_t)lp_config_get_int(config(tunnel),"tunnel","enabled",FALSE); - const char* addresses=lp_config_get_string(config(tunnel),"tunnel","server_addresses", NULL); linphone_tunnel_enable_logs_with_handler(tunnel,TRUE,my_ortp_logv); - if (addresses) - tunnel_add_servers_from_config(tunnel,addresses); + linphone_tunnel_load_config(tunnel); linphone_tunnel_enable(tunnel, enabled); } diff --git a/coreapi/linphone_tunnel.h b/coreapi/linphone_tunnel.h index bb343008a..e42a054dc 100644 --- a/coreapi/linphone_tunnel.h +++ b/coreapi/linphone_tunnel.h @@ -23,8 +23,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#ifndef LINPHONETUNNELMANAGER_H -#define LINPHONETUNNELMANAGER_H +#ifndef LINPHONETUNNEL_H +#define LINPHONETUNNEL_H #include "linphonecore.h" @@ -48,34 +48,108 @@ extern "C" { #endif +typedef struct _LinphoneTunnelConfig LinphoneTunnelConfig; + /** - * Add a tunnel server. At least one should be provided to be able to connect. - * When several addresses are provided, the tunnel client may try each of them until it gets connected. - * @param tunnel object - * @param host server ip address + * Create a new tunnel configuration + */ +LinphoneTunnelConfig *linphone_tunnel_config_new(); + +/** + * Set address of server. + * + * @param tunnel configuration object + * @param host tunnel server ip address + */ +void linphone_tunnel_config_set_host(LinphoneTunnelConfig *tunnel, const char *host); + +/** + * Get address of server. + * + * @param tunnel configuration object + */ +const char *linphone_tunnel_config_get_host(const LinphoneTunnelConfig *tunnel); + +/** + * Set tls port of server. + * + * @param tunnel configuration object * @param port tunnel server tls port, recommended value is 443 */ -void linphone_tunnel_add_server(LinphoneTunnel *tunnel, const char *host, int port); +void linphone_tunnel_config_set_port(LinphoneTunnelConfig *tunnel, int port); + /** - *Add tunnel server with auto detection capabilities + * Get tls port of server. * - * @param tunnel object - * @param host tunnel server ip address - * @param port tunnel server tls port, recommended value is 443 - * @param remote_udp_mirror_port remote port on the tunnel server side used to test udp reachability + * @param tunnel configuration object + */ +int linphone_tunnel_config_get_port(const LinphoneTunnelConfig *tunnel); + +/** + * Set the remote port on the tunnel server side used to test udp reachability. + * + * @param tunnel configuration object + * @param remote_udp_mirror_port remote port on the tunnel server side used to test udp reachability, set to -1 to disable the feature + */ +void linphone_tunnel_config_set_remote_udp_mirror_port(LinphoneTunnelConfig *tunnel, int remote_udp_mirror_port); + +/** + * Get the remote port on the tunnel server side used to test udp reachability. + * + * @param tunnel configuration object + */ +int linphone_tunnel_config_get_remote_udp_mirror_port(const LinphoneTunnelConfig *tunnel); + +/** + * Set the udp packet round trip delay in ms for a tunnel configuration. + * + * @param tunnel configuration object * @param delay udp packet round trip delay in ms considered as acceptable. recommended value is 1000 ms. */ -void linphone_tunnel_add_server_and_mirror(LinphoneTunnel *tunnel, const char *host, int port, int remote_udp_mirror_port, int delay); +void linphone_tunnel_config_set_delay(LinphoneTunnelConfig *tunnel, int delay); + +/** + * Get the udp packet round trip delay in ms for a tunnel configuration. + * + * @param tunnel configuration object + */ +int linphone_tunnel_config_get_delay(const LinphoneTunnelConfig *tunnel); + +/** + * Destroy a tunnel configuration + * + * @param tunnel configuration object + */ +void linphone_tunnel_config_destroy(LinphoneTunnelConfig *tunnel); + +/** + * Add tunnel server configuration + * + * @param tunnel object + * @param tunnel_config object + */ +void linphone_tunnel_add_server(LinphoneTunnel *tunnel, LinphoneTunnelConfig *tunnel_config); + +/** + * Remove tunnel server configuration + * + * @param tunnel object + * @param tunnel_config object + */ +void linphone_tunnel_remove_server(LinphoneTunnel *tunnel, LinphoneTunnelConfig *tunnel_config); + /** * @param tunnel object * returns a string of space separated list of host:port of tunnel server addresses * */ -char *linphone_tunnel_get_servers(LinphoneTunnel *tunnel); +const MSList *linphone_tunnel_get_servers(LinphoneTunnel *tunnel); + /** * @param tunnel object * Removes all tunnel server address previously entered with addServer() **/ void linphone_tunnel_clean_servers(LinphoneTunnel *tunnel); + /** * Sets whether tunneling of SIP and RTP is required. * @param tunnel object @@ -84,11 +158,13 @@ void linphone_tunnel_clean_servers(LinphoneTunnel *tunnel); * **/ void linphone_tunnel_enable(LinphoneTunnel *tunnel, bool_t enabled); + /** * @param tunnel object * Returns a boolean indicating whether tunneled operation is enabled. **/ bool_t linphone_tunnel_enabled(LinphoneTunnel *tunnel); + /** * @param tunnel object * Forces reconnection to the tunnel server. @@ -97,6 +173,7 @@ bool_t linphone_tunnel_enabled(LinphoneTunnel *tunnel); * the lost connection to be closed and new connection to be issued. **/ void linphone_tunnel_reconnect(LinphoneTunnel *tunnel); + /** * Start tunnel need detection. * @param tunnel object @@ -129,8 +206,6 @@ void linphone_tunnel_get_http_proxy(LinphoneTunnel*tunnel,const char **host, int void linphone_tunnel_set_http_proxy_auth_info(LinphoneTunnel*tunnel, const char* username,const char* passwd); -void linphone_tunnel_enable_logs(LinphoneTunnel *tunnel, bool_t enabled); - /** * @} **/ @@ -140,5 +215,5 @@ void linphone_tunnel_enable_logs(LinphoneTunnel *tunnel, bool_t enabled); #endif -#endif +#endif //LINPHONETUNNEL_H diff --git a/coreapi/linphone_tunnel_config.c b/coreapi/linphone_tunnel_config.c new file mode 100644 index 000000000..f38568016 --- /dev/null +++ b/coreapi/linphone_tunnel_config.c @@ -0,0 +1,83 @@ +/*************************************************************************** + * linphone_tunnel_config.c + * + * Copyright 2012 Belledonne Communications + ****************************************************************************/ + +/* + * 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 "linphone_tunnel.h" + +struct _LinphoneTunnelConfig { + char *host; + int port; + int remote_udp_mirror_port; + int delay; +}; + +LinphoneTunnelConfig *linphone_tunnel_config_new() { + LinphoneTunnelConfig *ltc = ms_new0(LinphoneTunnelConfig,1); + ltc->remote_udp_mirror_port = 12345; + ltc->delay = 1000; + return ltc; +} + +void linphone_tunnel_config_set_host(LinphoneTunnelConfig *tunnel, const char *host) { + if(tunnel->host != NULL) { + ms_free(tunnel->host); + tunnel->host = NULL; + } + if(host != NULL && strlen(host)) { + tunnel->host = ms_strdup(host); + } +} + +const char *linphone_tunnel_config_get_host(const LinphoneTunnelConfig *tunnel) { + return tunnel->host; +} + +void linphone_tunnel_config_set_port(LinphoneTunnelConfig *tunnel, int port) { + tunnel->port = port; +} + +int linphone_tunnel_config_get_port(const LinphoneTunnelConfig *tunnel) { + return tunnel->port; +} + +void linphone_tunnel_config_set_remote_udp_mirror_port(LinphoneTunnelConfig *tunnel, int remote_udp_mirror_port) { + tunnel->remote_udp_mirror_port = remote_udp_mirror_port; +} + +int linphone_tunnel_config_get_remote_udp_mirror_port(const LinphoneTunnelConfig *tunnel) { + return tunnel->remote_udp_mirror_port; +} + +void linphone_tunnel_config_set_delay(LinphoneTunnelConfig *tunnel, int delay) { + tunnel->delay = delay; +} + +int linphone_tunnel_config_get_delay(const LinphoneTunnelConfig *tunnel) { + return tunnel->delay; +} + +void linphone_tunnel_config_destroy(LinphoneTunnelConfig *tunnel) { + if(tunnel->host != NULL) { + ms_free(tunnel->host); + } + ms_free(tunnel); +} + diff --git a/coreapi/linphone_tunnel_stubs.c b/coreapi/linphone_tunnel_stubs.c index d7fb27796..0560b3956 100644 --- a/coreapi/linphone_tunnel_stubs.c +++ b/coreapi/linphone_tunnel_stubs.c @@ -38,14 +38,15 @@ LinphoneTunnel* linphone_core_get_tunnel(LinphoneCore *lc){ void linphone_tunnel_destroy(LinphoneTunnel *tunnel){ } -void linphone_tunnel_add_server(LinphoneTunnel *tunnel, const char *host, int port){ + +void linphone_tunnel_add_server(LinphoneTunnel *tunnel, LinphoneTunnelConfig *tunnel_config){ } -void linphone_tunnel_add_server_and_mirror(LinphoneTunnel *tunnel, const char *host, int port, int remote_udp_mirror, int delay){ +void linphone_tunnel_remove_server(LinphoneTunnel *tunnel, LinphoneTunnelConfig *tunnel_config){ } -char *linphone_tunnel_get_servers(LinphoneTunnel *tunnel){ - return NULL; +const MSList *linphone_tunnel_get_servers(LinphoneTunnel *tunnel){ + return NULL; } void linphone_tunnel_clean_servers(LinphoneTunnel *tunnel){ @@ -55,9 +56,10 @@ void linphone_tunnel_enable(LinphoneTunnel *tunnel, bool_t enabled){ } bool_t linphone_tunnel_enabled(LinphoneTunnel *tunnel){ - return FALSE; + return FALSE; } + void linphone_tunnel_enable_logs_with_handler(LinphoneTunnel *tunnel, bool_t enabled, OrtpLogFunc logHandler){ } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index b1b6e6c6b..9545af23f 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -65,6 +65,7 @@ static void linphone_core_run_hooks(LinphoneCore *lc); static void linphone_core_free_hooks(LinphoneCore *lc); #include "enum.h" + const char *linphone_core_get_nat_address_resolved(LinphoneCore *lc); static void toggle_video_preview(LinphoneCore *lc, bool_t val); @@ -565,6 +566,7 @@ static void sip_config_read(LinphoneCore *lc) sal_set_root_ca(lc->sal, lp_config_get_string(lc->config,"sip","root_ca", ROOT_CA_FILE)); #endif linphone_core_verify_server_certificates(lc,lp_config_get_int(lc->config,"sip","verify_server_certs",TRUE)); + linphone_core_verify_server_cn(lc,lp_config_get_int(lc->config,"sip","verify_server_cn",TRUE)); /*setting the dscp must be done before starting the transports, otherwise it is not taken into effect*/ sal_set_dscp(lc->sal,linphone_core_get_sip_dscp(lc)); /*start listening on ports*/ @@ -2585,6 +2587,19 @@ bool_t linphone_core_inc_invite_pending(LinphoneCore*lc){ return FALSE; } +bool_t linphone_core_incompatible_security(LinphoneCore *lc, SalMediaDescription *md){ + if (linphone_core_is_media_encryption_mandatory(lc) && linphone_core_get_media_encryption(lc)==LinphoneMediaEncryptionSRTP){ + int i; + for(i=0;instreams;i++){ + SalStreamDescription *sd=&md->streams[i]; + if (sd->proto!=SalProtoRtpSavp){ + return TRUE; + } + } + } + return FALSE; +} + void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call){ char *barmesg; char *tmp; @@ -2596,10 +2611,12 @@ void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call){ linphone_call_make_local_media_description(lc,call); sal_call_set_local_media_description(call->op,call->localdesc); md=sal_call_get_final_media_description(call->op); - if (md && sal_media_description_empty(md)){ - sal_call_decline(call->op,SalReasonMedia,NULL); - linphone_call_unref(call); - return; + if (md){ + if (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md)){ + sal_call_decline(call->op,SalReasonMedia,NULL); + linphone_call_unref(call); + return; + } } from_parsed=linphone_address_new(sal_op_get_from(call->op)); @@ -3802,6 +3819,13 @@ void linphone_core_verify_server_certificates(LinphoneCore *lc, bool_t yesno){ sal_verify_server_certificates(lc->sal,yesno); } +/** + * Specify whether the tls server certificate common name must be verified when connecting to a SIP/TLS server. +**/ +void linphone_core_verify_server_cn(LinphoneCore *lc, bool_t yesno){ + sal_verify_server_cn(lc->sal,yesno); +} + static void notify_end_of_ring(void *ud, MSFilter *f, unsigned int event, void *arg){ LinphoneCore *lc=(LinphoneCore*)ud; lc->preview_finished=1; diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index b4c25380a..1003e9546 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -1210,6 +1210,7 @@ void linphone_core_set_sound_source(LinphoneCore *lc, char source); void linphone_core_set_ring(LinphoneCore *lc, const char *path); const char *linphone_core_get_ring(const LinphoneCore *lc); void linphone_core_verify_server_certificates(LinphoneCore *lc, bool_t yesno); +void linphone_core_verify_server_cn(LinphoneCore *lc, bool_t yesno); void linphone_core_set_root_ca(LinphoneCore *lc, const char *path); const char *linphone_core_get_root_ca(LinphoneCore *lc); void linphone_core_set_ringback(LinphoneCore *lc, const char *path); @@ -1430,7 +1431,7 @@ void linphone_core_init_default_params(LinphoneCore*lc, LinphoneCallParams *para */ bool_t linphone_core_tunnel_available(void); -typedef struct LinphoneTunnel LinphoneTunnel; +typedef struct _LinphoneTunnel LinphoneTunnel; /** * get tunnel instance if available */ diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index a6a561c86..4144c1441 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -23,9 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "linphonecore_utils.h" #include -#ifdef TUNNEL_ENABLED -#include "linphone_tunnel.h" -#endif extern "C" { #include "mediastreamer2/mediastream.h" @@ -34,6 +31,8 @@ extern "C" { #include "private.h" #include +#include "lpconfig.h" + #ifdef ANDROID #include extern "C" void libmsilbc_init(); @@ -2126,8 +2125,14 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_tunnelAddServerAndMirror jstring jHost, jint port, jint mirror, jint delay) { LinphoneTunnel *tunnel=((LinphoneCore *) pCore)->tunnel; if (!tunnel) return; + const char* cHost=env->GetStringUTFChars(jHost, NULL); - linphone_tunnel_add_server_and_mirror(tunnel, cHost, port, mirror, delay); + LinphoneTunnelConfig *tunnelconfig = linphone_tunnel_config_new(); + linphone_tunnel_config_set_host(tunnelconfig, cHost); + linphone_tunnel_config_set_port(tunnelconfig, port); + linphone_tunnel_config_set_delay(tunnelconfig, delay); + linphone_tunnel_config_set_remote_udp_mirror_port(tunnelconfig, mirror); + linphone_tunnel_add_server(tunnel, tunnelconfig); env->ReleaseStringUTFChars(jHost, cHost); } @@ -2149,7 +2154,6 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_tunnelSetHttpProxy(JNIEn extern "C" void Java_org_linphone_core_LinphoneCoreImpl_tunnelAutoDetect(JNIEnv *env,jobject thiz,jlong pCore) { LinphoneTunnel *tunnel=((LinphoneCore *) pCore)->tunnel; if (!tunnel) return; linphone_tunnel_auto_detect(tunnel); - } extern "C" void Java_org_linphone_core_LinphoneCoreImpl_tunnelCleanServers(JNIEnv *env,jobject thiz,jlong pCore) { @@ -2220,3 +2224,17 @@ extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getVersion(JNIEnv* e jstring jvalue =env->NewStringUTF(linphone_core_get_version()); return jvalue; } + +extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_getConfig(JNIEnv *env, jobject thiz, jlong lc) { + return (jlong) linphone_core_get_config((LinphoneCore *)lc); +} + +extern "C" void Java_org_linphone_core_LpConfigImpl_setInt(JNIEnv *env, jobject thiz, jlong lpc, + jstring section, jstring key, jint value) { + const char *csection = env->GetStringUTFChars(section, NULL); + const char *ckey = env->GetStringUTFChars(key, NULL); + lp_config_set_int((LpConfig *)lpc, csection, ckey, (int) value); + env->ReleaseStringUTFChars(section, csection); + env->ReleaseStringUTFChars(key, ckey); +} + diff --git a/coreapi/lpconfig.c b/coreapi/lpconfig.c index bd2adfbb4..8457cf650 100644 --- a/coreapi/lpconfig.c +++ b/coreapi/lpconfig.c @@ -109,7 +109,7 @@ static bool_t is_first_char(const char *start, const char *pos){ return TRUE; } -LpSection *lp_config_find_section(LpConfig *lpconfig, const char *name){ +LpSection *lp_config_find_section(const LpConfig *lpconfig, const char *name){ LpSection *sec; MSList *elem; /*printf("Looking for section %s\n",name);*/ @@ -123,7 +123,7 @@ LpSection *lp_config_find_section(LpConfig *lpconfig, const char *name){ return NULL; } -LpItem *lp_section_find_item(LpSection *sec, const char *name){ +LpItem *lp_section_find_item(const LpSection *sec, const char *name){ MSList *elem; LpItem *item; /*printf("Looking for item %s\n",name);*/ @@ -260,7 +260,7 @@ void lp_section_remove_item(LpSection *sec, LpItem *item){ lp_item_destroy(item); } -const char *lp_config_get_string(LpConfig *lpconfig, const char *section, const char *key, const char *default_string){ +const char *lp_config_get_string(const LpConfig *lpconfig, const char *section, const char *key, const char *default_string){ LpSection *sec; LpItem *item; sec=lp_config_find_section(lpconfig,section); @@ -271,7 +271,7 @@ const char *lp_config_get_string(LpConfig *lpconfig, const char *section, const return default_string; } -bool_t lp_config_get_range(LpConfig *lpconfig, const char *section, const char *key, int *min, int *max, int default_min, int default_max) { +bool_t lp_config_get_range(const LpConfig *lpconfig, const char *section, const char *key, int *min, int *max, int default_min, int default_max) { const char *str = lp_config_get_string(lpconfig, section, key, NULL); if (str != NULL) { char *minusptr = strchr(str, '-'); @@ -290,7 +290,7 @@ bool_t lp_config_get_range(LpConfig *lpconfig, const char *section, const char * } } -int lp_config_get_int(LpConfig *lpconfig,const char *section, const char *key, int default_value){ +int lp_config_get_int(const LpConfig *lpconfig,const char *section, const char *key, int default_value){ const char *str=lp_config_get_string(lpconfig,section,key,NULL); if (str!=NULL) { int ret=0; @@ -302,7 +302,7 @@ int lp_config_get_int(LpConfig *lpconfig,const char *section, const char *key, i else return default_value; } -int64_t lp_config_get_int64(LpConfig *lpconfig,const char *section, const char *key, int64_t default_value){ +int64_t lp_config_get_int64(const LpConfig *lpconfig,const char *section, const char *key, int64_t default_value){ const char *str=lp_config_get_string(lpconfig,section,key,NULL); if (str!=NULL) { #ifdef WIN32 @@ -314,7 +314,7 @@ int64_t lp_config_get_int64(LpConfig *lpconfig,const char *section, const char * else return default_value; } -float lp_config_get_float(LpConfig *lpconfig,const char *section, const char *key, float default_value){ +float lp_config_get_float(const LpConfig *lpconfig,const char *section, const char *key, float default_value){ const char *str=lp_config_get_string(lpconfig,section,key,NULL); float ret=default_value; if (str==NULL) return default_value; @@ -404,11 +404,32 @@ int lp_config_sync(LpConfig *lpconfig){ return 0; } -int lp_config_has_section(LpConfig *lpconfig, const char *section){ +int lp_config_has_section(const LpConfig *lpconfig, const char *section){ if (lp_config_find_section(lpconfig,section)!=NULL) return 1; return 0; } +void lp_config_for_each_section(const LpConfig *lpconfig, void (*callback)(const char *section, void *ctx), void *ctx) { + LpSection *sec; + MSList *elem; + for (elem=lpconfig->sections;elem!=NULL;elem=ms_list_next(elem)){ + sec=(LpSection*)elem->data; + callback(sec->name, ctx); + } +} + +void lp_config_for_each_entry(const LpConfig *lpconfig, const char *section, void (*callback)(const char *entry, void *ctx), void *ctx) { + LpItem *item; + MSList *elem; + LpSection *sec=lp_config_find_section(lpconfig,section); + if (sec!=NULL){ + for (elem=sec->items;elem!=NULL;elem=ms_list_next(elem)){ + item=(LpItem*)elem->data; + callback(item->key, ctx); + } + } +} + void lp_config_clean_section(LpConfig *lpconfig, const char *section){ LpSection *sec=lp_config_find_section(lpconfig,section); if (sec!=NULL){ diff --git a/coreapi/lpconfig.h b/coreapi/lpconfig.h index 8e6f92128..310baaff3 100644 --- a/coreapi/lpconfig.h +++ b/coreapi/lpconfig.h @@ -73,7 +73,7 @@ int lp_config_read_file(LpConfig *lpconfig, const char *filename); * @ingroup misc * The default value string is returned if the config item isn't found. **/ -const char *lp_config_get_string(LpConfig *lpconfig, const char *section, const char *key, const char *default_string); +const char *lp_config_get_string(const LpConfig *lpconfig, const char *section, const char *key, const char *default_string); int lp_config_read_file(LpConfig *lpconfig, const char *filename); /** * Retrieves a configuration item as a range, given its section, key, and default min and max values. @@ -82,14 +82,14 @@ int lp_config_read_file(LpConfig *lpconfig, const char *filename); * @return TRUE if the value is successfully parsed as a range, FALSE otherwise. * If FALSE is returned, min and max are filled respectively with default_min and default_max values. */ -bool_t lp_config_get_range(LpConfig *lpconfig, const char *section, const char *key, int *min, int *max, int default_min, int default_max); +bool_t lp_config_get_range(const LpConfig *lpconfig, const char *section, const char *key, int *min, int *max, int default_min, int default_max); /** * Retrieves a configuration item as an integer, given its section, key, and default value. * * @ingroup misc * The default integer value is returned if the config item isn't found. **/ -int lp_config_get_int(LpConfig *lpconfig,const char *section, const char *key, int default_value); +int lp_config_get_int(const LpConfig *lpconfig,const char *section, const char *key, int default_value); /** * Retrieves a configuration item as a 64 bit integer, given its section, key, and default value. @@ -97,7 +97,7 @@ int lp_config_get_int(LpConfig *lpconfig,const char *section, const char *key, i * @ingroup misc * The default integer value is returned if the config item isn't found. **/ -int64_t lp_config_get_int64(LpConfig *lpconfig,const char *section, const char *key, int64_t default_value); +int64_t lp_config_get_int64(const LpConfig *lpconfig,const char *section, const char *key, int64_t default_value); int lp_config_read_file(LpConfig *lpconfig, const char *filename); @@ -107,7 +107,7 @@ int lp_config_read_file(LpConfig *lpconfig, const char *filename); * @ingroup misc * The default float value is returned if the config item isn't found. **/ -float lp_config_get_float(LpConfig *lpconfig,const char *section, const char *key, float default_value); +float lp_config_get_float(const LpConfig *lpconfig,const char *section, const char *key, float default_value); /** * Sets a string config item * @@ -158,13 +158,26 @@ int lp_config_sync(LpConfig *lpconfig); * * @ingroup misc **/ -int lp_config_has_section(LpConfig *lpconfig, const char *section); +int lp_config_has_section(const LpConfig *lpconfig, const char *section); /** * Removes every pair of key,value in a section and remove the section. * * @ingroup misc **/ void lp_config_clean_section(LpConfig *lpconfig, const char *section); +/** + * Call a function for each section present in the configuration. + * + * @ingroup misc +**/ +void lp_config_for_each_section(const LpConfig *lpconfig, void (*callback)(const char *section, void *ctx), void *ctx); +/** + * Call a function for each entry present in a section configuration. + * + * @ingroup misc +**/ +void lp_config_for_each_entry(const LpConfig *lpconfig, const char *section, void (*callback)(const char *entry, void *ctx), void *ctx); + /*tells whether uncommited (with lp_config_sync()) modifications exist*/ int lp_config_needs_commit(const LpConfig *lpconfig); void lp_config_destroy(LpConfig *cfg); diff --git a/coreapi/plugins/buddylookup/configure.ac b/coreapi/plugins/buddylookup/configure.ac index 5e61343da..b3c3c711f 100644 --- a/coreapi/plugins/buddylookup/configure.ac +++ b/coreapi/plugins/buddylookup/configure.ac @@ -22,7 +22,7 @@ AC_ARG_ENABLE(strict, [wall_werror=yes] ) -dnl AC_CONFIG_HEADER([config.h]) +dnl AC_CONFIG_HEADERS([config.h]) # Checks for programs. AC_PROG_CC diff --git a/coreapi/private.h b/coreapi/private.h index 91b0b32c0..41449dc9e 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -308,6 +308,7 @@ int linphone_core_start_update_call(LinphoneCore *lc, LinphoneCall *call); int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call); void linphone_core_start_refered_call(LinphoneCore *lc, LinphoneCall *call); void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call); +bool_t linphone_core_incompatible_security(LinphoneCore *lc, SalMediaDescription *md); extern SalCallbacks linphone_sal_callbacks; void linphone_proxy_config_set_error(LinphoneProxyConfig *cfg, LinphoneReason error); bool_t linphone_core_rtcp_enabled(const LinphoneCore *lc); diff --git a/coreapi/sal.c b/coreapi/sal.c index 7a3bbdf7b..2b09212aa 100644 --- a/coreapi/sal.c +++ b/coreapi/sal.c @@ -151,6 +151,7 @@ static bool_t payload_type_equals(const PayloadType *p1, const PayloadType *p2){ if (strcmp(p1->mime_type,p2->mime_type)!=0) return FALSE; if (p1->clock_rate!=p2->clock_rate) return FALSE; if (p1->channels!=p2->channels) return FALSE; + if (payload_type_get_number(p1) != payload_type_get_number(p2)) return FALSE; /* Do not compare fmtp right now: they are modified internally when the call is started */ diff --git a/coreapi/sal.h b/coreapi/sal.h index 77e43d6b1..9c0ceca76 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -359,6 +359,7 @@ void sal_use_101(Sal *ctx, bool_t use_101); void sal_set_root_ca(Sal* ctx, const char* rootCa); const char *sal_get_root_ca(Sal* ctx); void sal_verify_server_certificates(Sal *ctx, bool_t verify); +void sal_verify_server_cn(Sal *ctx, bool_t verify); int sal_iterate(Sal *sal); MSList * sal_get_pending_auths(Sal *sal); diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index b26751a71..93686a75e 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -282,6 +282,7 @@ Sal * sal_init(){ sal->reuse_authorization=FALSE; sal->rootCa = 0; sal->verify_server_certs=TRUE; + sal->verify_server_cn=TRUE; sal->expire_old_contact=FALSE; sal->add_dates=FALSE; sal->dscp=-1; @@ -378,6 +379,9 @@ static void set_tls_options(Sal *ctx){ #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE eXosip_tls_verify_certificate(ctx->verify_server_certs); #endif +#ifdef HAVE_EXOSIP_TLS_VERIFY_CN + eXosip_tls_verify_cn(ctx->verify_server_cn); +#endif } void sal_set_dscp(Sal *ctx, int dscp){ @@ -397,12 +401,12 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i switch (tr) { case SalTransportUDP: proto=IPPROTO_UDP; - eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive); + eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive); break; case SalTransportTCP: case SalTransportTLS: proto= IPPROTO_TCP; - keepalive=-1; + keepalive=-1; eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive); set_tls_options(ctx); break; @@ -499,6 +503,13 @@ void sal_verify_server_certificates(Sal *ctx, bool_t verify){ #endif } +void sal_verify_server_cn(Sal *ctx, bool_t verify){ + ctx->verify_server_cn=verify; +#ifdef HAVE_EXOSIP_TLS_VERIFY_CN + eXosip_tls_verify_cn(verify); +#endif +} + static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){ osip_via_t *via=NULL; osip_generic_param_t *param=NULL; @@ -938,8 +949,13 @@ int sal_call_terminate(SalOp *h){ } void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){ - if (h->terminated) return; - if (h->pending_auth){ + bool_t terminating=FALSE; + if (h->pending_auth && strcmp(h->pending_auth->request->sip_method,"BYE")==0) { + terminating=TRUE; + } + if (h->terminated && !terminating) return; + + if (h->pending_auth){ push_auth_to_exosip(info); /*FIXME exosip does not take into account this update register message*/ diff --git a/coreapi/sal_eXosip2.h b/coreapi/sal_eXosip2.h index 29eee78ae..89ac93abf 100644 --- a/coreapi/sal_eXosip2.h +++ b/coreapi/sal_eXosip2.h @@ -48,6 +48,7 @@ struct Sal{ bool_t use_101; bool_t reuse_authorization; bool_t verify_server_certs; + bool_t verify_server_cn; bool_t expire_old_contact; bool_t add_dates; }; diff --git a/coreapi/sal_eXosip2_presence.c b/coreapi/sal_eXosip2_presence.c index 3559081db..078ec24b4 100644 --- a/coreapi/sal_eXosip2_presence.c +++ b/coreapi/sal_eXosip2_presence.c @@ -209,108 +209,108 @@ static void mk_presence_body (const SalPresenceStatus online_status, const char if (online_status==SalPresenceOnline) { - snprintf(buf, buflen, "\n\ -\n\ -\n\ -\n\ -\n\ -
\n\ -\n\ -\n\ -
\n\ -
\n\ -
", contact_info, atom_id, contact_info); + snprintf(buf, buflen, "\n" +"\n" +"\n" +"\n" +"\n" +"
\n" +"\n" +"\n" +"
\n" +"
\n" +"
", contact_info, atom_id, contact_info); } else if (online_status == SalPresenceBusy || online_status == SalPresenceDonotdisturb) { - snprintf(buf, buflen, "\n\ -\n\ -\n\ -\n\ -\n\ -
\n\ -\n\ -\n\ -
\n\ -
\n
", contact_info, atom_id, contact_info); + snprintf(buf, buflen, "\n" +"\n" +"\n" +"\n" +"\n" +"
\n" +"\n" +"\n" +"
\n" +"
\n
", contact_info, atom_id, contact_info); } else if (online_status==SalPresenceBerightback) { - snprintf(buf, buflen, "\n\ -\n\ -\n\ -\n\ -\n\ -
\n\ -\n\ -\n\ -
\n\ -
\n\ -
", contact_info, atom_id, contact_info); + snprintf(buf, buflen, "\n" +"\n" +"\n" +"\n" +"\n" +"
\n" +"\n" +"\n" +"
\n" +"
\n" +"
", contact_info, atom_id, contact_info); } else if (online_status == SalPresenceAway || online_status == SalPresenceMoved) { - snprintf(buf, buflen, "\n\ -\n\ -\n\ -\n\ -\n\ -
\n\ -\n\ -\n\ -
\n\ -
\n\ -
", contact_info, atom_id, contact_info); + snprintf(buf, buflen, "\n" +"\n" +"\n" +"\n" +"\n" +"
\n" +"\n" +"\n" +"
\n" +"
\n" +"
", contact_info, atom_id, contact_info); } else if (online_status==SalPresenceOnthephone) { - snprintf(buf, buflen, "\n\ -\n\ -\n\ -\n\ -\n\ -
\n\ -\n\ -\n\ -
\n\ -
\n\ -
", contact_info, atom_id, contact_info); + snprintf(buf, buflen, "\n" +"\n" +"\n" +"\n" +"\n" +"
\n" +"\n" +"\n" +"
\n" +"
\n" +"
", contact_info, atom_id, contact_info); } else if (online_status==SalPresenceOuttolunch) { - snprintf(buf, buflen, "\n\ -\n\ -\n\ -\n\ -\n\ -
\n\ -\n\ -\n\ -
\n\ -
\n\ -
", contact_info, atom_id, contact_info); + snprintf(buf, buflen, "\n" +"\n" +"\n" +"\n" +"\n" +"
\n" +"\n" +"\n" +"
\n" +"
\n" +"
", contact_info, atom_id, contact_info); } else { - snprintf(buf, buflen, "\n\ -\n\ -\n\ -\n\ -\n\ -
\n\ -\n\ -\n\ -
\n\ -
\n\ -
", contact_info, atom_id, contact_info); + snprintf(buf, buflen, "\n" +"\n" +"\n" +"\n" +"\n" +"
\n" +"\n" +"\n" +"
\n" +"
\n" +"
", contact_info, atom_id, contact_info); } break; } @@ -323,108 +323,108 @@ static void mk_presence_body (const SalPresenceStatus online_status, const char if (online_status==SalPresenceOnline) { - snprintf(buf, buflen, "\n\ -\n\ -\n\ -\n\ -\n\ -
\n\ -\n\ -\n\ -
\n\ -
\n\ -
", contact_info, atom_id, contact_info); + snprintf(buf, buflen, "\n" +"\n" +"\n" +"\n" +"\n" +"
\n" +"\n" +"\n" +"
\n" +"
\n" +"
", contact_info, atom_id, contact_info); } else if (online_status == SalPresenceBusy || online_status == SalPresenceDonotdisturb) { - snprintf(buf, buflen, "\n\ -\n\ -\n\ -\n\ -\n\ -
\n\ -\n\ -\n\ -
\n\ -
\n
", contact_info, atom_id, contact_info); + snprintf(buf, buflen, "\n" +"\n" +"\n" +"\n" +"\n" +"
\n" +"\n" +"\n" +"
\n" +"
\n
", contact_info, atom_id, contact_info); } else if (online_status==SalPresenceBerightback) { - snprintf(buf, buflen, "\n\ -\n\ -\n\ -\n\ -\n\ -
\n\ -\n\ -\n\ -
\n\ -
\n\ -
", contact_info, atom_id, contact_info); + snprintf(buf, buflen, "\n" +"\n" +"\n" +"\n" +"\n" +"
\n" +"\n" +"\n" +"
\n" +"
\n" +"
", contact_info, atom_id, contact_info); } else if (online_status == SalPresenceAway || online_status == SalPresenceMoved) { - snprintf(buf, buflen, "\n\ -\n\ -\n\ -\n\ -\n\ -
\n\ -\n\ -\n\ -
\n\ -
\n\ -
", contact_info, atom_id, contact_info); + snprintf(buf, buflen, "\n" +"\n" +"\n" +"\n" +"\n" +"
\n" +"\n" +"\n" +"
\n" +"
\n" +"
", contact_info, atom_id, contact_info); } else if (online_status==SalPresenceOnthephone) { - snprintf(buf, buflen, "\n\ -\n\ -\n\ -\n\ -\n\ -
\n\ -\n\ -\n\ -
\n\ -
\n\ -
", contact_info, atom_id, contact_info); + snprintf(buf, buflen, "\n" +"\n" +"\n" +"\n" +"\n" +"
\n" +"\n" +"\n" +"
\n" +"
\n" +"
", contact_info, atom_id, contact_info); } else if (online_status==SalPresenceOuttolunch) { - snprintf(buf, buflen, "\n\ -\n\ -\n\ -\n\ -\n\ -
\n\ -\n\ -\n\ -
\n\ -
\n\ -
", contact_info, atom_id, contact_info); + snprintf(buf, buflen, "\n" +"\n" +"\n" +"\n" +"\n" +"
\n" +"\n" +"\n" +"
\n" +"
\n" +"
", contact_info, atom_id, contact_info); } else { - snprintf(buf, buflen, "\n\ -\n\ -\n\ -\n\ -\n\ -
\n\ -\n\ -\n\ -
\n\ -
\n\ -
", contact_info, atom_id, contact_info); + snprintf(buf, buflen, "\n" +"\n" +"\n" +"\n" +"\n" +"
\n" +"\n" +"\n" +"
\n" +"
\n" +"
", contact_info, atom_id, contact_info); } break; } @@ -432,118 +432,118 @@ static void mk_presence_body (const SalPresenceStatus online_status, const char if (online_status==SalPresenceOnline) { - snprintf(buf, buflen, "\n\ -\n\ -\n\ -open\n\ -%s\n\ -\n\ -", + snprintf(buf, buflen, "\n" +"\n" +"\n" +"open\n" +"%s\n" +"\n" +"", contact_info, contact_info); } else if (online_status == SalPresenceBusy || online_status == SalPresenceDonotdisturb) { - snprintf(buf, buflen, "\n\ -\n\ -\n\ -open\n\ -%s\n\ -\n\ -\n\ -\n\ -\n\ -", + snprintf(buf, buflen, "\n" +"\n" +"\n" +"open\n" +"%s\n" +"\n" +"\n" +"\n" +"\n" +"", contact_info, contact_info); } else if (online_status==SalPresenceBerightback) { - snprintf(buf, buflen, "\n\ -\n\ -\n\ -open\n\ -%s\n\ -\n\ -\n\ -\n\ -\n\ -", + snprintf(buf, buflen, "\n" +"\n" +"\n" +"open\n" +"%s\n" +"\n" +"\n" +"\n" +"\n" +"", contact_info, contact_info); } else if (online_status == SalPresenceAway || online_status == SalPresenceMoved) { - snprintf(buf, buflen, "\n\ -\n\ -\n\ -open\n\ -%s\n\ -\n\ -\n\ -\n\ -\n\ -", + snprintf(buf, buflen, "\n" +"\n" +"\n" +"open\n" +"%s\n" +"\n" +"\n" +"\n" +"\n" +"", contact_info, contact_info); } else if (online_status==SalPresenceOnthephone) { - snprintf(buf, buflen, "\n\ -\n\ -\n\ -open\n\ -%s\n\ -\n\ -\n\ -\n\ -\n\ -", + snprintf(buf, buflen, "\n" +"\n" +"\n" +"open\n" +"%s\n" +"\n" +"\n" +"\n" +"\n" +"", contact_info, contact_info); } else if (online_status==SalPresenceOuttolunch) { - snprintf(buf, buflen, "\n\ -\n\ -\n\ -open\n\ -%s\n\ -\n\ -\n\ -\n\ -Out to lunch \n\ -\n\ -", + snprintf(buf, buflen, "\n" +"\n" +"\n" +"open\n" +"%s\n" +"\n" +"\n" +"\n" +"Out to lunch \n" +"\n" +"", contact_info, contact_info); } else { - snprintf(buf, buflen, "\n\ -\n\ -\n\ -closed\n\ -%s\n\ -\n\ -\n", contact_info, contact_info); + snprintf(buf, buflen, "\n" +"\n" +"\n" +"closed\n" +"%s\n" +"\n" +"\n", contact_info, contact_info); } break; } diff --git a/gtk/chat.c b/gtk/chat.c index 8b165f1fa..257a55758 100644 --- a/gtk/chat.c +++ b/gtk/chat.c @@ -31,8 +31,10 @@ void linphone_gtk_quit_chatroom(LinphoneChatRoom *cr) { int idx = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"idx")); g_return_if_fail(w!=NULL); gtk_notebook_remove_page (GTK_NOTEBOOK(nb),idx); - linphone_gtk_update_chat_picture(FALSE); + linphone_gtk_create_chat_picture(FALSE); g_object_set_data(G_OBJECT(friendlist),"chatview",NULL); + g_object_set_data(G_OBJECT(w),"from_message",NULL); + g_object_set_data(G_OBJECT(w),"cr",NULL); gtk_widget_destroy(w); } @@ -40,12 +42,19 @@ GtkWidget *create_tab_chat_header(LinphoneChatRoom *cr,const LinphoneAddress *ur GtkWidget *w=gtk_hbox_new (FALSE,0); GtkWidget *i=create_pixmap ("chat.png"); GtkWidget *l; - GtkWidget *b=gtk_button_new_with_label("x"); + GtkWidget *image=gtk_image_new_from_stock(GTK_STOCK_CLOSE,GTK_ICON_SIZE_MENU); + GtkWidget *b=gtk_button_new(); - gtk_widget_set_size_request(b,20,20); + gtk_button_set_image(GTK_BUTTON(b),image); + gtk_button_set_relief(GTK_BUTTON(b),GTK_RELIEF_NONE); + gtk_widget_set_size_request(b,25,20); g_signal_connect_swapped(G_OBJECT(b),"clicked",G_CALLBACK(linphone_gtk_quit_chatroom),cr); - gchar *text=g_strdup_printf("Chat "); - l=gtk_label_new (text); + + const char *display=linphone_address_get_display_name(uri); + if (display==NULL || display[0]=='\0') { + display=linphone_address_get_username(uri); + } + l=gtk_label_new (display); gtk_box_pack_start (GTK_BOX(w),i,FALSE,FALSE,0); gtk_box_pack_start (GTK_BOX(w),l,FALSE,FALSE,0); gtk_box_pack_end(GTK_BOX(w),b,TRUE,TRUE,0); @@ -53,57 +62,85 @@ GtkWidget *create_tab_chat_header(LinphoneChatRoom *cr,const LinphoneAddress *ur return w; } +void udpate_tab_chat_header(GtkWidget *chat_view,const LinphoneAddress *uri,LinphoneChatRoom *cr){ + GtkWidget *main_window=linphone_gtk_get_main_window(); + GtkNotebook *notebook=GTK_NOTEBOOK(linphone_gtk_get_widget(main_window,"viewswitch")); + GtkWidget *w=gtk_hbox_new (FALSE,0); + GtkWidget *i=create_pixmap ("chat.png"); + GtkWidget *l; + GtkWidget *image=gtk_image_new_from_stock(GTK_STOCK_CLOSE,GTK_ICON_SIZE_MENU); + GtkWidget *b=gtk_button_new(); + + gtk_button_set_image(GTK_BUTTON(b),image); + gtk_button_set_relief(GTK_BUTTON(b),GTK_RELIEF_NONE); + gtk_widget_set_size_request(b,25,20); + g_signal_connect_swapped(G_OBJECT(b),"clicked",G_CALLBACK(linphone_gtk_quit_chatroom),cr); + + const char *display=linphone_address_get_display_name(uri); + if (display==NULL || display[0]=='\0') { + display=linphone_address_get_username(uri); + } + l=gtk_label_new (display); + gtk_box_pack_start (GTK_BOX(w),i,FALSE,FALSE,0); + gtk_box_pack_start (GTK_BOX(w),l,FALSE,FALSE,0); + gtk_box_pack_end(GTK_BOX(w),b,TRUE,TRUE,0); + + gtk_notebook_set_tab_label(notebook,chat_view,w); + gtk_widget_show_all(w); + +} + void linphone_gtk_push_text(GtkWidget *w, const LinphoneAddress *from, const char *message, gboolean me,LinphoneChatRoom *cr){ GtkTextView *text=GTK_TEXT_VIEW(linphone_gtk_get_widget(w,"textview")); GtkTextBuffer *buffer=gtk_text_view_get_buffer(text); - GtkTextIter iter,begin; - GList *l = g_object_get_data(G_OBJECT(w),"list"); + GtkTextIter iter,begin,end; gtk_text_buffer_get_start_iter(buffer,&begin); int off; gtk_text_buffer_get_end_iter(buffer,&iter); off=gtk_text_iter_get_offset(&iter); + GList *list=g_object_get_data(G_OBJECT(w),"list"); if(g_strcmp0((char *)g_object_get_data(G_OBJECT(w),"from_message"),linphone_address_as_string(from))!=0){ gtk_text_buffer_get_iter_at_offset(buffer,&iter,off); const char *display=linphone_address_get_display_name(from); if (display==NULL || display[0]=='\0') { display=linphone_address_get_username(from); - } - gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,display,-1,"bold",NULL); + } gtk_text_buffer_get_end_iter(buffer,&iter); - gtk_text_buffer_insert(buffer,&iter,":",-1); + gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,display,-1,"bold",me ? "left" : "left",NULL); gtk_text_buffer_get_end_iter(buffer,&iter); gtk_text_buffer_insert(buffer,&iter,"\n",-1); g_object_set_data(G_OBJECT(w),"from_message",linphone_address_as_string(from)); } gtk_text_buffer_get_end_iter(buffer,&iter); gtk_text_buffer_get_iter_at_offset(buffer,&begin,off); - if(me){ - l=g_list_append(l,GINT_TO_POINTER(gtk_text_iter_get_offset(&iter))); - g_object_set_data(G_OBJECT(w),"list",l); - } - gtk_text_buffer_insert(buffer,&iter,"\t",-1); - gtk_text_buffer_insert(buffer,&iter,message,-1); gtk_text_buffer_get_end_iter(buffer,&iter); + gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,message,-1,me ? "left" : "left",NULL); + gtk_text_buffer_get_end_iter(buffer,&iter); gtk_text_buffer_insert(buffer,&iter,"\n",-1); - - GtkTextMark *mark=gtk_text_buffer_create_mark(buffer,NULL,&iter,FALSE); - gtk_text_view_scroll_mark_onscreen(text,mark); - //gtk_text_buffer_get_end_iter(b,&iter); - //gtk_text_iter_forward_to_line_end(&iter); - //gtk_text_view_scroll_to_iter(v,&iter,0,TRUE,1.0,1.0); - gtk_text_buffer_get_bounds (buffer, &begin, &iter); - + gtk_text_buffer_get_bounds (buffer, &begin, &end); GHashTable *hash=(GHashTable *)g_object_get_data(G_OBJECT(linphone_gtk_get_main_window()),"history"); if(me){ g_hash_table_insert(hash,linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr)), - (gpointer)gtk_text_buffer_get_text(buffer,&begin,&iter,FALSE)); + (gpointer)gtk_text_buffer_get_text(buffer,&begin,&end,FALSE)); } else { - g_hash_table_insert(hash,linphone_address_as_string_uri_only(from), - (gpointer)gtk_text_buffer_get_text(buffer,&begin,&iter,FALSE)); + (gpointer)gtk_text_buffer_get_text(buffer,&begin,&end,FALSE)); } - g_object_set_data(G_OBJECT(linphone_gtk_get_main_window()),"history",hash); + g_object_set_data(G_OBJECT(linphone_gtk_get_main_window()),"history",hash); + + if(me){ + gtk_text_buffer_get_end_iter(buffer,&iter); + list=g_list_append(list,GINT_TO_POINTER(gtk_text_iter_get_line(&iter))); + gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,"Message in progress.. ",-1, + "italic","right","small","font_grey",NULL); + gtk_text_buffer_get_end_iter(buffer,&iter); + gtk_text_buffer_insert(buffer,&iter,"\n",-1); + g_object_set_data(G_OBJECT(w),"list",list); + } + + GtkTextMark *mark=gtk_text_buffer_create_mark(buffer,NULL,&iter,FALSE); + gtk_text_view_scroll_mark_onscreen(text,mark); } const LinphoneAddress* linphone_gtk_get_used_identity(){ @@ -117,67 +154,79 @@ const LinphoneAddress* linphone_gtk_get_used_identity(){ /* function in dev for displaying ack*/ void update_chat_state_message(LinphoneChatMessageState state){ - /*GdkPixbuf *pixbuf; - - switch (state) { - case LinphoneChatMessageStateInProgress: - pixbuf=create_pixbuf("chat_message_in_progress.png"); - break; - case LinphoneChatMessageStateDelivered: - pixbuf=create_pixbuf("chat_message_delivered.png"); - break; - case LinphoneChatMessageStateNotDelivered: - pixbuf=create_pixbuf("chat_message_not_delivered.png"); - break; - default : pixbuf=NULL; - } - GtkWidget *main_window=linphone_gtk_get_main_window(); GtkWidget *friendlist=linphone_gtk_get_widget(main_window,"contact_list"); GtkWidget *page=(GtkWidget*)g_object_get_data(G_OBJECT(friendlist),"chatview"); + GList *list=g_object_get_data(G_OBJECT(page),"list"); + if(page!=NULL){ GtkTextView *text=GTK_TEXT_VIEW(linphone_gtk_get_widget(page,"textview")); GtkTextBuffer *b=gtk_text_view_get_buffer(text); GtkTextIter iter; - GList *l = g_object_get_data(G_OBJECT(page),"list"); - gtk_text_buffer_get_end_iter(b,&iter); - gtk_text_buffer_get_iter_at_offset(b,&iter,GPOINTER_TO_INT(g_list_nth_data(l,0))); - fprintf(stdout,"offset check %i \n",GPOINTER_TO_INT(g_list_nth_data(l,0))); - l=g_list_remove(l,g_list_nth_data(l,0)); - gtk_text_buffer_insert_pixbuf(b,&iter,pixbuf); + GtkTextIter end; + GtkTextIter start; - //gtk_text_buffer_get_end_iter(b,&iter); - //gtk_text_buffer_insert_pixbuf(b,&iter,pixbuf); - //gtk_text_buffer_get_end_iter(b,&iter); - //gtk_text_buffer_insert(b,&iter,"\n",-1); - g_object_set_data(G_OBJECT(page),"list",l); - } else { - fprintf(stdout,"NULLLL\n"); - }*/ + gtk_text_buffer_get_iter_at_line(b,&iter, + GPOINTER_TO_INT(g_list_nth_data(list,0))); + if(gtk_text_iter_get_chars_in_line(&iter) >0) { + gtk_text_buffer_get_iter_at_line_offset(b,&start, + GPOINTER_TO_INT(g_list_nth_data(list,0)), + gtk_text_iter_get_chars_in_line(&iter)-1); + }else { + gtk_text_buffer_get_iter_at_line_offset(b,&start, + GPOINTER_TO_INT(g_list_nth_data(list,0)),0); + } + gtk_text_buffer_get_iter_at_line_offset(b,&end, + GPOINTER_TO_INT(g_list_nth_data(list,0)),0); + gtk_text_buffer_delete(b,&start,&end); + gtk_text_buffer_get_iter_at_line(b,&iter,GPOINTER_TO_INT(g_list_nth_data(list,0))); + gchar *result; + switch (state) { + case LinphoneChatMessageStateInProgress: + result="Message in progress.. "; + break; + case LinphoneChatMessageStateDelivered: + result="Message delivered "; + break; + case LinphoneChatMessageStateNotDelivered: + result="Message not delivered "; + break; + default : result="Message in progress.. "; + } + + GDateTime *dt=g_date_time_new_now_local(); + char *time=g_date_time_format(dt,"%k:%M"); + gchar result2[80]; + sprintf(result2,"%s %s",result,time); + + gtk_text_buffer_insert_with_tags_by_name(b,&iter,result2,-1, + "italic","right","small","font_grey",NULL); + list=g_list_remove(list,g_list_nth_data(list,0)); + g_object_set_data(G_OBJECT(page),"list",list); + } } static void on_chat_state_changed(LinphoneChatMessage *msg, LinphoneChatMessageState state, void *user_pointer){ g_message("chat message state is %s",linphone_chat_message_state_to_string(state)); - update_chat_state_message(state); + update_chat_state_message(state); } -void linphone_gtk_send_text(LinphoneChatRoom *cr){ +void linphone_gtk_send_text(){ GtkWidget *main_window=linphone_gtk_get_main_window(); GtkWidget *friendlist=linphone_gtk_get_widget(main_window,"contact_list"); GtkWidget *w=(GtkWidget*)g_object_get_data(G_OBJECT(friendlist),"chatview"); GtkWidget *entry=linphone_gtk_get_widget(w,"text_entry"); const gchar *entered; - + LinphoneChatRoom *cr=g_object_get_data(G_OBJECT(w),"cr"); entered=gtk_entry_get_text(GTK_ENTRY(entry)); if (strlen(entered)>0) { LinphoneChatMessage *msg; linphone_gtk_push_text(w, linphone_gtk_get_used_identity(), - entered,TRUE,g_object_get_data(G_OBJECT(w),"cr")); - msg=linphone_chat_room_create_message(cr,entered); + entered,TRUE,cr); + msg=linphone_chat_room_create_message(cr,entered); linphone_chat_room_send_message2(cr,msg,on_chat_state_changed,NULL); gtk_entry_set_text(GTK_ENTRY(entry),""); - } } @@ -187,21 +236,27 @@ GtkWidget* linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddres GHashTable *hash=g_object_get_data(G_OBJECT(main_window),"history"); GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(main_window,"viewswitch"); GtkWidget *text=linphone_gtk_get_widget(chat_view,"textview"); + GdkColor color; int idx; - + + color.red = 32512; + color.green = 32512; + color.blue = 32512; + gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW(text),GTK_WRAP_WORD); gtk_text_view_set_editable (GTK_TEXT_VIEW(text),FALSE); gtk_notebook_append_page (notebook,chat_view,create_tab_chat_header(cr,with)); idx = gtk_notebook_page_num(notebook, chat_view); gtk_notebook_set_current_page(notebook, idx); gtk_widget_show(chat_view); - - GList *l = NULL; + g_object_set_data(G_OBJECT(chat_view),"cr",cr); g_object_set_data(G_OBJECT(chat_view),"idx",GINT_TO_POINTER(idx)); g_object_set_data(G_OBJECT(chat_view),"from_message",NULL); - g_object_set_data(G_OBJECT(chat_view),"from_chatroom",linphone_address_as_string_uri_only(with)); - g_object_set_data(G_OBJECT(chat_view),"list",l); + g_object_set_data(G_OBJECT(chat_view),"from_chatroom",(gpointer) with); + + GList *list=NULL; + g_object_set_data(G_OBJECT(chat_view),"list",list); gchar *buf=g_hash_table_lookup(hash,linphone_address_as_string_uri_only(with)); if(buf != NULL){ @@ -211,22 +266,28 @@ GtkWidget* linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddres GtkTextBuffer *text_buffer; text_buffer=gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)); gtk_text_buffer_get_bounds(text_buffer, &start, &end); - g_object_set_data(G_OBJECT(chat_view),"cr",cr); gtk_text_buffer_delete (text_buffer, &start, &end); gtk_text_buffer_insert(text_buffer,&start,buf,-1); } gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), - "right","justification", GTK_JUSTIFY_RIGHT,NULL); - + "right","justification", GTK_JUSTIFY_RIGHT,NULL); gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), - "bold","weight", PANGO_WEIGHT_BOLD,NULL); + "left","justification", GTK_JUSTIFY_LEFT,NULL); + gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), + "bold","weight", PANGO_WEIGHT_BOLD,NULL); + gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), + "italic","style", PANGO_STYLE_ITALIC,NULL); + gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), + "small","size",9*PANGO_SCALE,NULL); + gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), + "font_grey","foreground-gdk",&color,NULL); GtkWidget *button = linphone_gtk_get_widget(chat_view,"send"); - g_signal_connect_swapped(G_OBJECT(button),"clicked",(GCallback)linphone_gtk_send_text,cr); + g_signal_connect_swapped(G_OBJECT(button),"clicked",(GCallback)linphone_gtk_send_text,NULL); GtkWidget *entry = linphone_gtk_get_widget(chat_view,"text_entry"); - g_signal_connect_swapped(G_OBJECT(entry),"activate",(GCallback)linphone_gtk_send_text,cr); + g_signal_connect_swapped(G_OBJECT(entry),"activate",(GCallback)linphone_gtk_send_text,NULL); return chat_view; } @@ -237,13 +298,11 @@ LinphoneChatRoom * linphone_gtk_create_chatroom(const LinphoneAddress *with){ return cr; } - - void linphone_gtk_load_chatroom(LinphoneChatRoom *cr,const LinphoneAddress *uri,GtkWidget *chat_view){ GtkWidget *main_window=linphone_gtk_get_main_window (); GHashTable *hash=g_object_get_data(G_OBJECT(main_window),"history"); - if(g_strcmp0((char *)g_object_get_data(G_OBJECT(chat_view),"from_chatroom"), - linphone_address_as_string_uri_only(uri))!=0) + LinphoneAddress *from=(LinphoneAddress *)g_object_get_data(G_OBJECT(chat_view),"from_chatroom"); + if(g_strcmp0(linphone_address_as_string(from),linphone_address_as_string(uri))!=0) { GtkTextView *text_view=GTK_TEXT_VIEW(linphone_gtk_get_widget(chat_view,"textview")); GtkTextIter start; @@ -255,17 +314,16 @@ void linphone_gtk_load_chatroom(LinphoneChatRoom *cr,const LinphoneAddress *uri, g_object_set_data(G_OBJECT(chat_view),"cr",cr); gtk_text_buffer_delete (text_buffer, &start, &end); if(buf!=NULL){ - gtk_text_buffer_insert(text_buffer,&start,buf,-1); - } else { - g_object_set_data(G_OBJECT(chat_view),"from_message",NULL); - GtkWidget *entry = linphone_gtk_get_widget(chat_view,"text_entry"); - g_signal_connect_swapped(G_OBJECT(entry),"activate",(GCallback)linphone_gtk_send_text,cr); + gtk_text_buffer_insert_with_tags_by_name(text_buffer,&start,buf,-1,"font_grey",NULL); + GtkTextMark *mark=gtk_text_buffer_create_mark(text_buffer, NULL, &start, FALSE); + gtk_text_view_scroll_to_mark(text_view,mark, 0, FALSE, 0, 0); + } - GtkWidget *button = linphone_gtk_get_widget(chat_view,"send"); - g_signal_connect_swapped(G_OBJECT(button),"clicked",(GCallback)linphone_gtk_send_text,cr); - } - - g_object_set_data(G_OBJECT(chat_view),"from_chatroom",linphone_address_as_string_uri_only(uri)); + udpate_tab_chat_header(chat_view,uri,cr); + g_object_set_data(G_OBJECT(chat_view),"cr",cr); + g_object_set_data(G_OBJECT(chat_view),"from_chatroom",(gpointer) uri); + g_object_set_data(G_OBJECT(chat_view),"from_message",linphone_address_as_string_uri_only(uri)); + g_object_set_data(G_OBJECT(linphone_gtk_get_widget(main_window,"contact_list")),"chatview",(gpointer)chat_view); } } @@ -284,6 +342,8 @@ void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room, const GtkWidget *main_window=linphone_gtk_get_main_window(); GtkWidget *friendlist=linphone_gtk_get_widget(main_window,"contact_list"); GtkWidget *w; + GDateTime *dt=g_date_time_new_now_local(); + char *time=g_date_time_format(dt,"%k:%M"); w=(GtkWidget*)g_object_get_data(G_OBJECT(friendlist),"chatview"); if(w!=NULL){ @@ -291,16 +351,23 @@ void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room, const } else { w=linphone_gtk_init_chatroom(room,from); g_object_set_data(G_OBJECT(friendlist),"chatview",(gpointer)w); + g_object_set_data(G_OBJECT(friendlist),"from",(gpointer)from); } - - #ifdef HAVE_GTK_OSX + const char *display=linphone_address_get_display_name(from); + if (display==NULL || display[0]=='\0') { + display=linphone_address_get_username(from); + } + + #ifdef HAVE_GTK_OSXs /* Notified when a new message is sent */ linphone_gtk_status_icon_set_blinking(TRUE); #else if(!gtk_window_is_active(GTK_WINDOW(main_window))){ if(!GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"is_notified"))){ - linphone_gtk_notify(NULL,message); + gchar result2[80]; + sprintf(result2,"%s \n %s sent at %s",message,display,time); + linphone_gtk_notify(NULL,result2); g_object_set_data(G_OBJECT(w),"is_notified",GINT_TO_POINTER(TRUE)); } else { g_object_set_data(G_OBJECT(w),"is_notified",GINT_TO_POINTER(FALSE)); @@ -308,8 +375,7 @@ void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room, const } #endif linphone_gtk_push_text(w,from,message,FALSE,room); - //linphone_gtk_update_chat_picture(TRUE); + linphone_gtk_update_chat_picture(); //gtk_window_present(GTK_WINDOW(w)); /*gtk_window_set_urgency_hint(GTK_WINDOW(w),TRUE);*/ } - diff --git a/gtk/friendlist.c b/gtk/friendlist.c index 3124fdbb1..5ce869b46 100644 --- a/gtk/friendlist.c +++ b/gtk/friendlist.c @@ -171,7 +171,7 @@ static void linphone_gtk_call_selected(GtkTreeView *treeview){ "start_call")); } -void linphone_gtk_update_chat_picture(gboolean active){ +void linphone_gtk_create_chat_picture(gboolean active){ GtkTreeIter iter; GtkWidget *w = linphone_gtk_get_main_window(); GtkWidget *friendlist=linphone_gtk_get_widget(w,"contact_list"); @@ -187,6 +187,33 @@ void linphone_gtk_update_chat_picture(gboolean active){ } } +void linphone_gtk_update_chat_picture(){ + GtkTreeIter iter; + GtkListStore *store=NULL; + GtkWidget *w = linphone_gtk_get_main_window(); + GtkWidget *friendlist=linphone_gtk_get_widget(w,"contact_list"); + GtkTreeModel *model=gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist)); + GtkWidget *chat_view=(GtkWidget*)g_object_get_data(G_OBJECT(friendlist),"chatview"); + LinphoneFriend *lf=NULL; + LinphoneAddress *uri=(LinphoneAddress *)g_object_get_data(G_OBJECT(friendlist),"from"); + store=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist))); + if (gtk_tree_model_get_iter_first(model,&iter)) { + do{ + gtk_tree_model_get (model, &iter,FRIEND_ID , &lf, -1); + if(chat_view!=NULL){ + if(uri !=NULL) { + if(g_strcmp0(linphone_address_as_string(linphone_friend_get_address(lf)), + linphone_address_as_string(uri))==0){ + gtk_list_store_set(store,&iter,FRIEND_CHAT,create_active_chat_picture(),-1); + } else { + gtk_list_store_set(store,&iter,FRIEND_CHAT,create_chat_picture(),-1); + } + } + } + }while(gtk_tree_model_iter_next(model,&iter)); + } +} + static gboolean grab_focus(GtkWidget *w){ gtk_widget_grab_focus(w); return FALSE; @@ -207,16 +234,14 @@ void linphone_gtk_chat_selected(GtkWidget *item){ store=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(item))); if (gtk_tree_selection_get_selected (select, &model, &iter)){ GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(w,"viewswitch"); - gtk_tree_model_get(model,&iter,FRIEND_CHATROOM,&cr,-1); const LinphoneAddress *uri; gtk_tree_model_get (model, &iter,FRIEND_ID , &lf, -1); uri=linphone_friend_get_address(lf); if(cr == NULL){ cr=linphone_gtk_create_chatroom(uri); - gtk_list_store_set(store,&iter, FRIEND_CHATROOM,cr,-1); - gtk_list_store_set(store,&iter, FRIEND_CHAT_CONVERSATION,NULL,-1); } page=(GtkWidget*)g_object_get_data(G_OBJECT(friendlist),"chatview"); + g_object_set_data(G_OBJECT(friendlist),"from",(gpointer)uri); if(page==NULL){ page=linphone_gtk_init_chatroom(cr,uri); g_object_set_data(G_OBJECT(friendlist),"chatview",(gpointer)page); @@ -224,7 +249,7 @@ void linphone_gtk_chat_selected(GtkWidget *item){ linphone_gtk_load_chatroom(cr,uri,page); } gtk_notebook_set_current_page(notebook,gtk_notebook_page_num(notebook,page)); - linphone_gtk_update_chat_picture(FALSE); + linphone_gtk_create_chat_picture(FALSE); g_idle_add((GSourceFunc)grab_focus,linphone_gtk_get_widget(page,"text_entry")); gtk_list_store_set(store,&iter,FRIEND_CHAT,create_active_chat_picture(),-1); } @@ -672,6 +697,7 @@ void linphone_gtk_show_friends(void){ escaped=g_markup_escape_text(uri,-1); gtk_list_store_set(store,&iter,FRIEND_SIP_ADDRESS,escaped,-1); g_free(escaped); + linphone_gtk_update_chat_picture(); //bi=linphone_friend_get_info(lf); /*if (bi!=NULL && bi->image_data!=NULL){ GdkPixbuf *pbuf= @@ -893,7 +919,7 @@ static gint tree_view_get_cell_from_pos(GtkTreeView *view, guint x, guint y){ for (node = columns; node != NULL && col == NULL; node = node->next){ GtkTreeViewColumn *checkcol = (GtkTreeViewColumn*) node->data; gtk_tree_view_column_cell_get_size(checkcol,NULL,NULL,NULL,NULL,&height); - if (x >= colx && x < (colx + checkcol->width) && y < height*coly){ + if (x >= colx && x < (colx + checkcol->width) && y < (height+2)*coly){ col = checkcol; gint num = get_col_number_from_tree_view_column(col); return num; diff --git a/gtk/linphone.h b/gtk/linphone.h index c9accb6f6..367b18c26 100644 --- a/gtk/linphone.h +++ b/gtk/linphone.h @@ -53,10 +53,13 @@ GtkWidget*create_pixmap(const gchar *filename); GtkWidget *_gtk_image_new_from_memory_at_scale(const void *data, gint len, gint w, gint h, gboolean preserve_ratio); GdkPixbuf *_gdk_pixbuf_new_from_memory_at_scale(const void *data, gint len, gint w, gint h, gboolean preserve_ratio); +void linphone_gtk_destroy_window(GtkWidget *window); GtkWidget *linphone_gtk_create_window(const char *window_name); GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char *name); GtkWidget *linphone_gtk_create_widget(const char *filename, const char *widget_name); -GtkWidget * linphone_gtk_create_assistant(void); + +void linphone_gtk_show_assistant(void); +void linphone_gtk_close_assistant(void); LinphoneCore *linphone_gtk_get_core(void); GtkWidget *linphone_gtk_get_main_window(); @@ -104,9 +107,10 @@ void linphone_gtk_status_icon_set_blinking(gboolean val); void linphone_gtk_notify(LinphoneCall *call, const char *msg); LinphoneChatRoom *linphone_gtk_start_chat(GtkTreeView* t); void linphone_gtk_load_chatroom(LinphoneChatRoom *cr,const LinphoneAddress *uri,GtkWidget *chat_view); -void linphone_gtk_send_text(LinphoneChatRoom *cr); +void linphone_gtk_send_text(); GtkWidget * linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddress *with); -void linphone_gtk_update_chat_picture(gboolean active); +void linphone_gtk_create_chat_picture(gboolean active); +void linphone_gtk_update_chat_picture(); void linphone_gtk_chat_set_conversation(const LinphoneAddress *uri,gchar *conversation); gchar * linphone_gtk_chat_get_conversation(const LinphoneAddress *uri); diff --git a/gtk/main.c b/gtk/main.c index 5d9158713..12e84bc97 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -50,7 +50,6 @@ const char *this_program_ident_string="linphone_ident_string=" LINPHONE_VERSION; static LinphoneCore *the_core=NULL; static GtkWidget *the_ui=NULL; -GtkWidget *the_wizard=NULL; static void linphone_gtk_registration_state_changed(LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState rs, const char *msg); static void linphone_gtk_notify_recv(LinphoneCore *lc, LinphoneFriend * fid); @@ -238,6 +237,7 @@ static void linphone_gtk_init_liblinphone(const char *config_file, vtable.transfer_state_changed=linphone_gtk_transfer_state_changed; the_core=linphone_core_new(&vtable,config_file,factory_config_file,NULL); + //lp_config_set_int(linphone_core_get_config(the_core), "sip", "store_auth_info", 0); linphone_core_set_user_agent(the_core,"Linphone", LINPHONE_VERSION); linphone_core_set_waiting_callback(the_core,linphone_gtk_wait,NULL); linphone_core_set_zrtp_secrets_file(the_core,secrets_file); @@ -257,6 +257,11 @@ GtkWidget *linphone_gtk_get_main_window(){ return the_ui; } +void linphone_gtk_destroy_main_window() { + linphone_gtk_destroy_window(the_ui); + the_ui = NULL; +} + static void linphone_gtk_configure_window(GtkWidget *w, const char *window_name){ static const char *icon_path=NULL; static const char *hiddens=NULL; @@ -295,6 +300,12 @@ static int get_ui_file(const char *name, char *path, int pathsize){ return 0; } +void linphone_gtk_destroy_window(GtkWidget *widget) { + GtkBuilder* builder = g_object_get_data(G_OBJECT(widget), "builder"); + gtk_widget_destroy(widget); + g_object_unref (G_OBJECT (builder)); +} + GtkWidget *linphone_gtk_create_window(const char *window_name){ GError* error = NULL; GtkBuilder* builder = gtk_builder_new (); @@ -313,7 +324,7 @@ GtkWidget *linphone_gtk_create_window(const char *window_name){ g_error("Could not retrieve '%s' window from xml file",window_name); return NULL; } - g_object_set_data(G_OBJECT(w),"builder",builder); + g_object_set_data(G_OBJECT(w), "builder",builder); gtk_builder_connect_signals(builder,w); linphone_gtk_configure_window(w,window_name); return w; @@ -1731,21 +1742,15 @@ static void linphone_gtk_check_soundcards(){ } } -#ifdef BUILD_WIZARD -// Display the account wizard -void linphone_gtk_display_wizard() { - if (the_wizard == NULL || !gtk_widget_get_visible(the_wizard)) { // Only one instance of the wizard at the same time - the_wizard = linphone_gtk_create_assistant(); - } -} -#endif - static void linphone_gtk_quit(void){ static gboolean quit_done=FALSE; if (!quit_done){ quit_done=TRUE; linphone_gtk_unmonitor_usb(); g_source_remove_by_user_data(linphone_gtk_get_core()); +#ifdef BUILD_WIZARD + linphone_gtk_close_assistant(); +#endif linphone_gtk_uninit_instance(); linphone_gtk_destroy_log_window(); linphone_core_destroy(the_core); @@ -1897,7 +1902,7 @@ int main(int argc, char *argv[]){ #ifdef BUILD_WIZARD // Veryfing if at least one sip account is configured. If not, show wizard if (linphone_core_get_proxy_config_list(linphone_gtk_get_core()) == NULL) { - linphone_gtk_display_wizard(); + linphone_gtk_show_assistant(); } #endif diff --git a/gtk/main.ui b/gtk/main.ui index a68ea4cb8..f82875cb6 100644 --- a/gtk/main.ui +++ b/gtk/main.ui @@ -113,6 +113,7 @@ True True + 4 @@ -834,7 +835,7 @@ False image12 False - + diff --git a/gtk/parameters.ui b/gtk/parameters.ui index 293af4270..e4a6430fa 100644 --- a/gtk/parameters.ui +++ b/gtk/parameters.ui @@ -216,10 +216,10 @@ Set Maximum Transmission Unit: - False True True False + False True @@ -256,10 +256,10 @@ Send DTMFs as SIP info - False True True False + False True @@ -272,11 +272,11 @@ Use IPv6 instead of IPv4 - False True True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False True @@ -324,7 +324,7 @@ True False GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 6 + 7 2 @@ -364,7 +364,7 @@ 3 - 4 + 5 @@ -380,30 +380,20 @@ 4 - - - False - Tunnel - - - 5 - 6 - - gtk-edit - False True True + False True 1 2 - 5 - 6 + 6 + 7 @@ -439,25 +429,25 @@ DSCP fields - 4 - 5 + 5 + 6 gtk-edit - False True True True + False True 1 2 - 4 - 5 + 5 + 6 @@ -506,10 +496,10 @@ Fixed - False True True False + False True @@ -573,10 +563,10 @@ Fixed - False True True False + False True @@ -594,6 +584,33 @@ 3 + + + False + Tunnel + + + 6 + 7 + + + + + Media encryption is mandatory + True + True + False + False + True + + + + 1 + 2 + 4 + 5 + + @@ -628,10 +645,10 @@ Direct connection to the Internet - False True True False + False True True @@ -649,10 +666,10 @@ Behind NAT / Firewall (specify gateway IP below) - False True True False + False True True no_nat @@ -717,10 +734,10 @@ Behind NAT / Firewall (use STUN to resolve) - False True True False + False True no_nat @@ -734,10 +751,10 @@ Behind NAT / Firewall (use ICE) - False True True False + False True no_nat @@ -892,9 +909,6 @@ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 6 2 - - - True @@ -916,11 +930,11 @@ gtk-media-play - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False True @@ -1093,10 +1107,10 @@ Enable echo cancellation - False True True False + False True @@ -1107,6 +1121,9 @@ 6 + + + @@ -1442,11 +1459,11 @@ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False True True True - + False + True @@ -1489,11 +1506,11 @@ - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False @@ -1537,11 +1554,11 @@ - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False @@ -1585,11 +1602,11 @@ - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False @@ -1678,11 +1695,11 @@ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False @@ -1864,11 +1881,11 @@ gtk-go-up - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False True @@ -1881,11 +1898,11 @@ gtk-go-down - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False True @@ -1897,11 +1914,11 @@ - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False @@ -1945,11 +1962,11 @@ - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False @@ -2112,10 +2129,10 @@ Enable adaptive rate control - False True True False + False 0 True @@ -2141,7 +2158,7 @@ 2 3 GTK_FILL - + @@ -2267,10 +2284,10 @@ Show advanced settings - False True True False + False True @@ -2347,11 +2364,11 @@ end - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False diff --git a/gtk/propertybox.c b/gtk/propertybox.c index 1e86c17d2..c2258ea57 100644 --- a/gtk/propertybox.c +++ b/gtk/propertybox.c @@ -885,19 +885,35 @@ void linphone_gtk_ui_level_toggled(GtkWidget *w) { linphone_gtk_ui_level_adapt(top); } +static void linphone_gtk_set_media_encryption_mandatory_sensitive(GtkWidget *propbox, gboolean val){ + GtkWidget *w=linphone_gtk_get_widget(propbox,"media_encryption_mandatory"); + gtk_widget_set_sensitive(w,val); +} + static void linphone_gtk_media_encryption_changed(GtkWidget *combo){ char *selected=gtk_combo_box_get_active_text(GTK_COMBO_BOX(combo)); LinphoneCore *lc=linphone_gtk_get_core(); + GtkWidget *toplevel=gtk_widget_get_toplevel(combo); if (selected!=NULL){ - if (strcasecmp(selected,"SRTP")==0) + if (strcasecmp(selected,"SRTP")==0){ linphone_core_set_media_encryption(lc,LinphoneMediaEncryptionSRTP); - else if (strcasecmp(selected,"ZRTP")==0) + linphone_gtk_set_media_encryption_mandatory_sensitive(toplevel,TRUE); + }else if (strcasecmp(selected,"ZRTP")==0){ linphone_core_set_media_encryption(lc,LinphoneMediaEncryptionZRTP); - else linphone_core_set_media_encryption(lc,LinphoneMediaEncryptionNone); + linphone_gtk_set_media_encryption_mandatory_sensitive(toplevel,FALSE); + } + else { + linphone_core_set_media_encryption(lc,LinphoneMediaEncryptionNone); + linphone_gtk_set_media_encryption_mandatory_sensitive(toplevel,FALSE); + } g_free(selected); }else g_warning("gtk_combo_box_get_active_text() returned NULL"); } +void linphone_gtk_set_media_encryption_mandatory(GtkWidget *button){ + linphone_core_set_media_encryption_mandatory(linphone_gtk_get_core(),gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))); +} + static void linphone_gtk_show_media_encryption(GtkWidget *pb){ LinphoneCore *lc=linphone_gtk_get_core(); GtkWidget *combo=linphone_gtk_get_widget(pb,"media_encryption_combo"); @@ -933,21 +949,30 @@ static void linphone_gtk_show_media_encryption(GtkWidget *pb){ /*hide this setting*/ gtk_widget_hide(combo); gtk_widget_hide(linphone_gtk_get_widget(pb,"media_encryption_label")); + gtk_widget_hide(linphone_gtk_get_widget(pb,"media_encryption_mandatory")); }else{ LinphoneMediaEncryption menc=linphone_core_get_media_encryption(lc); switch(menc){ case LinphoneMediaEncryptionNone: gtk_combo_box_set_active(GTK_COMBO_BOX(combo),0); + linphone_gtk_set_media_encryption_mandatory_sensitive(pb,FALSE); break; case LinphoneMediaEncryptionSRTP: - if (srtp_id!=-1) gtk_combo_box_set_active(GTK_COMBO_BOX(combo),srtp_id); + if (srtp_id!=-1) { + gtk_combo_box_set_active(GTK_COMBO_BOX(combo),srtp_id); + linphone_gtk_set_media_encryption_mandatory_sensitive(pb,TRUE); + } break; case LinphoneMediaEncryptionZRTP: - if (zrtp_id!=-1) gtk_combo_box_set_active(GTK_COMBO_BOX(combo),zrtp_id); + if (zrtp_id!=-1) { + gtk_combo_box_set_active(GTK_COMBO_BOX(combo),zrtp_id); + linphone_gtk_set_media_encryption_mandatory_sensitive(pb,FALSE); + } break; } g_signal_connect(G_OBJECT(combo),"changed",(GCallback)linphone_gtk_media_encryption_changed,NULL); } + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(pb,"media_encryption_mandatory")),linphone_core_is_media_encryption_mandatory(lc)); g_object_unref(G_OBJECT(model)); } @@ -1160,44 +1185,22 @@ void linphone_gtk_edit_tunnel_closed(GtkWidget *button){ gtk_widget_destroy(pb); } - -static void tunnel_get_server_host_and_port(LinphoneTunnel *tunnel, char *host, int size, int *port){ - char *colon; - char *addresses; - char *str1; - char *address; - const char* configured_addresses; - - configured_addresses=linphone_tunnel_get_servers(tunnel); - - if (configured_addresses==NULL){ - host[0]=0; - *port=0; - return; - } - addresses=ms_strdup(configured_addresses); - str1=addresses; - address=strtok(str1," "); // Not thread safe - if (!address) return; - colon=strchr(address, ':'); - if (!colon) return; - *colon++='\0'; - *port=atoi(colon); - strncpy(host,address,size); - ms_free(addresses); -} - - void linphone_gtk_edit_tunnel(GtkButton *button){ GtkWidget *w=linphone_gtk_create_window("tunnel_config"); LinphoneCore *lc=linphone_gtk_get_core(); LinphoneTunnel *tunnel=linphone_core_get_tunnel(lc); - char host[128]={'\0'}; + const MSList *configs; + const char *host = NULL; int port=0; if (!tunnel) return; - tunnel_get_server_host_and_port(tunnel, host, sizeof(host), &port); + configs = linphone_tunnel_get_servers(tunnel); + if(configs != NULL) { + LinphoneTunnelConfig *ltc = (LinphoneTunnelConfig *)configs->data; + host = linphone_tunnel_config_get_host(ltc); + port = linphone_tunnel_config_get_port(ltc); + } gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"host")),host); if (port==0) port=443; @@ -1230,6 +1233,7 @@ void linphone_gtk_tunnel_ok(GtkButton *button){ GtkWidget *w=gtk_widget_get_toplevel(GTK_WIDGET(button)); LinphoneCore *lc=linphone_gtk_get_core(); LinphoneTunnel *tunnel=linphone_core_get_tunnel(lc); + LinphoneTunnelConfig *config=linphone_tunnel_config_new(); gint port = (gint)gtk_spin_button_get_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(w,"port"))); gboolean enabled=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"radio_enable"))); @@ -1243,7 +1247,9 @@ void linphone_gtk_tunnel_ok(GtkButton *button){ if (host && *host=='\0') host=NULL; if (http_port==0) http_port=8080; linphone_tunnel_clean_servers(tunnel); - linphone_tunnel_add_server(tunnel,host,port); + linphone_tunnel_config_set_host(config, host); + linphone_tunnel_config_set_port(config, port); + linphone_tunnel_add_server(tunnel, config); linphone_tunnel_enable(tunnel,enabled); linphone_tunnel_set_http_proxy(tunnel,http_host,http_port,username,password); diff --git a/gtk/setupwizard.c b/gtk/setupwizard.c index 39673da99..f4374c539 100644 --- a/gtk/setupwizard.c +++ b/gtk/setupwizard.c @@ -25,6 +25,7 @@ static LinphoneAccountCreator *linphone_gtk_assistant_get_creator(GtkWidget*w); static const int PASSWORD_MIN_SIZE = 6; static const int LOGIN_MIN_SIZE = 4; +static GtkWidget *the_assistant=NULL; static GdkPixbuf *ok; static GdkPixbuf *notok; @@ -400,7 +401,7 @@ static int is_account_validated(GtkWidget *page) { } static void linphone_gtk_assistant_closed(GtkWidget *w){ - gtk_widget_destroy(w); + linphone_gtk_close_assistant(); } static void linphone_gtk_assistant_prepare(GtkWidget *assistant, GtkWidget *page){ @@ -531,8 +532,17 @@ static LinphoneAccountCreator *linphone_gtk_assistant_get_creator(GtkWidget*w){ return (LinphoneAccountCreator*)g_object_get_data(G_OBJECT(w),"creator"); } -GtkWidget * linphone_gtk_create_assistant(void){ - GtkWidget *w=gtk_assistant_new(); +void linphone_gtk_close_assistant(void){ + if(the_assistant==NULL) + return; + gtk_widget_destroy(the_assistant); + the_assistant = NULL; +} + +void linphone_gtk_show_assistant(void){ + if(the_assistant!=NULL) + return; + GtkWidget *w=the_assistant=gtk_assistant_new(); gtk_window_set_resizable (GTK_WINDOW(w), FALSE); ok = create_pixbuf(linphone_gtk_get_ui_config("ok","ok.png")); @@ -597,7 +607,5 @@ GtkWidget * linphone_gtk_create_assistant(void){ g_signal_connect(G_OBJECT(w),"prepare",(GCallback)linphone_gtk_assistant_prepare,NULL); gtk_widget_show(w); - - return w; } diff --git a/java/common/org/linphone/core/LinphoneCore.java b/java/common/org/linphone/core/LinphoneCore.java index d612589fe..08371f515 100644 --- a/java/common/org/linphone/core/LinphoneCore.java +++ b/java/common/org/linphone/core/LinphoneCore.java @@ -876,4 +876,10 @@ public interface LinphoneCore { * Enable/Disable the use of inband DTMFs */ void setUseRfc2833ForDtmfs(boolean use); + + /** + * @return returns LpConfig object to read/write to the config file: usefull if you wish to extend + * the config file with your own sections + */ + LpConfig getConfig(); } diff --git a/java/common/org/linphone/core/LpConfig.java b/java/common/org/linphone/core/LpConfig.java new file mode 100644 index 000000000..f31e4d525 --- /dev/null +++ b/java/common/org/linphone/core/LpConfig.java @@ -0,0 +1,48 @@ +/* +LPConfig.java +Copyright (C) 2013 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. +*/ +package org.linphone.core; + + +/** + * The LpConfig object is used to manipulate a configuration file. + * + *
+ * The format of the configuration file is a .ini like format:
+ * - sections are defined in []
+ * - each section contains a sequence of key=value pairs.
+ * 
+ * Example:
+ * [sound]
+ * echocanceler=1
+ * playback_dev=ALSA: Default device
+ *
+ * [video]
+ * enabled=1
+ * 
+ * } + * @author Guillaume Beraudo + */ +public interface LpConfig { + + /** + * Sets an integer config item + * @param key + */ + void setInt(String section, String key, int value); +} diff --git a/java/impl/org/linphone/core/LinphoneCoreImpl.java b/java/impl/org/linphone/core/LinphoneCoreImpl.java index d4f7808c6..02e31f9a1 100644 --- a/java/impl/org/linphone/core/LinphoneCoreImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreImpl.java @@ -866,4 +866,10 @@ class LinphoneCoreImpl implements LinphoneCore { public void setUseRfc2833ForDtmfs(boolean use) { setUseRfc2833ForDtmfs(nativePtr, use); } + + private native long getConfig(long ptr); + public LpConfig getConfig() { + long configPtr=getConfig(nativePtr); + return new LpConfigImpl(configPtr); + } } diff --git a/java/impl/org/linphone/core/LpConfigImpl.java b/java/impl/org/linphone/core/LpConfigImpl.java new file mode 100644 index 000000000..1cb705ec2 --- /dev/null +++ b/java/impl/org/linphone/core/LpConfigImpl.java @@ -0,0 +1,36 @@ +/* +LPConfigImpl.java +Copyright (C) 2013 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. +*/ +package org.linphone.core; + + + +class LpConfigImpl implements LpConfig { + + private final long nativePtr; + + public LpConfigImpl(long ptr) { + nativePtr=ptr; + } + + private native void setInt(long ptr, String section, String key, int value); + public void setInt(String section, String key, int value) { + setInt(nativePtr, section, key, value); + } + +} diff --git a/m4/exosip.m4 b/m4/exosip.m4 index aa4b7a9c3..31769e00d 100644 --- a/m4/exosip.m4 +++ b/m4/exosip.m4 @@ -40,6 +40,10 @@ AC_CHECK_LIB([eXosip2],[eXosip_tls_verify_certificate], [AC_DEFINE([HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE],[1],[Defined when eXosip_tls_verify_certificate is available])], [AC_MSG_WARN([Could not find eXosip_tls_verify_certificate in eXosip2 !])], [-losipparser2 -losip2 ]) +AC_CHECK_LIB([eXosip2],[eXosip_tls_verify_cn], + [AC_DEFINE([HAVE_EXOSIP_TLS_VERIFY_CN],[1],[Defined when eXosip_tls_verify_certificate is available])], + [AC_MSG_WARN([Could not find eXosip_tls_verify_cn in eXosip2 !])], + [-losipparser2 -losip2 ]) AC_CHECK_LIB([eXosip2],[eXosip_trylock], [AC_DEFINE([HAVE_EXOSIP_TRYLOCK],[1],[Defined when eXosip_get_socket is available])], [], diff --git a/mediastreamer2 b/mediastreamer2 index b8dffb274..1cf3b8e36 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit b8dffb2741223e13baa4c9d1514a1911d070b0e7 +Subproject commit 1cf3b8e36d832d763220b762c6bceef0db88c04c diff --git a/oRTP b/oRTP index 0091eeead..20abeb39e 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 0091eeead5d472797fb474f876a4cc835712c3e6 +Subproject commit 20abeb39e1edae0f72080f7998410e9b16b9da05 diff --git a/pixmaps/Makefile.am b/pixmaps/Makefile.am index a7ee4ecb9..186254c11 100644 --- a/pixmaps/Makefile.am +++ b/pixmaps/Makefile.am @@ -11,10 +11,10 @@ status-orange.png \ status-red.png \ status-offline.png \ call.png \ -chat.png \ +chat.png active_chat.png\ chat_message_inprogress.png chat_message_delivered.png chat_message_not_delivered.png\ contact-orange.png dialer-orange.png history-orange.png\ -startcall-green.png stopcall-red.png addcall-green.png linphone.icns \ +startcall-green.png startcall-small.png stopcall-red.png stopcall-small.png addcall-green.png linphone.icns \ contact_starred.png contact_unstarred.png \ speaker.png \ ok.png \ diff --git a/po/POTFILES.skip b/po/POTFILES.skip index 49808b8ef..e254f124a 100755 --- a/po/POTFILES.skip +++ b/po/POTFILES.skip @@ -1,49 +1,49 @@ - gtk/p2pwizard.ui -mediastreamer2/src/alaw.c -mediastreamer2/src/alsa.c -mediastreamer2/src/aqsnd.c -mediastreamer2/src/audiomixer.c -mediastreamer2/src/chanadapt.c -mediastreamer2/src/drawdib-display.c -mediastreamer2/src/dtmfgen.c -mediastreamer2/src/equalizer.c -mediastreamer2/src/extdisplay.c -mediastreamer2/src/gsm.c -mediastreamer2/src/ice.c -mediastreamer2/src/itc.c -mediastreamer2/src/genericplc.c -mediastreamer2/src/macsnd.c -mediastreamer2/src/msandroid.cpp -mediastreamer2/src/msandroidvideo.cpp -mediastreamer2/src/msconf.c -mediastreamer2/src/msdscap-mingw.cc -mediastreamer2/src/msfileplayer.c -mediastreamer2/src/msfilerec.c -mediastreamer2/src/msfilerec_win.c -mediastreamer2/src/msiounit.c -mediastreamer2/src/msjoin.c -mediastreamer2/src/msresample.c -mediastreamer2/src/msrtp.c -mediastreamer2/src/msspeex.c -mediastreamer2/src/msv4l.c -mediastreamer2/src/msv4l2.c -mediastreamer2/src/msvolume.c -mediastreamer2/src/nowebcam.c -mediastreamer2/src/pixconv.c -mediastreamer2/src/sizeconv.c -mediastreamer2/src/speexec.c -mediastreamer2/src/tee.c -mediastreamer2/src/theora.c -mediastreamer2/src/ulaw.c -mediastreamer2/src/videodec.c -mediastreamer2/src/videoenc.c -mediastreamer2/src/videoout.c -mediastreamer2/src/void.c -mediastreamer2/src/wincevideods.c -mediastreamer2/src/winvideo.c -mediastreamer2/src/winvideo2.c -mediastreamer2/src/winvideods.c -mediastreamer2/src/x11video.c -mediastreamer2/src/vp8.c - +mediastreamer2/src/android/androidsound_depr.cpp +mediastreamer2/src/android/androidvideo.cpp +mediastreamer2/src/audiofilters/alaw.c +mediastreamer2/src/audiofilters/alsa.c +mediastreamer2/src/audiofilters/aqsnd.c +mediastreamer2/src/audiofilters/audiomixer.c +mediastreamer2/src/audiofilters/chanadapt.c +mediastreamer2/src/audiofilters/dtmfgen.c +mediastreamer2/src/audiofilters/equalizer.c +mediastreamer2/src/audiofilters/gsm.c +mediastreamer2/src/audiofilters/genericplc.c +mediastreamer2/src/audiofilters/macsnd.c +mediastreamer2/src/audiofilters/msconf.c +mediastreamer2/src/audiofilters/msfileplayer.c +mediastreamer2/src/audiofilters/msfilerec.c +mediastreamer2/src/audiofilters/msfilerec_win.c +mediastreamer2/src/audiofilters/msiounit.m +mediastreamer2/src/audiofilters/msresample.c +mediastreamer2/src/audiofilters/msspeex.c +mediastreamer2/src/audiofilters/msvolume.c +mediastreamer2/src/audiofilters/oss.c +mediastreamer2/src/audiofilters/speexec.c +mediastreamer2/src/audiofilters/ulaw.c +mediastreamer2/src/audiofilters/webrtc_aec.c +mediastreamer2/src/otherfilters/itc.c +mediastreamer2/src/otherfilters/join.c +mediastreamer2/src/otherfilters/msrtp.c +mediastreamer2/src/otherfilters/tee.c +mediastreamer2/src/otherfilters/void.c +mediastreamer2/src/videofilters/drawdib-display.c +mediastreamer2/src/videofilters/extdisplay.c +mediastreamer2/src/videofilters/msdscap-mingw.cc +mediastreamer2/src/videofilters/msv4l.c +mediastreamer2/src/videofilters/msv4l2.c +mediastreamer2/src/videofilters/nowebcam.c +mediastreamer2/src/videofilters/pixconv.c +mediastreamer2/src/videofilters/sizeconv.c +mediastreamer2/src/videofilters/theora.c +mediastreamer2/src/videofilters/videodec.c +mediastreamer2/src/videofilters/videoenc.c +mediastreamer2/src/videofilters/videoout.c +mediastreamer2/src/videofilters/vp8.c +mediastreamer2/src/videofilters/wincevideods.c +mediastreamer2/src/videofilters/winvideo.c +mediastreamer2/src/videofilters/winvideods.c +mediastreamer2/src/videofilters/winvideo2.c +mediastreamer2/src/videofilters/x11video.c +mediastreamer2/src/voip/ice.c diff --git a/po/fr.po b/po/fr.po index 5062fc074..8c955f75c 100644 --- a/po/fr.po +++ b/po/fr.po @@ -1,12 +1,12 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) 2001 Free Software Foundation, Inc. -# Simon Morlat , 2001. -# +# SOME DESCRIPTIVE TITLE. +# Copyright (C) 2001 Free Software Foundation, Inc. +# Simon Morlat , 2001. +# msgid "" msgstr "" "Project-Id-Version: Linphone 0.9.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-01-08 10:35+0100\n" +"POT-Creation-Date: 2011-12-05 12:41+0100\n" "PO-Revision-Date: 2002-12-06 17:33+0100\n" "Last-Translator: Simon Morlat \n" "Language-Team: french \n" @@ -16,19 +16,16 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #: ../gtk/calllogs.c:82 -#, fuzzy msgid "Aborted" -msgstr "abandonné" +msgstr "Abandonné" #: ../gtk/calllogs.c:85 -#, fuzzy msgid "Missed" -msgstr "manqué" +msgstr "Manqué" #: ../gtk/calllogs.c:88 -#, fuzzy msgid "Declined" -msgstr "Refuser" +msgstr "Refusé" #: ../gtk/calllogs.c:94 #, c-format @@ -62,7 +59,8 @@ msgid "" "%s\t%s" msgstr "" -#: ../gtk/conference.c:33 ../gtk/main.ui.h:13 +#: ../gtk/conference.c:33 +#: ../gtk/main.ui.h:13 msgid "Conference" msgstr "Conférence" @@ -70,7 +68,9 @@ msgstr "Conférence" msgid "Me" msgstr "Moi" -#: ../gtk/support.c:49 ../gtk/support.c:73 ../gtk/support.c:102 +#: ../gtk/support.c:49 +#: ../gtk/support.c:73 +#: ../gtk/support.c:102 #, c-format msgid "Couldn't find pixmap file: %s" msgstr "Icone non trouvée: %s" @@ -100,12 +100,8 @@ msgid "if set automatically answer incoming calls" msgstr "si positionné, répond automatiquement aux appels entrants" #: ../gtk/main.c:131 -msgid "" -"Specifiy a working directory (should be the base of the installation, eg: c:" -"\\Program Files\\Linphone)" -msgstr "" -"Spécifie un répertoire de travail (qui devrait être le répertoire " -"d'installation, par exemple c:\\Program Files\\Linphone)" +msgid "Specifiy a working directory (should be the base of the installation, eg: c:\\Program Files\\Linphone)" +msgstr "Spécifie un répertoire de travail (qui devrait être le répertoire d'installation, par exemple c:\\Program Files\\Linphone)" #: ../gtk/main.c:498 #, c-format @@ -116,15 +112,12 @@ msgstr "Appel avec %s" #, c-format msgid "" "%s would like to add you to his contact list.\n" -"Would you allow him to see your presence status or add him to your contact " -"list ?\n" +"Would you allow him to see your presence status or add him to your contact list ?\n" "If you answer no, this person will be temporarily blacklisted." msgstr "" "%s souhaite vous ajouter à sa liste de contact.\n" -"Souhaitez vous l'autoriser à voir votre information de présence et l'ajouter " -"à votre liste également ?\n" -"Si vous répondez non, cette personne sera mise temporairement sur liste " -"noire." +"Souhaitez vous l'autoriser à voir votre information de présence et l'ajouter à votre liste également ?\n" +"Si vous répondez non, cette personne sera mise temporairement sur liste noire." #: ../gtk/main.c:948 #, c-format @@ -139,19 +132,24 @@ msgstr "" msgid "Call error" msgstr "Erreur lors de l'appel" -#: ../gtk/main.c:1054 ../coreapi/linphonecore.c:2949 +#: ../gtk/main.c:1054 +#: ../coreapi/linphonecore.c:2949 msgid "Call ended" msgstr "Appel terminé." -#: ../gtk/main.c:1057 ../coreapi/linphonecore.c:244 +#: ../gtk/main.c:1057 +#: ../coreapi/linphonecore.c:244 msgid "Incoming call" msgstr "Appel entrant" -#: ../gtk/main.c:1059 ../gtk/incall_view.c:451 ../gtk/main.ui.h:6 +#: ../gtk/main.c:1059 +#: ../gtk/incall_view.c:451 +#: ../gtk/main.ui.h:6 msgid "Answer" msgstr "Répondre" -#: ../gtk/main.c:1061 ../gtk/main.ui.h:7 +#: ../gtk/main.c:1061 +#: ../gtk/main.ui.h:7 msgid "Decline" msgstr "Refuser" @@ -182,7 +180,8 @@ msgstr "Linphone - un téléphone video pour l'internet" msgid "%s (Default)" msgstr "%s (par défaut)" -#: ../gtk/main.c:1714 ../coreapi/callbacks.c:774 +#: ../gtk/main.c:1714 +#: ../coreapi/callbacks.c:774 #, c-format msgid "We are transferred to %s" msgstr "Transfert vers %s" @@ -201,13 +200,15 @@ msgstr "Un visiophone libre" #: ../gtk/friendlist.c:335 msgid "Add to addressbook" -msgstr "" +msgstr "Ajouter au carnet d'adresse" #: ../gtk/friendlist.c:509 msgid "Presence status" msgstr "Info de présence" -#: ../gtk/friendlist.c:526 ../gtk/propertybox.c:362 ../gtk/contact.ui.h:1 +#: ../gtk/friendlist.c:526 +#: ../gtk/propertybox.c:362 +#: ../gtk/contact.ui.h:1 msgid "Name" msgstr "Nom" @@ -269,11 +270,13 @@ msgstr "Débit min. (kbit/s)" msgid "Parameters" msgstr "Paramètres" -#: ../gtk/propertybox.c:430 ../gtk/propertybox.c:573 +#: ../gtk/propertybox.c:430 +#: ../gtk/propertybox.c:573 msgid "Enabled" msgstr "Activé" -#: ../gtk/propertybox.c:432 ../gtk/propertybox.c:573 +#: ../gtk/propertybox.c:432 +#: ../gtk/propertybox.c:573 msgid "Disabled" msgstr "Désactivé" @@ -283,7 +286,7 @@ msgstr "Compte" #: ../gtk/propertybox.c:759 msgid "English" -msgstr "" +msgstr "Anglais" #: ../gtk/propertybox.c:760 msgid "French" @@ -291,31 +294,31 @@ msgstr "Français" #: ../gtk/propertybox.c:761 msgid "Swedish" -msgstr "" +msgstr "Suédois" #: ../gtk/propertybox.c:762 msgid "Italian" -msgstr "" +msgstr "Italien" #: ../gtk/propertybox.c:763 msgid "Spanish" -msgstr "" +msgstr "Espagnol" #: ../gtk/propertybox.c:764 msgid "Brazilian Portugese" -msgstr "" +msgstr "Portugais brésilien" #: ../gtk/propertybox.c:765 msgid "Polish" -msgstr "" +msgstr "Polonais" #: ../gtk/propertybox.c:766 msgid "German" -msgstr "" +msgstr "Allemand" #: ../gtk/propertybox.c:767 msgid "Russian" -msgstr "" +msgstr "Russe" #: ../gtk/propertybox.c:768 msgid "Japanese" @@ -323,15 +326,15 @@ msgstr "日本語" #: ../gtk/propertybox.c:769 msgid "Dutch" -msgstr "" +msgstr "Néérlandais" #: ../gtk/propertybox.c:770 msgid "Hungarian" -msgstr "" +msgstr "Hongrois" #: ../gtk/propertybox.c:771 msgid "Czech" -msgstr "" +msgstr "Tchèque" #: ../gtk/propertybox.c:772 msgid "Chinese" @@ -339,22 +342,19 @@ msgstr "简体中文" #: ../gtk/propertybox.c:773 msgid "Traditional Chinese" -msgstr "" +msgstr "Chinois traditionnel" #: ../gtk/propertybox.c:774 msgid "Norwegian" -msgstr "" +msgstr "Norvégien" #: ../gtk/propertybox.c:775 msgid "Hebrew" -msgstr "" +msgstr "Hébreu" #: ../gtk/propertybox.c:842 -msgid "" -"You need to restart linphone for the new language selection to take effect." -msgstr "" -"La nouvelle selection de langue prendra effet au prochain démarrage de " -"linphone." +msgid "You need to restart linphone for the new language selection to take effect." +msgstr "La nouvelle selection de langue prendra effet au prochain démarrage de linphone." #: ../gtk/propertybox.c:912 msgid "None" @@ -432,7 +432,8 @@ msgstr "" msgid "Username:" msgstr "Nom d'utilisateur:" -#: ../gtk/setupwizard.c:93 ../gtk/password.ui.h:4 +#: ../gtk/setupwizard.c:93 +#: ../gtk/password.ui.h:4 msgid "Password:" msgstr "Mot de passe:" @@ -441,14 +442,12 @@ msgid "Enter your account informations" msgstr "" #: ../gtk/setupwizard.c:120 -#, fuzzy msgid "Username*" -msgstr "Nom d'utilisateur" +msgstr "Nom d'utilisateur*" #: ../gtk/setupwizard.c:121 -#, fuzzy msgid "Password*" -msgstr "Mot de passe" +msgstr "Mot de passe*" #: ../gtk/setupwizard.c:124 msgid "Domain*" @@ -463,14 +462,12 @@ msgid "(*) Required fields" msgstr "" #: ../gtk/setupwizard.c:298 -#, fuzzy msgid "Username: (*)" -msgstr "Nom d'utilisateur:" +msgstr "Nom d'utilisateur: (*)" #: ../gtk/setupwizard.c:300 -#, fuzzy msgid "Password: (*)" -msgstr "Mot de passe:" +msgstr "Mot de passe: (*)" #: ../gtk/setupwizard.c:302 msgid "Email: (*)" @@ -492,8 +489,7 @@ msgstr "" #: ../gtk/setupwizard.c:387 msgid "" -"Please validate your account by clicking on the link we just sent you by " -"email.\n" +"Please validate your account by clicking on the link we just sent you by email.\n" "Then come back here and press Next button." msgstr "" @@ -524,13 +520,14 @@ msgstr "" #: ../gtk/setupwizard.c:588 msgid "Error" -msgstr "" +msgstr "Erreur" #: ../gtk/setupwizard.c:592 msgid "Terminating" msgstr "" -#: ../gtk/incall_view.c:69 ../gtk/incall_view.c:90 +#: ../gtk/incall_view.c:69 +#: ../gtk/incall_view.c:90 #, c-format msgid "Call #%i" msgstr "Appel #%i" @@ -540,7 +537,8 @@ msgstr "Appel #%i" msgid "Transfer to call #%i with %s" msgstr "Transférer vers l'appel #%i avec %s" -#: ../gtk/incall_view.c:209 ../gtk/incall_view.c:212 +#: ../gtk/incall_view.c:209 +#: ../gtk/incall_view.c:212 #, fuzzy msgid "Not used" msgstr "Non trouvé" @@ -571,14 +569,16 @@ msgstr "Redirection" msgid "Through a relay server" msgstr "" -#: ../gtk/incall_view.c:238 ../gtk/incall_view.c:242 +#: ../gtk/incall_view.c:238 +#: ../gtk/incall_view.c:242 #, c-format msgid "" "download: %f\n" "upload: %f (kbit/s)" msgstr "" -#: ../gtk/incall_view.c:341 ../gtk/main.ui.h:12 +#: ../gtk/incall_view.c:341 +#: ../gtk/main.ui.h:12 msgid "Hang up" msgstr "" @@ -586,7 +586,8 @@ msgstr "" msgid "Calling..." msgstr "Tentative d'appel..." -#: ../gtk/incall_view.c:433 ../gtk/incall_view.c:646 +#: ../gtk/incall_view.c:433 +#: ../gtk/incall_view.c:646 msgid "00::00::00" msgstr "" @@ -614,7 +615,8 @@ msgstr "très faible" msgid "too bad" msgstr "nulle" -#: ../gtk/incall_view.c:490 ../gtk/incall_view.c:506 +#: ../gtk/incall_view.c:490 +#: ../gtk/incall_view.c:506 msgid "unavailable" msgstr "indisponible" @@ -631,7 +633,8 @@ msgstr "Sécurisé par ZRTP- [jeton: %s]" msgid "Set unverified" msgstr "Marquer comme non vérifié" -#: ../gtk/incall_view.c:617 ../gtk/main.ui.h:5 +#: ../gtk/incall_view.c:617 +#: ../gtk/main.ui.h:5 msgid "Set verified" msgstr "Marquer comme vérifié" @@ -661,20 +664,19 @@ msgid "Transfer in progress" msgstr "" #: ../gtk/incall_view.c:734 -#, fuzzy msgid "Transfer done." -msgstr "Transfert" +msgstr "Transfert terminé" #: ../gtk/incall_view.c:737 -#, fuzzy msgid "Transfer failed." -msgstr "Transfert" +msgstr "Transfert échoué" #: ../gtk/incall_view.c:781 msgid "Resume" msgstr "Reprendre" -#: ../gtk/incall_view.c:788 ../gtk/main.ui.h:9 +#: ../gtk/incall_view.c:788 +#: ../gtk/main.ui.h:9 msgid "Pause" msgstr "Pause" @@ -692,9 +694,8 @@ msgid "Send" msgstr "Envoyer" #: ../gtk/main.ui.h:3 -#, fuzzy msgid "End conference" -msgstr "En conférence" +msgstr "Fin de conférence" #: ../gtk/main.ui.h:4 msgid "label" @@ -702,7 +703,7 @@ msgstr "" #: ../gtk/main.ui.h:8 msgid "Video" -msgstr "" +msgstr "Vidéo" #: ../gtk/main.ui.h:10 msgid "Mute" @@ -758,17 +759,19 @@ msgstr "" #: ../gtk/main.ui.h:25 msgid "SIP address or phone number:" -msgstr "Addresse SIP ou numéro" +msgstr "Adresse SIP ou numéro" #: ../gtk/main.ui.h:26 msgid "Initiate a new call" msgstr "Démarrer un nouvel appel" -#: ../gtk/main.ui.h:27 ../gtk/parameters.ui.h:48 +#: ../gtk/main.ui.h:27 +#: ../gtk/parameters.ui.h:48 msgid "Add" msgstr "Ajouter" -#: ../gtk/main.ui.h:28 ../gtk/parameters.ui.h:49 +#: ../gtk/main.ui.h:28 +#: ../gtk/parameters.ui.h:49 msgid "Edit" msgstr "Editer" @@ -788,7 +791,8 @@ msgstr "" msgid "*" msgstr "" -#: ../gtk/main.ui.h:33 ../gtk/parameters.ui.h:7 +#: ../gtk/main.ui.h:33 +#: ../gtk/parameters.ui.h:7 msgid "C" msgstr "" @@ -860,11 +864,13 @@ msgstr "Appels récents" msgid "My current identity:" msgstr "Mon identité sip:" -#: ../gtk/main.ui.h:51 ../gtk/tunnel_config.ui.h:7 +#: ../gtk/main.ui.h:51 +#: ../gtk/tunnel_config.ui.h:7 msgid "Username" msgstr "Nom d'utilisateur" -#: ../gtk/main.ui.h:52 ../gtk/tunnel_config.ui.h:8 +#: ../gtk/main.ui.h:52 +#: ../gtk/tunnel_config.ui.h:8 msgid "Password" msgstr "Mot de passe" @@ -1113,7 +1119,7 @@ msgstr "Protocoles réseaux et ports" #: ../gtk/parameters.ui.h:23 msgid "Direct connection to the Internet" -msgstr "Connection directe à l'Internet" +msgstr "Connexion directe à l'Internet" #: ../gtk/parameters.ui.h:24 msgid "Behind NAT / Firewall (specify gateway IP below)" @@ -1121,7 +1127,7 @@ msgstr "Derrière un pare-feu (spécifier la passerelle ci dessous)" #: ../gtk/parameters.ui.h:25 msgid "Public IP address:" -msgstr "Addresse IP publique:" +msgstr "Adresse IP publique:" #: ../gtk/parameters.ui.h:26 msgid "Behind NAT / Firewall (use STUN to resolve)" @@ -1190,9 +1196,7 @@ msgstr "Paramètres multimedia" #: ../gtk/parameters.ui.h:42 msgid "This section defines your SIP address when not using a SIP account" -msgstr "" -"Cette rubrique permet de définir son addresse SIP lorsqu'on ne possède pas " -"de compte SIP" +msgstr "Cette rubrique permet de définir son addresse SIP lorsqu'on ne possède pas de compte SIP" #: ../gtk/parameters.ui.h:43 msgid "Your display name (eg: John Doe):" @@ -1234,11 +1238,13 @@ msgstr "Sécurité" msgid "Manage SIP Accounts" msgstr "Gérer mes comptes SIP" -#: ../gtk/parameters.ui.h:55 ../gtk/tunnel_config.ui.h:4 +#: ../gtk/parameters.ui.h:55 +#: ../gtk/tunnel_config.ui.h:4 msgid "Enable" msgstr "Activer" -#: ../gtk/parameters.ui.h:56 ../gtk/tunnel_config.ui.h:5 +#: ../gtk/parameters.ui.h:56 +#: ../gtk/tunnel_config.ui.h:5 msgid "Disable" msgstr "Désactiver" @@ -1263,13 +1269,8 @@ msgid "Enable adaptive rate control" msgstr "Activer le control de débit adaptatif." #: ../gtk/parameters.ui.h:62 -msgid "" -"Adaptive rate control is a technique to dynamically guess the available " -"bandwidth during a call." -msgstr "" -"Le control de débit adaptatif est une technique pour adapter la qualité " -"de l'audio et de la video en fonction de la bande passante disponible, " -"durant l'appel." +msgid "Adaptive rate control is a technique to dynamically guess the available bandwidth during a call." +msgstr "Le control de débit adaptatif est une technique pour adapter la qualité de l'audio et de la video en fonction de la bande passante disponible, durant l'appel." #: ../gtk/parameters.ui.h:63 msgid "Bandwidth control" @@ -1350,9 +1351,8 @@ msgid "Audio codec" msgstr "Codecs audio" #: ../gtk/call_statistics.ui.h:3 -#, fuzzy msgid "Video codec" -msgstr "Codecs video" +msgstr "Codecs vidéo" #: ../gtk/call_statistics.ui.h:4 msgid "Audio IP bandwidth usage" @@ -1437,11 +1437,8 @@ msgid "Could not resolve this number." msgstr "La destination n'a pu être trouvée." #: ../coreapi/linphonecore.c:2121 -msgid "" -"Could not parse given sip address. A sip url usually looks like sip:" -"user@domain" -msgstr "" -"Adresse SIP mal formulée. Une address sip ressemble à " +msgid "Could not parse given sip address. A sip url usually looks like sip:user@domain" +msgstr "Adresse SIP mal formulée. Une address sip ressemble à " #: ../coreapi/linphonecore.c:2312 msgid "Contacting" @@ -1569,12 +1566,8 @@ msgid "Unknown-bug" msgstr "Bug inconnu" #: ../coreapi/proxy.c:204 -msgid "" -"The sip proxy address you entered is invalid, it must start with \"sip:\" " -"followed by a hostname." -msgstr "" -"L'addresse SIP du proxy est invalide. Elle doit commencer par \"sip:\" " -"suivie par un nom de domaine." +msgid "The sip proxy address you entered is invalid, it must start with \"sip:\" followed by a hostname." +msgstr "L'addresse SIP du proxy est invalide. Elle doit commencer par \"sip:\" suivie par un nom de domaine." #: ../coreapi/proxy.c:210 msgid "" @@ -1582,8 +1575,7 @@ msgid "" "It should look like sip:username@proxydomain, such as sip:alice@example.net" msgstr "" "L'identité SIP que vous avez fourni est invalide.\n" -"Elle doit être de la forme sip:username@domain, comme par example sip:" -"alice@example.net" +"Elle doit être de la forme sip:username@domain, comme par example sip:alice@example.net" #: ../coreapi/proxy.c:1053 #, c-format diff --git a/tools/Makefile.am b/tools/Makefile.am index e906e29b0..ffb469214 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -13,29 +13,46 @@ COMMON_CFLAGS=\ if BUILD_TOOLS -lib_LTLIBRARIES=libxml2lpc.la +lib_LTLIBRARIES=libxml2lpc.la liblpc2xml.la libxml2lpc_la_SOURCES=\ xml2lpc.c \ xml2lpc.h +liblpc2xml_la_SOURCES=\ + lpc2xml.c \ + lpc2xml.h + libxml2lpc_la_CFLAGS=$(COMMON_CFLAGS) libxml2lpc_la_LIBADD=\ $(top_builddir)/coreapi/liblinphone.la \ $(LIBXML2_LIBS) -libxml2lpc_la_LDFLAGS=-no-undefined +liblpc2xml_la_CFLAGS=$(COMMON_CFLAGS) +liblpc2xml_la_LIBADD=\ + $(top_builddir)/coreapi/liblinphone.la \ + $(LIBXML2_LIBS) -bin_PROGRAMS=xml2lpc_test +libxml2lpc_la_LDFLAGS=-no-undefined +liblpc2xml_la_LDFLAGS=-no-undefined + +bin_PROGRAMS=xml2lpc_test lpc2xml_test xml2lpc_test_SOURCES=\ xml2lpc_test.c +lpc2xml_test_SOURCES=\ + lpc2xml_test.c + xml2lpc_test_CFLAGS=$(COMMON_CFLAGS) xml2lpc_test_LDADD=\ $(top_builddir)/coreapi/liblinphone.la \ libxml2lpc.la +lpc2xml_test_CFLAGS=$(COMMON_CFLAGS) +lpc2xml_test_LDADD=\ + $(top_builddir)/coreapi/liblinphone.la \ + liblpc2xml.la endif diff --git a/tools/lpc2xml.c b/tools/lpc2xml.c new file mode 100644 index 000000000..feabdde2e --- /dev/null +++ b/tools/lpc2xml.c @@ -0,0 +1,237 @@ +/* +linphone +Copyright (C) 2012 Belledonne Communications SARL +Yann DIORCET (yann.diorcet@linphone.org) + +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 "lpc2xml.h" +#include +#include +#include + +#define LPC2XML_BZ 2048 + +struct _lpc2xml_context { + const LpConfig *lpc; + lpc2xml_function cbf; + void *ctx; + + xmlDoc *doc; + char errorBuffer[LPC2XML_BZ]; + char warningBuffer[LPC2XML_BZ]; +}; + + +lpc2xml_context* lpc2xml_context_new(lpc2xml_function cbf, void *ctx) { + lpc2xml_context *xmlCtx = (lpc2xml_context*)malloc(sizeof(lpc2xml_context)); + if(xmlCtx != NULL) { + xmlCtx->lpc = NULL; + xmlCtx->cbf = cbf; + xmlCtx->ctx = ctx; + + xmlCtx->doc = NULL; + xmlCtx->errorBuffer[0]='\0'; + xmlCtx->warningBuffer[0]='\0'; + } + return xmlCtx; +} + +void lpc2xml_context_destroy(lpc2xml_context *ctx) { + if(ctx->doc != NULL) { + xmlFreeDoc(ctx->doc); + ctx->doc = NULL; + } + free(ctx); +} +/* +static void lpc2xml_context_clear_logs(lpc2xml_context *ctx) { + ctx->errorBuffer[0]='\0'; + ctx->warningBuffer[0]='\0'; +}*/ + +static void lpc2xml_log(lpc2xml_context *xmlCtx, int level, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + if(xmlCtx->cbf != NULL) { + xmlCtx->cbf((xmlCtx)->ctx, level, fmt, args); + } + va_end(args); +} + +static int processEntry(const char *section, const char *entry, xmlNode *node, lpc2xml_context *ctx) { + const char *content = lp_config_get_string(ctx->lpc, section, entry, NULL); + if(content == NULL) { + lpc2xml_log(ctx->ctx, LPC2XML_ERROR, "Issue when reading the lpc"); + return -1; + } + xmlNodeSetContent(node, (const xmlChar *) content); + return 0; +} + +struct __processSectionCtx { + int ret; + const char *section; + xmlNode *node; + lpc2xml_context *ctx; +}; + +static void processSection_cb(const char *entry, struct __processSectionCtx *ctx) { + if(ctx->ret == 0) { + xmlNode *node = xmlNewChild(ctx->node, NULL, (const xmlChar *)"entry", NULL); + if(node == NULL) { + lpc2xml_log(ctx->ctx, LPC2XML_ERROR, "Can't create \"entry\" element"); + ctx->ret = -1; + return; + } + xmlAttr *name_attr = xmlSetProp(node, (const xmlChar *)"name", (const xmlChar *)entry); + if(name_attr == NULL) { + lpc2xml_log(ctx->ctx, LPC2XML_ERROR, "Can't create name attribute for \"entry\" element"); + ctx->ret = -1; + return; + } + ctx->ret = processEntry(ctx->section, entry, node, ctx->ctx); + } +} + +static int processSection(const char *section, xmlNode *node, lpc2xml_context *ctx) { + struct __processSectionCtx pc_ctx = {0, section, node, ctx}; + lp_config_for_each_entry(ctx->lpc, section, (void (*)(const char *, void *))processSection_cb, (void*)&pc_ctx); + return pc_ctx.ret; +} + + + +struct __processConfigCtx { + int ret; + xmlNode *node; + lpc2xml_context *ctx; +}; + +static void processConfig_cb(const char *section, struct __processConfigCtx *ctx) { + if(ctx->ret == 0) { + xmlNode *node = xmlNewChild(ctx->node, NULL, (const xmlChar *)"section", NULL); + if(node == NULL) { + lpc2xml_log(ctx->ctx, LPC2XML_ERROR, "Can't create \"section\" element"); + ctx->ret = -1; + return; + } + xmlAttr *name_attr = xmlSetProp(node, (const xmlChar *)"name", (const xmlChar *)section); + if(name_attr == NULL) { + lpc2xml_log(ctx->ctx, LPC2XML_ERROR, "Can't create name attribute for \"section\" element"); + ctx->ret = -1; + return; + } + ctx->ret = processSection(section, node, ctx->ctx); + } +} + +static int processConfig(xmlNode *node, lpc2xml_context *ctx) { + struct __processConfigCtx pc_ctx = {0, node, ctx}; + lp_config_for_each_section(ctx->lpc, (void (*)(const char *, void *))processConfig_cb, (void*)&pc_ctx); + return pc_ctx.ret; +} + +static int processDoc(xmlDoc *doc, lpc2xml_context *ctx) { + int ret = 0; + xmlNode *root_node = xmlNewNode(NULL, (const xmlChar *)"config"); + if(root_node == NULL) { + lpc2xml_log(ctx, LPC2XML_ERROR, "Can't create \"config\" element"); + return -1; + } + xmlNs *lpc_ns = xmlNewNs(root_node, (const xmlChar *)"http://www.linphone.org/xsds/lpconfig.xsd", NULL); + if(lpc_ns == NULL) { + lpc2xml_log(ctx, LPC2XML_WARNING, "Can't create lpc namespace"); + } else { + xmlSetNs(root_node, lpc_ns); + } + xmlNs *xsi_ns = xmlNewNs(root_node, (const xmlChar *)"http://www.w3.org/2001/XMLSchema-instance", (const xmlChar *)"xsi"); + if(lpc_ns == NULL) { + lpc2xml_log(ctx, LPC2XML_WARNING, "Can't create xsi namespace"); + } + xmlAttr *schemaLocation = xmlNewNsProp(root_node, xsi_ns, (const xmlChar *)"schemaLocation", (const xmlChar *)"http://www.linphone.org/xsds/lpconfig.xsd lpconfig.xsd"); + if(schemaLocation == NULL) { + lpc2xml_log(ctx, LPC2XML_WARNING, "Can't create schemaLocation"); + } + ret = processConfig(root_node, ctx); + xmlDocSetRootElement(doc, root_node); + return ret; +} + +static int internal_convert_lpc2xml(lpc2xml_context *ctx) { + int ret = 0; + lpc2xml_log(ctx, LPC2XML_DEBUG, "Generation started"); + if(ctx->doc != NULL) { + xmlFreeDoc(ctx->doc); + ctx->doc = NULL; + } + xmlDoc *doc = xmlNewDoc((const xmlChar *)"1.0"); + ret = processDoc(doc, ctx); + if(ret == 0) { + ctx->doc = doc; + } else { + xmlFreeDoc(doc); + } + lpc2xml_log(ctx, LPC2XML_DEBUG, "Generation ended ret:%d", ret); + return ret; +} + +int lpc2xml_set_lpc(lpc2xml_context* context, const LpConfig *lpc) { + context->lpc = lpc; + return 0; +} + +int lpc2xml_convert_file(lpc2xml_context* context, const char *filename) { + int ret = 0; + xmlSaveCtxtPtr save_ctx = xmlSaveToFilename(filename, "UTF-8", XML_SAVE_FORMAT); + ret = internal_convert_lpc2xml(context); + if(ret == 0) { + ret = xmlSaveDoc(save_ctx, context->doc); + } + xmlSaveClose(save_ctx); + return ret; +} + +int lpc2xml_convert_fd(lpc2xml_context* context, int fd) { + int ret = 0; + xmlSaveCtxtPtr save_ctx = xmlSaveToFd(fd, "UTF-8", XML_SAVE_FORMAT); + ret = internal_convert_lpc2xml(context); + if(ret == 0) { + ret = xmlSaveDoc(save_ctx, context->doc); + } + xmlSaveClose(save_ctx); + return ret; +} + +int lpc2xml_convert_string(lpc2xml_context* context, char **content) { + int ret = 0; + xmlBufferPtr buffer = xmlBufferCreate(); + xmlSaveCtxtPtr save_ctx = xmlSaveToBuffer(buffer, "UTF-8", XML_SAVE_FORMAT); + internal_convert_lpc2xml(context); + if(ret == 0) { + ret = xmlSaveDoc(save_ctx, context->doc); + } + xmlSaveClose(save_ctx); + if(ret == 0) { +#if LIBXML_VERSION >= 20800 + *content = (char *)xmlBufferDetach(buffer); +#else + *content = strdup((const char *)xmlBufferContent(buffer)); +#endif + } + xmlBufferFree(buffer); + return ret; +} diff --git a/tools/lpc2xml.h b/tools/lpc2xml.h new file mode 100644 index 000000000..025400907 --- /dev/null +++ b/tools/lpc2xml.h @@ -0,0 +1,46 @@ +/* +linphone +Copyright (C) 2012 Belledonne Communications SARL + +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 LPC2XML_H_ +#define LPC2XML_H_ + +#include "lpconfig.h" + +typedef struct _lpc2xml_context lpc2xml_context; + +typedef enum _lpc2xml_log_level { + LPC2XML_DEBUG = 0, + LPC2XML_MESSAGE, + LPC2XML_WARNING, + LPC2XML_ERROR +} lpc2xml_log_level; + +typedef void(*lpc2xml_function)(void *ctx, lpc2xml_log_level level, const char *fmt, va_list list); + +lpc2xml_context* lpc2xml_context_new(lpc2xml_function cbf, void *ctx); +void lpc2xml_context_destroy(lpc2xml_context*); + +int lpc2xml_set_lpc(lpc2xml_context* context, const LpConfig *lpc); + +int lpc2xml_convert_file(lpc2xml_context* context, const char *filename); +int lpc2xml_convert_fd(lpc2xml_context* context, int fd); +int lpc2xml_convert_string(lpc2xml_context* context, char **content); + + +#endif //LPC2XML_H_ diff --git a/tools/lpc2xml_test.c b/tools/lpc2xml_test.c new file mode 100644 index 000000000..cdad72f97 --- /dev/null +++ b/tools/lpc2xml_test.c @@ -0,0 +1,67 @@ +/* +linphone +Copyright (C) 2012 Belledonne Communications SARL + +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 +#include "lpc2xml.h" + +void cb_function(void *ctx, lpc2xml_log_level level, const char *msg, va_list list) { + const char *header = ""; + switch(level) { + case LPC2XML_DEBUG: + header = "DEBUG"; + break; + case LPC2XML_MESSAGE: + header = "MESSAGE"; + break; + case LPC2XML_WARNING: + header = "WARNING"; + break; + case LPC2XML_ERROR: + header = "ERROR"; + break; + } + fprintf(stdout, "%s - ", header); + vfprintf(stdout, msg, list); + fprintf(stdout, "\n"); +} + +void show_usage(int argc, char *argv[]) { + fprintf(stderr, "usage %s convert \n", + argv[0]); +} + +int main(int argc, char *argv[]) { + if(argc != 4) { + show_usage(argc, argv); + return -1; + } + + lpc2xml_context *ctx = lpc2xml_context_new(cb_function, NULL); + LpConfig *lpc = lp_config_new(argv[2]); + lpc2xml_set_lpc(ctx, lpc); + if(strcmp("convert", argv[1]) == 0) { + lpc2xml_convert_file(ctx, argv[3]); + } else { + show_usage(argc, argv); + } + lp_config_destroy(lpc); + lpc2xml_context_destroy(ctx); + return 0; +} + diff --git a/tools/xml2lpc.c b/tools/xml2lpc.c index d5e2160ab..9d720f1f3 100644 --- a/tools/xml2lpc.c +++ b/tools/xml2lpc.c @@ -78,7 +78,7 @@ static void xml2lpc_log(xml2lpc_context *xmlCtx, int level, const char *fmt, ... va_end(args); } -static void xml2lpc_genericxml_error(void *ctx, const char *fmt, ...) { +static void xml2lpc_genericxml_error(void *ctx, const char *fmt, ...) { xml2lpc_context *xmlCtx = (xml2lpc_context *)ctx; int sl = strlen(xmlCtx->errorBuffer); va_list args; @@ -87,7 +87,7 @@ static void xml2lpc_genericxml_error(void *ctx, const char *fmt, ...) { va_end(args); } -static void xml2lpc_genericxml_warning(void *ctx, const char *fmt, ...) { +static void xml2lpc_genericxml_warning(void *ctx, const char *fmt, ...) { xml2lpc_context *xmlCtx = (xml2lpc_context *)ctx; int sl = strlen(xmlCtx->warningBuffer); va_list args; @@ -214,11 +214,11 @@ static int processDoc(xmlNode *node, xml2lpc_context *ctx) { return 0; } -static int internal_convert_xml2lpc(xmlDoc *doc, xml2lpc_context *ctx) { +static int internal_convert_xml2lpc(xml2lpc_context *ctx) { xml2lpc_log(ctx, XML2LPC_DEBUG, "Parse started"); - xmlNode *rootNode = xmlDocGetRootElement(doc); + xmlNode *rootNode = xmlDocGetRootElement(ctx->doc); //dumpNodes(0, rootNode, cbf, ctx); - int ret = processDoc(rootNode, ctx); + int ret = processDoc(rootNode, ctx); xml2lpc_log(ctx, XML2LPC_DEBUG, "Parse ended ret:%d", ret); return ret; } @@ -230,10 +230,10 @@ int xml2lpc_validate(xml2lpc_context *xmlCtx) { validCtx = xmlSchemaNewValidCtxt(xmlSchemaParse(parserCtx)); xmlSchemaSetValidErrors(validCtx, xml2lpc_genericxml_error, xml2lpc_genericxml_warning, xmlCtx); int ret = xmlSchemaValidateDoc(validCtx, xmlCtx->doc); - if(ret >0) { + if(ret > 0) { xml2lpc_log(xmlCtx, XML2LPC_WARNING, "%s", xmlCtx->warningBuffer); xml2lpc_log(xmlCtx, XML2LPC_ERROR, "%s", xmlCtx->errorBuffer); - } else { + } else if(ret < 0) { xml2lpc_log(xmlCtx, XML2LPC_ERROR, "Internal error"); } xmlSchemaFreeValidCtxt(validCtx); @@ -243,7 +243,7 @@ int xml2lpc_validate(xml2lpc_context *xmlCtx) { int xml2lpc_convert(xml2lpc_context *xmlCtx, LpConfig *lpc) { xml2lpc_context_clear_logs(xmlCtx); xmlCtx->lpc = lpc; - return internal_convert_xml2lpc(xmlCtx->doc, xmlCtx); + return internal_convert_xml2lpc(xmlCtx); } int xml2lpc_set_xml_file(xml2lpc_context* xmlCtx, const char *filename) {