Merge remote-tracking branch 'linphone/master'

This commit is contained in:
Simon Morlat 2013-01-17 09:17:00 +01:00
commit a46ce1af15
36 changed files with 1406 additions and 536 deletions

View file

@ -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])

View file

@ -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);
}

View file

@ -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){

View file

@ -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..."));
}
}

View file

@ -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());
}

View file

@ -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;
}

View file

@ -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

View file

@ -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;i<md->nstreams;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;

View file

@ -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
*/

View file

@ -23,9 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "linphonecore_utils.h"
#include <ortp/zrtp.h>
#ifdef TUNNEL_ENABLED
#include "linphone_tunnel.h"
#endif
extern "C" {
#include "mediastreamer2/mediastream.h"
@ -34,6 +31,8 @@ extern "C" {
#include "private.h"
#include <cpu-features.h>
#include "lpconfig.h"
#ifdef ANDROID
#include <android/log.h>
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);
}

View file

@ -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){

View file

@ -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);

View file

@ -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

View file

@ -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);

View file

@ -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
*/

View file

@ -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);

View file

@ -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;

View file

@ -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;
};

View file

@ -209,108 +209,108 @@ static void mk_presence_body (const SalPresenceStatus online_status, const char
if (online_status==SalPresenceOnline)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s\" priority=\"0.800000\">\n\
<status status=\"open\" />\n\
<msnsubstatus substatus=\"online\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
"<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
"<presence>\n"
"<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
"<atom id=\"%i\">\n"
"<address uri=\"%s\" priority=\"0.800000\">\n"
"<status status=\"open\" />\n"
"<msnsubstatus substatus=\"online\" />\n"
"</address>\n"
"</atom>\n"
"</presence>", contact_info, atom_id, contact_info);
}
else if (online_status == SalPresenceBusy ||
online_status == SalPresenceDonotdisturb)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s\" priority=\"0.800000\">\n\
<status status=\"inuse\" />\n\
<msnsubstatus substatus=\"busy\" />\n\
</address>\n\
</atom>\n</presence>", contact_info, atom_id, contact_info);
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
"<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
"<presence>\n"
"<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
"<atom id=\"%i\">\n"
"<address uri=\"%s\" priority=\"0.800000\">\n"
"<status status=\"inuse\" />\n"
"<msnsubstatus substatus=\"busy\" />\n"
"</address>\n"
"</atom>\n</presence>", contact_info, atom_id, contact_info);
}
else if (online_status==SalPresenceBerightback)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s\" priority=\"0.800000\">\n\
<status status=\"open\" />\n\
<msnsubstatus substatus=\"berightback\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
"<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
"<presence>\n"
"<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
"<atom id=\"%i\">\n"
"<address uri=\"%s\" priority=\"0.800000\">\n"
"<status status=\"open\" />\n"
"<msnsubstatus substatus=\"berightback\" />\n"
"</address>\n"
"</atom>\n"
"</presence>", contact_info, atom_id, contact_info);
}
else if (online_status == SalPresenceAway ||
online_status == SalPresenceMoved)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s\" priority=\"0.800000\">\n\
<status status=\"open\" />\n\
<msnsubstatus substatus=\"away\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
"<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
"<presence>\n"
"<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
"<atom id=\"%i\">\n"
"<address uri=\"%s\" priority=\"0.800000\">\n"
"<status status=\"open\" />\n"
"<msnsubstatus substatus=\"away\" />\n"
"</address>\n"
"</atom>\n"
"</presence>", contact_info, atom_id, contact_info);
}
else if (online_status==SalPresenceOnthephone)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s\" priority=\"0.800000\">\n\
<status status=\"inuse\" />\n\
<msnsubstatus substatus=\"onthephone\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
"<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
"<presence>\n"
"<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
"<atom id=\"%i\">\n"
"<address uri=\"%s\" priority=\"0.800000\">\n"
"<status status=\"inuse\" />\n"
"<msnsubstatus substatus=\"onthephone\" />\n"
"</address>\n"
"</atom>\n"
"</presence>", contact_info, atom_id, contact_info);
}
else if (online_status==SalPresenceOuttolunch)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s\" priority=\"0.800000\">\n\
<status status=\"open\" />\n\
<msnsubstatus substatus=\"outtolunch\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
"<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
"<presence>\n"
"<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
"<atom id=\"%i\">\n"
"<address uri=\"%s\" priority=\"0.800000\">\n"
"<status status=\"open\" />\n"
"<msnsubstatus substatus=\"outtolunch\" />\n"
"</address>\n"
"</atom>\n"
"</presence>", contact_info, atom_id, contact_info);
}
else
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s\" priority=\"0.800000\">\n\
<status status=\"closed\" />\n\
<msnsubstatus substatus=\"away\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
"<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
"<presence>\n"
"<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
"<atom id=\"%i\">\n"
"<address uri=\"%s\" priority=\"0.800000\">\n"
"<status status=\"closed\" />\n"
"<msnsubstatus substatus=\"away\" />\n"
"</address>\n"
"</atom>\n"
"</presence>", 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, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s\">\n\
<status status=\"open\" />\n\
<msnsubstatus substatus=\"online\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
"<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n"
"<presence>\n"
"<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
"<atom id=\"%i\">\n"
"<address uri=\"%s\">\n"
"<status status=\"open\" />\n"
"<msnsubstatus substatus=\"online\" />\n"
"</address>\n"
"</atom>\n"
"</presence>", contact_info, atom_id, contact_info);
}
else if (online_status == SalPresenceBusy ||
online_status == SalPresenceDonotdisturb)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s\">\n\
<status status=\"inuse\" />\n\
<msnsubstatus substatus=\"busy\" />\n\
</address>\n\
</atom>\n</presence>", contact_info, atom_id, contact_info);
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
"<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n"
"<presence>\n"
"<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
"<atom id=\"%i\">\n"
"<address uri=\"%s\">\n"
"<status status=\"inuse\" />\n"
"<msnsubstatus substatus=\"busy\" />\n"
"</address>\n"
"</atom>\n</presence>", contact_info, atom_id, contact_info);
}
else if (online_status==SalPresenceBerightback)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s\">\n\
<status status=\"inactive\" />\n\
<msnsubstatus substatus=\"berightback\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
"<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n"
"<presence>\n"
"<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
"<atom id=\"%i\">\n"
"<address uri=\"%s\">\n"
"<status status=\"inactive\" />\n"
"<msnsubstatus substatus=\"berightback\" />\n"
"</address>\n"
"</atom>\n"
"</presence>", contact_info, atom_id, contact_info);
}
else if (online_status == SalPresenceAway ||
online_status == SalPresenceMoved)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s\">\n\
<status status=\"inactive\" />\n\
<msnsubstatus substatus=\"idle\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
"<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n"
"<presence>\n"
"<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
"<atom id=\"%i\">\n"
"<address uri=\"%s\">\n"
"<status status=\"inactive\" />\n"
"<msnsubstatus substatus=\"idle\" />\n"
"</address>\n"
"</atom>\n"
"</presence>", contact_info, atom_id, contact_info);
}
else if (online_status==SalPresenceOnthephone)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s\">\n\
<status status=\"inuse\" />\n\
<msnsubstatus substatus=\"onthephone\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
"<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n"
"<presence>\n"
"<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
"<atom id=\"%i\">\n"
"<address uri=\"%s\">\n"
"<status status=\"inuse\" />\n"
"<msnsubstatus substatus=\"onthephone\" />\n"
"</address>\n"
"</atom>\n"
"</presence>", contact_info, atom_id, contact_info);
}
else if (online_status==SalPresenceOuttolunch)
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s\">\n\
<status status=\"inactive\" />\n\
<msnsubstatus substatus=\"outtolunch\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
"<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n"
"<presence>\n"
"<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
"<atom id=\"%i\">\n"
"<address uri=\"%s\">\n"
"<status status=\"inactive\" />\n"
"<msnsubstatus substatus=\"outtolunch\" />\n"
"</address>\n"
"</atom>\n"
"</presence>", contact_info, atom_id, contact_info);
}
else
{
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n\
<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n\
<presence>\n\
<presentity uri=\"%s;method=SUBSCRIBE\" />\n\
<atom id=\"%i\">\n\
<address uri=\"%s\">\n\
<status status=\"closed\" />\n\
<msnsubstatus substatus=\"offline\" />\n\
</address>\n\
</atom>\n\
</presence>", contact_info, atom_id, contact_info);
snprintf(buf, buflen, "<?xml version=\"1.0\"?>\n"
"<!DOCTYPE presence SYSTEM \"http://schemas.microsoft.com/2002/09/sip/presence\">\n"
"<presence>\n"
"<presentity uri=\"%s;method=SUBSCRIBE\" />\n"
"<atom id=\"%i\">\n"
"<address uri=\"%s\">\n"
"<status status=\"closed\" />\n"
"<msnsubstatus substatus=\"offline\" />\n"
"</address>\n"
"</atom>\n"
"</presence>", 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, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
entity=\"%s\">\n\
<tuple id=\"sg89ae\">\n\
<status><basic>open</basic></status>\n\
<contact priority=\"0.8\">%s</contact>\n\
</tuple>\n\
</presence>",
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" "
"xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" "
"xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" "
"entity=\"%s\">\n"
"<tuple id=\"sg89ae\">\n"
"<status><basic>open</basic></status>\n"
"<contact priority=\"0.8\">%s</contact>\n"
"</tuple>\n"
"</presence>",
contact_info, contact_info);
}
else if (online_status == SalPresenceBusy ||
online_status == SalPresenceDonotdisturb)
{
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
entity=\"%s\">\n\
<tuple id=\"sg89ae\">\n\
<status><basic>open</basic></status>\n\
<contact priority=\"0.8\">%s</contact>\n\
</tuple>\n\
<dm:person id=\"sg89aep\">\n\
<rpid:activities><rpid:busy/></rpid:activities>\n\
</dm:person>\n\
</presence>",
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" "
"xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" "
"xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" "
"entity=\"%s\">\n"
"<tuple id=\"sg89ae\">\n"
"<status><basic>open</basic></status>\n"
"<contact priority=\"0.8\">%s</contact>\n"
"</tuple>\n"
"<dm:person id=\"sg89aep\">\n"
"<rpid:activities><rpid:busy/></rpid:activities>\n"
"</dm:person>\n"
"</presence>",
contact_info, contact_info);
}
else if (online_status==SalPresenceBerightback)
{
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
entity=\"%s\">\n\
<tuple id=\"sg89ae\">\n\
<status><basic>open</basic></status>\n\
<contact priority=\"0.8\">%s</contact>\n\
</tuple>\n\
<dm:person id=\"sg89aep\">\n\
<rpid:activities><rpid:in-transit/></rpid:activities>\n\
</dm:person>\n\
</presence>",
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" "
"xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" "
"xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" "
"entity=\"%s\">\n"
"<tuple id=\"sg89ae\">\n"
"<status><basic>open</basic></status>\n"
"<contact priority=\"0.8\">%s</contact>\n"
"</tuple>\n"
"<dm:person id=\"sg89aep\">\n"
"<rpid:activities><rpid:in-transit/></rpid:activities>\n"
"</dm:person>\n"
"</presence>",
contact_info, contact_info);
}
else if (online_status == SalPresenceAway ||
online_status == SalPresenceMoved)
{
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
entity=\"%s\">\n\
<tuple id=\"sg89ae\">\n\
<status><basic>open</basic></status>\n\
<contact priority=\"0.8\">%s</contact>\n\
</tuple>\n\
<dm:person id=\"sg89aep\">\n\
<rpid:activities><rpid:away/></rpid:activities>\n\
</dm:person>\n\
</presence>",
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" "
"xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" "
"xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" "
"entity=\"%s\">\n"
"<tuple id=\"sg89ae\">\n"
"<status><basic>open</basic></status>\n"
"<contact priority=\"0.8\">%s</contact>\n"
"</tuple>\n"
"<dm:person id=\"sg89aep\">\n"
"<rpid:activities><rpid:away/></rpid:activities>\n"
"</dm:person>\n"
"</presence>",
contact_info, contact_info);
}
else if (online_status==SalPresenceOnthephone)
{
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
entity=\"%s\">\n\
<tuple id=\"sg89ae\">\n\
<status><basic>open</basic></status>\n\
<contact priority=\"0.8\">%s</contact>\n\
</tuple>\n\
<dm:person id=\"sg89aep\">\n\
<rpid:activities><rpid:on-the-phone/></rpid:activities>\n\
</dm:person>\n\
</presence>",
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" "
"xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" "
"xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" "
"entity=\"%s\">\n"
"<tuple id=\"sg89ae\">\n"
"<status><basic>open</basic></status>\n"
"<contact priority=\"0.8\">%s</contact>\n"
"</tuple>\n"
"<dm:person id=\"sg89aep\">\n"
"<rpid:activities><rpid:on-the-phone/></rpid:activities>\n"
"</dm:person>\n"
"</presence>",
contact_info, contact_info);
}
else if (online_status==SalPresenceOuttolunch)
{
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
entity=\"%s\">\n\
<tuple id=\"7777\">\n\
<status><basic>open</basic></status>\n\
<contact priority=\"0.8\">%s</contact>\n\
</tuple>\n\
<dm:person id=\"78787878\">\n\
<rpid:activities><rpid:meal/></rpid:activities>\n\
<rpid:note>Out to lunch</rpid:note> \n\
</dm:person>\n\
</presence>",
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" "
"xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" "
"xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" "
"entity=\"%s\">\n"
"<tuple id=\"7777\">\n"
"<status><basic>open</basic></status>\n"
"<contact priority=\"0.8\">%s</contact>\n"
"</tuple>\n"
"<dm:person id=\"78787878\">\n"
"<rpid:activities><rpid:meal/></rpid:activities>\n"
"<rpid:note>Out to lunch</rpid:note> \n"
"</dm:person>\n"
"</presence>",
contact_info, contact_info);
}
else
{
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\
<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \
xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" \
xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" \
entity=\"%s\">\n\
<tuple id=\"sg89ae\">\n\
<status><basic>closed</basic></status>\n\
<contact priority=\"0.8\">%s</contact>\n\
</tuple>\n\
</presence>\n", contact_info, contact_info);
snprintf(buf, buflen, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" "
"xmlns:dm=\"urn:ietf:params:xml:ns:pidf:data-model\" "
"xmlns:rpid=\"urn:ietf:params:xml:ns:pidf:rpid\" "
"entity=\"%s\">\n"
"<tuple id=\"sg89ae\">\n"
"<status><basic>closed</basic></status>\n"
"<contact priority=\"0.8\">%s</contact>\n"
"</tuple>\n"
"</presence>\n", contact_info, contact_info);
}
break;
}

View file

@ -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);

View file

@ -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);

View file

@ -113,6 +113,7 @@
<object class="GtkTextView" id="textview">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="border_width">4</property>
</object>
</child>
</object>

View file

@ -216,10 +216,10 @@
<child>
<object class="GtkCheckButton" id="mtu_set">
<property name="label" translatable="yes">Set Maximum Transmission Unit:</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="linphone_gtk_mtu_set" swapped="no"/>
</object>
@ -256,10 +256,10 @@
<child>
<object class="GtkCheckButton" id="dtmf_sipinfo">
<property name="label" translatable="yes">Send DTMFs as SIP info</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="linphone_gtk_use_sip_info_dtmf_toggled" swapped="no"/>
</object>
@ -272,11 +272,11 @@
<child>
<object class="GtkCheckButton" id="ipv6_enabled">
<property name="label" translatable="yes">Use IPv6 instead of IPv4</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="linphone_gtk_ipv6_toggled" swapped="no"/>
</object>
@ -324,7 +324,7 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="n_rows">6</property>
<property name="n_rows">7</property>
<property name="n_columns">2</property>
<child>
<object class="GtkComboBox" id="proto_combo">
@ -364,7 +364,7 @@
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="bottom_attach">5</property>
</packing>
</child>
<child>
@ -380,30 +380,20 @@
<property name="bottom_attach">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="tunnel_label">
<property name="can_focus">False</property>
<property name="label" translatable="yes">Tunnel</property>
</object>
<packing>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
</packing>
</child>
<child>
<object class="GtkButton" id="tunnel_edit_button">
<property name="label">gtk-edit</property>
<property name="use_action_appearance">False</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="linphone_gtk_edit_tunnel" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
<property name="top_attach">6</property>
<property name="bottom_attach">7</property>
</packing>
</child>
<child>
@ -439,25 +429,25 @@
<property name="label" translatable="yes">DSCP fields</property>
</object>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
</packing>
</child>
<child>
<object class="GtkButton" id="dscp_edit_button">
<property name="label">gtk-edit</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="linphone_gtk_dscp_edit" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="top_attach">5</property>
<property name="bottom_attach">6</property>
</packing>
</child>
<child>
@ -506,10 +496,10 @@
<child>
<object class="GtkCheckButton" id="fixed_audio_port">
<property name="label" translatable="yes">Fixed</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="linphone_gtk_fixed_audio_port_toggle" swapped="no"/>
</object>
@ -573,10 +563,10 @@
<child>
<object class="GtkCheckButton" id="fixed_video_port">
<property name="label" translatable="yes">Fixed</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="linphone_gtk_fixed_video_port_toggle" swapped="no"/>
</object>
@ -594,6 +584,33 @@
<property name="bottom_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="tunnel_label">
<property name="can_focus">False</property>
<property name="label" translatable="yes">Tunnel</property>
</object>
<packing>
<property name="top_attach">6</property>
<property name="bottom_attach">7</property>
</packing>
</child>
<child>
<object class="GtkCheckButton" id="media_encryption_mandatory">
<property name="label" translatable="yes">Media encryption is mandatory</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="linphone_gtk_set_media_encryption_mandatory" swapped="no"/>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
</packing>
</child>
</object>
</child>
</object>
@ -628,10 +645,10 @@
<child>
<object class="GtkRadioButton" id="no_nat">
<property name="label" translatable="yes">Direct connection to the Internet</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="linphone_gtk_no_firewall_toggled" swapped="no"/>
@ -649,10 +666,10 @@
<child>
<object class="GtkRadioButton" id="use_nat_address">
<property name="label" translatable="yes">Behind NAT / Firewall (specify gateway IP below)</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">no_nat</property>
@ -717,10 +734,10 @@
<child>
<object class="GtkRadioButton" id="use_stun">
<property name="label" translatable="yes">Behind NAT / Firewall (use STUN to resolve)</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="draw_indicator">True</property>
<property name="group">no_nat</property>
<signal name="toggled" handler="linphone_gtk_use_stun_toggled" swapped="no"/>
@ -734,10 +751,10 @@
<child>
<object class="GtkRadioButton" id="use_ice">
<property name="label" translatable="yes">Behind NAT / Firewall (use ICE)</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="draw_indicator">True</property>
<property name="group">no_nat</property>
<signal name="toggled" handler="linphone_gtk_use_ice_toggled" swapped="no"/>
@ -875,9 +892,6 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="n_rows">6</property>
<property name="n_columns">2</property>
<child>
<placeholder/>
</child>
<child>
<object class="GtkHBox" id="ring_sound_box">
<property name="visible">True</property>
@ -899,11 +913,11 @@
<child>
<object class="GtkButton" id="play_ring">
<property name="label">gtk-media-play</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="linphone_gtk_play_ring_file" swapped="no"/>
</object>
@ -1076,10 +1090,10 @@
<child>
<object class="GtkCheckButton" id="echo_cancelation">
<property name="label" translatable="yes">Enable echo cancellation</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="linphone_gtk_echo_cancelation_toggled" swapped="no"/>
</object>
@ -1090,6 +1104,9 @@
<property name="bottom_attach">6</property>
</packing>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
@ -1425,10 +1442,10 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<object class="GtkButton" id="wizard">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="linphone_gtk_show_assistant" swapped="no"/>
<child>
<object class="GtkHBox" id="hbox5">
@ -1472,11 +1489,11 @@
</child>
<child>
<object class="GtkButton" id="add_proxy">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="linphone_gtk_add_proxy" swapped="no"/>
<child>
<object class="GtkHBox" id="hbox14">
@ -1520,11 +1537,11 @@
</child>
<child>
<object class="GtkButton" id="edit_proxy">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="linphone_gtk_edit_proxy" swapped="no"/>
<child>
<object class="GtkHBox" id="hbox16">
@ -1568,11 +1585,11 @@
</child>
<child>
<object class="GtkButton" id="remove_proxy">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="linphone_gtk_remove_proxy" swapped="no"/>
<child>
<object class="GtkHBox" id="hbox7">
@ -1661,11 +1678,11 @@
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<child>
<object class="GtkButton" id="erase_passwords">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="linphone_gtk_clear_passwords" swapped="no"/>
<child>
<object class="GtkHBox" id="hbox18">
@ -1847,11 +1864,11 @@
<child>
<object class="GtkButton" id="button4">
<property name="label">gtk-go-up</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="linphone_gtk_codec_up" swapped="no"/>
</object>
@ -1864,11 +1881,11 @@
<child>
<object class="GtkButton" id="up_codec">
<property name="label">gtk-go-down</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="linphone_gtk_codec_down" swapped="no"/>
</object>
@ -1880,11 +1897,11 @@
</child>
<child>
<object class="GtkButton" id="enable_codec">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="linphone_gtk_codec_enable" swapped="no"/>
<child>
<object class="GtkHBox" id="hbox8">
@ -1928,11 +1945,11 @@
</child>
<child>
<object class="GtkButton" id="disable_codec">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="linphone_gtk_codec_disable" swapped="no"/>
<child>
<object class="GtkHBox" id="hbox9">
@ -2095,10 +2112,10 @@
<child>
<object class="GtkCheckButton" id="adaptive_rate_control">
<property name="label" translatable="yes">Enable adaptive rate control</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="linphone_gtk_adaptive_rate_control_toggled" swapped="no"/>
@ -2124,7 +2141,7 @@
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
<property name="y_options"></property>
</packing>
</child>
</object>
@ -2250,10 +2267,10 @@
<child>
<object class="GtkCheckButton" id="ui_level">
<property name="label" translatable="yes">Show advanced settings</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="linphone_gtk_ui_level_toggled" swapped="no"/>
</object>
@ -2330,11 +2347,11 @@
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="button5">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
<property name="use_action_appearance">False</property>
<signal name="clicked" handler="linphone_gtk_parameters_closed" swapped="no"/>
<child>
<object class="GtkHBox" id="hbox3">

View file

@ -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);

View file

@ -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();
}

View file

@ -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.
*
* <pre>
* 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
* </pre>
* }
* @author Guillaume Beraudo
*/
public interface LpConfig {
/**
* Sets an integer config item
* @param key
*/
void setInt(String section, String key, int value);
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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])],
[],

@ -1 +1 @@
Subproject commit 6874ac86f173b5cf57b87e5ee529652ba6676295
Subproject commit d5811e376759433da3c19585b2d8d0329e1c06b2

View file

@ -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

View file

@ -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

233
tools/lpc2xml.c Normal file
View file

@ -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 <string.h>
#include <libxml/xmlsave.h>
#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;
}

46
tools/lpc2xml.h Normal file
View file

@ -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_

67
tools/lpc2xml_test.c Normal file
View file

@ -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 <stdio.h>
#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 <lpc_file> <xml_file>\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;
}

View file

@ -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) {