diff --git a/configure.ac b/configure.ac index 221f78409..e18bfed2b 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/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 2f0d25b0d..1f7ff42fd 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -344,7 +344,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){ @@ -393,7 +393,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 f5a5d361f..c76441f5a 100644 --- a/coreapi/linphone_tunnel.cc +++ b/coreapi/linphone_tunnel.cc @@ -31,60 +31,257 @@ #include "private.h" #include "lpconfig.h" - LinphoneTunnel* linphone_core_get_tunnel(LinphoneCore *lc){ return lc->tunnel; } +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(LinphoneTunnelConfig *tunnel) { + return tunnel->host; +} + +void linphone_tunnel_config_set_port(LinphoneTunnelConfig *tunnel, int port) { + tunnel->port = port; +} + +int linphone_tunnel_config_get_port(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(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(LinphoneTunnelConfig *tunnel) { + return tunnel->delay; +} + +void linphone_tunnel_config_destroy(LinphoneTunnelConfig *tunnel) { + if(tunnel->host != NULL) { + ms_free(tunnel->host); + } + ms_free(tunnel); +} + #ifdef TUNNEL_ENABLED -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(tunnel_config->remote_udp_mirror_port != -1) { + str = ms_strdup_printf("%s:%d:%d:%d", + tunnel_config->host, + tunnel_config->port, + tunnel_config->remote_udp_mirror_port, + tunnel_config->delay); + } else { + str = ms_strdup_printf("%s:%d", + tunnel_config->host, + tunnel_config->port); + } + 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(tunnel_config->remote_udp_mirror_port == -1) { + bcTunnel(tunnel)->addServer(tunnel_config->host, tunnel_config->port); + } else { + bcTunnel(tunnel)->addServer(tunnel_config->host, tunnel_config->port, + tunnel_config->remote_udp_mirror_port, tunnel_config->delay); + } + 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){ @@ -173,28 +370,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); } @@ -205,10 +380,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); } @@ -220,13 +393,13 @@ 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){ +const MSList *linphone_tunnel_get_servers(LinphoneTunnel *tunnel){ return NULL; } diff --git a/coreapi/linphone_tunnel.h b/coreapi/linphone_tunnel.h index bb343008a..03c568e4e 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(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(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(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(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/linphonecore.c b/coreapi/linphonecore.c index c6fc73590..ee0be33be 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); void linphone_core_get_local_ip(LinphoneCore *lc, const char *dest, char *result); static void toggle_video_preview(LinphoneCore *lc, bool_t val); @@ -566,6 +567,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*/ @@ -2549,6 +2551,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; @@ -2560,10 +2575,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)); @@ -3685,6 +3702,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 f1a9174c8..55198e319 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -1209,6 +1209,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); @@ -1429,7 +1430,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 c171fac88..29d31b7c6 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -299,6 +299,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 203c7cb92..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){ @@ -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; 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 506c9036d..868937573 100644 --- a/gtk/chat.c +++ b/gtk/chat.c @@ -42,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); @@ -55,6 +62,34 @@ 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); @@ -70,17 +105,17 @@ void linphone_gtk_push_text(GtkWidget *w, const LinphoneAddress *from, const cha 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); - 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); gtk_text_buffer_get_bounds (buffer, &begin, &end); @@ -97,7 +132,8 @@ void linphone_gtk_push_text(GtkWidget *w, const LinphoneAddress *from, const cha /*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",NULL); + 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); @@ -118,7 +154,7 @@ const LinphoneAddress* linphone_gtk_get_used_identity(){ /* function in dev for displaying ack*/ void update_chat_state_message(LinphoneChatMessageState state){ - /*GtkWidget *main_window=linphone_gtk_get_main_window(); + /* 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"); @@ -144,29 +180,24 @@ void update_chat_state_message(LinphoneChatMessageState state){ 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: - gtk_text_buffer_insert_with_tags_by_name(b,&iter,"Message in progress.",-1, - "italic","right","small",NULL); + result="Message in progress.. "; break; case LinphoneChatMessageStateDelivered: - gtk_text_buffer_insert_with_tags_by_name(b,&iter,"Message delivered",-1, - "italic","right","small",NULL); + result="Message delivered "; break; case LinphoneChatMessageStateNotDelivered: - gtk_text_buffer_insert_with_tags_by_name(b,&iter,"Message not delivered",-1, - "italic","right","small",NULL); + result="Message not delivered "; break; - default : gtk_text_buffer_insert_with_tags_by_name(b,&iter,"12",-1, - "italic","right","small",NULL); + default : result="Message in progress.. "; } - + gtk_text_buffer_insert_with_tags_by_name(b,&iter,result,-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); - } else { - fprintf(stdout,"NULLLL\n"); - }*/ + } */ } static void on_chat_state_changed(LinphoneChatMessage *msg, LinphoneChatMessageState state, void *user_pointer){ @@ -199,8 +230,12 @@ 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); @@ -208,7 +243,6 @@ GtkWidget* linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddres idx = gtk_notebook_page_num(notebook, chat_view); gtk_notebook_set_current_page(notebook, idx); gtk_widget_show(chat_view); - g_object_set_data(G_OBJECT(chat_view),"cr",cr); g_object_set_data(G_OBJECT(chat_view),"idx",GINT_TO_POINTER(idx)); @@ -232,6 +266,8 @@ GtkWidget* linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddres gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), "right","justification", GTK_JUSTIFY_RIGHT,NULL); + gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), + "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)), @@ -239,7 +275,7 @@ GtkWidget* linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddres gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), "small","size",8*PANGO_SCALE,NULL); gtk_text_buffer_create_tag(gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)), - "font_grey","foreground","grey",NULL); + "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,NULL); @@ -272,10 +308,12 @@ 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_with_tags_by_name(text_buffer,&start,buf,-1,"font_grey","small",NULL); + 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); } + + 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",linphone_address_as_string_uri_only(uri)); g_object_set_data(G_OBJECT(chat_view),"from_message",linphone_address_as_string_uri_only(uri)); @@ -307,7 +345,6 @@ void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room, const g_object_set_data(G_OBJECT(friendlist),"chatview",(gpointer)w); } - #ifdef HAVE_GTK_OSX /* Notified when a new message is sent */ linphone_gtk_status_icon_set_blinking(TRUE); diff --git a/gtk/main.c b/gtk/main.c index 59530d816..12e84bc97 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -237,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); diff --git a/gtk/main.ui b/gtk/main.ui index ca1893cbf..f82875cb6 100644 --- a/gtk/main.ui +++ b/gtk/main.ui @@ -113,6 +113,7 @@ True True + 4 diff --git a/gtk/parameters.ui b/gtk/parameters.ui index 9e32e29c7..130b7e7c5 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 @@ -875,9 +892,6 @@ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK 6 2 - - - True @@ -899,11 +913,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 @@ -1076,10 +1090,10 @@ Enable echo cancellation - False True True False + False True @@ -1090,6 +1104,9 @@ 6 + + + @@ -1425,10 +1442,10 @@ GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - False True True True + False @@ -1472,11 +1489,11 @@ - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False @@ -1520,11 +1537,11 @@ - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False @@ -1568,11 +1585,11 @@ - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False @@ -1661,11 +1678,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 @@ -1847,11 +1864,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 @@ -1864,11 +1881,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 @@ -1880,11 +1897,11 @@ - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False @@ -1928,11 +1945,11 @@ - False True True True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + False @@ -2095,10 +2112,10 @@ Enable adaptive rate control - False True True False + False 0 True @@ -2124,7 +2141,7 @@ 2 3 GTK_FILL - + @@ -2250,10 +2267,10 @@ Show advanced settings - False True True False + False True @@ -2330,11 +2347,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 90b2bf947..41fe854ed 100644 --- a/gtk/propertybox.c +++ b/gtk/propertybox.c @@ -880,19 +880,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"); @@ -928,21 +944,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)); } @@ -1152,44 +1177,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; @@ -1222,6 +1225,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"))); @@ -1235,7 +1239,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/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 6874ac86f..d5811e376 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 6874ac86f173b5cf57b87e5ee529652ba6676295 +Subproject commit d5811e376759433da3c19585b2d8d0329e1c06b2 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/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..12af75322 --- /dev/null +++ b/tools/lpc2xml.c @@ -0,0 +1,233 @@ +/* +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 + + +#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, unsigned 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) { + *content = xmlBufferDetach(buffer); + } + xmlBufferFree(buffer); + return ret; +} diff --git a/tools/lpc2xml.h b/tools/lpc2xml.h new file mode 100644 index 000000000..f1583109b --- /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, unsigned 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) {