Commit c33fa844 authored by Simon Morlat's avatar Simon Morlat
Browse files

implement better system for "single instance application" requirement.

parent b6a5ffce
......@@ -682,12 +682,6 @@ static void subscribe_closed(SalOp *op, const char *from){
linphone_subscription_closed(lc,op);
}
static void internal_message(Sal *sal, const char *msg){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal);
if (lc->vtable.show)
lc->vtable.show(lc);
}
static void ping_reply(SalOp *op){
LinphoneCall *call=(LinphoneCall*) sal_op_get_user_pointer(op);
ms_message("ping reply !");
......@@ -723,7 +717,6 @@ SalCallbacks linphone_sal_callbacks={
notify_presence,
subscribe_received,
subscribe_closed,
internal_message,
ping_reply
};
......
......@@ -983,14 +983,6 @@ void *linphone_core_get_user_data(LinphoneCore *lc);
the config file with your own sections */
struct _LpConfig *linphone_core_get_config(LinphoneCore *lc);
/* attempts to wake up another linphone engine already running.
The "show" callback is called for the other linphone, causing gui to show up.
call_addr is an optional sip-uri to call immediately after waking up.
The method returns 0 if an already running linphone was found*/
int linphone_core_wake_up_possible_already_running_instance(
const char * config_file, const char * call_addr);
/*set a callback for some blocking operations, it takes you informed of the progress of the operation*/
void linphone_core_set_waiting_callback(LinphoneCore *lc, LinphoneWaitingCallback cb, void *user_context);
......
......@@ -557,89 +557,6 @@ void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){
}
}
static int extract_sip_port(const char *config){
char line[512];
char port[12];
int ret=-1;
FILE *f=fopen(config,"r");
if (f){
while(fgets(line,sizeof(line),f)!=NULL){
if (fmtp_get_value(line,"sip_port",port,sizeof(port))){
ret=atoi(port);
}
}
fclose(f);
}
return ret;
}
int linphone_core_wake_up_possible_already_running_instance(
const char * config_file, const char * addr_to_call)
{
int port=extract_sip_port(config_file);
const char *wakeup="WAKEUP sip:127.0.0.1 SIP/2.0\r\n"
"Via: SIP/2.0/UDP 127.0.0.1:%i;rport;branch=z9hG4bK%u\r\n"
"From: <sip:another_linphone@127.0.0.1>;tag=%u\r\n"
"To: <sip:you@127.0.0.1>\r\n"
"CSeq: 1 WAKEUP\r\n"
"Call-ID: %u@onsantape\r\n"
"Content-length: 0\r\n\r\n";
const char * call = "REFER sip:127.0.0.1 SIP/2.0\r\n"
"Via: SIP/2.0/UDP 127.0.0.1:%i;rport;branch=z9hG4bK%u\r\n"
"From: <sip:another_linphone@127.0.0.1>;tag=%u\r\n"
"To: <sip:you@127.0.0.1>\r\n"
"Refer-To: %s\r\n"
"CSeq: 1 WAKEUP\r\n"
"Call-ID: %u@onsantape\r\n"
"Content-length: 0\r\n\r\n";
/*make sure ortp is initialized (it initializes win32 socket api)*/
ortp_init();
if (port>0){
struct sockaddr_storage ss;
socklen_t sslen;
char tmp[100];
snprintf(tmp,sizeof(tmp),"127.0.0.1:%i",port);
if (parse_hostname_to_addr(tmp,&ss,&sslen)==0){
int locport=57123;
ortp_socket_t sock=create_socket(locport);
if (sock<0) sock=create_socket(++locport);
if (sock>=0){
char req[512];
if (addr_to_call != NULL)
snprintf(req, sizeof(req), call, locport,
random(), random(), addr_to_call, random());
else
snprintf(req, sizeof(req), wakeup, locport,
random(), random(), random());
if (connect(sock,(struct sockaddr*)&ss,sslen)<0){
fprintf(stderr,"connect failed: %s\n",getSocketError());
}else if (send(sock,req,strlen(req),0)>0){
/*wait a bit for a response*/
int i;
for(i=0;i<10;++i){
if (recv(sock,req,sizeof(req),0)>0){
close_socket(sock);
return 0;
}else if (getSocketErrorCode()!=EWOULDBLOCK){
break;
}
#ifdef WIN32
Sleep(100);
#else
usleep(100000);
#endif
}
}else{
ms_message("sendto() of WAKEUP request failed, nobody to wakeup.");
}
}
close_socket(sock);
}
}
return -1;
}
#ifdef HAVE_GETIFADDRS
#include <ifaddrs.h>
......
......@@ -219,7 +219,6 @@ typedef void (*SalOnNotify)(SalOp *op, const char *from, const char *value);
typedef void (*SalOnNotifyPresence)(SalOp *op, SalSubscribeState ss, SalPresenceStatus status, const char *msg);
typedef void (*SalOnSubscribeReceived)(SalOp *salop, const char *from);
typedef void (*SalOnSubscribeClosed)(SalOp *salop, const char *from);
typedef void (*SalOnInternalMsg)(Sal *sal, const char *msg);
typedef void (*SalOnPingReply)(SalOp *salop);
typedef struct SalCallbacks{
......@@ -243,7 +242,6 @@ typedef struct SalCallbacks{
SalOnNotifyPresence notify_presence;
SalOnSubscribeReceived subscribe_received;
SalOnSubscribeClosed subscribe_closed;
SalOnInternalMsg internal_message;
SalOnPingReply ping_reply;
}SalCallbacks;
......
......@@ -338,8 +338,6 @@ void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
ctx->callbacks.subscribe_received=(SalOnSubscribeReceived)unimplemented_stub;
if (ctx->callbacks.text_received==NULL)
ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
if (ctx->callbacks.internal_message==NULL)
ctx->callbacks.internal_message=(SalOnInternalMsg)unimplemented_stub;
if (ctx->callbacks.ping_reply==NULL)
ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
}
......@@ -1606,11 +1604,6 @@ static void other_request(Sal *sal, eXosip_event_t *ev){
eXosip_options_build_answer(ev->tid,200,&options);
fill_options_answer(options);
eXosip_options_send_answer(ev->tid,200,options);
}else if (strcmp(ev->request->sip_method,"WAKEUP")==0
&& comes_from_local_if(ev->request)) {
eXosip_message_send_answer(ev->tid,200,NULL);
ms_message("Receiving WAKEUP request !");
sal->callbacks.internal_message(sal,"WAKEUP");
}else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
ms_message("Receiving REFER request !");
if (comes_from_local_if(ev->request)) {
......
......@@ -44,6 +44,7 @@ linphone_SOURCES= \
setupwizard.c\
incall_view.c \
loginframe.c \
singleinstance.c \
linphone.h
linphone_LDADD=$(ORTP_LIBS) \
......
......@@ -72,8 +72,10 @@ void linphone_gtk_text_received(LinphoneCore *lc, LinphoneChatRoom *room, const
void linphone_gtk_call_log_update(GtkWidget *w);
void linphone_gtk_create_log_window(void);
void linphone_gtk_log_show(void);
void linphone_gtk_show_main_window(void);
void linphone_gtk_log_push(OrtpLogLevel lev, const char *fmt, va_list args);
void linphone_gtk_destroy_log_window(void);
void linphone_gtk_refer_received(LinphoneCore *lc, const char *refer_to);
gboolean linphone_gtk_check_logs();
void linphone_gtk_buddy_info_updated(LinphoneCore *lc, LinphoneFriend *lf);
const gchar *linphone_gtk_get_ui_config(const char *key, const char *def);
......@@ -112,4 +114,5 @@ void linphone_gtk_set_ui_config(const char *key, const char *value);
void linphone_gtk_log_uninit();
bool_t linphone_gtk_init_instance(const char *app_name, const char *addr_to_call);
void linphone_gtk_uninit_instance(void);
......@@ -57,7 +57,6 @@ static void linphone_gtk_display_message(LinphoneCore *lc, const char *msg);
static void linphone_gtk_display_warning(LinphoneCore *lc, const char *warning);
static void linphone_gtk_display_url(LinphoneCore *lc, const char *msg, const char *url);
static void linphone_gtk_call_log_updated(LinphoneCore *lc, LinphoneCallLog *cl);
static void linphone_gtk_refer_received(LinphoneCore *lc, const char *refer_to);
static void linphone_gtk_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cs, const char *msg);
static gboolean linphone_gtk_auto_answer(LinphoneCall *call);
static void linphone_gtk_status_icon_set_blinking(gboolean val);
......@@ -628,7 +627,7 @@ static void completion_add_text(GtkEntry *entry, const char *text){
}
static void linphone_gtk_show_main_window(){
void linphone_gtk_show_main_window(){
GtkWidget *w=linphone_gtk_get_main_window();
LinphoneCore *lc=linphone_gtk_get_core();
if (linphone_core_video_enabled(lc)){
......@@ -1506,7 +1505,7 @@ void linphone_gtk_log_handler(OrtpLogLevel lev, const char *fmt, va_list args){
}
static void linphone_gtk_refer_received(LinphoneCore *lc, const char *refer_to){
void linphone_gtk_refer_received(LinphoneCore *lc, const char *refer_to){
GtkEntry * uri_bar =GTK_ENTRY(linphone_gtk_get_widget(
linphone_gtk_get_main_window(), "uribar"));
char *text;
......@@ -1526,6 +1525,7 @@ static void linphone_gtk_check_soundcards(){
}
static void linphone_gtk_quit(void){
linphone_gtk_uninit_instance();
gdk_threads_leave();
linphone_gtk_destroy_log_window();
linphone_core_destroy(the_core);
......@@ -1559,6 +1559,7 @@ int main(int argc, char *argv[]){
const char *lang;
GtkSettings *settings;
GdkPixbuf *pbuf;
const char *app_name="Linphone";
g_thread_init(NULL);
gdk_threads_init();
......@@ -1566,6 +1567,7 @@ int main(int argc, char *argv[]){
progpath = strdup(argv[0]);
config_file=linphone_gtk_get_config_file();
#ifdef WIN32
/*workaround for windows: sometimes LANG is defined to an integer value, not understood by gtk */
......@@ -1627,9 +1629,7 @@ int main(int argc, char *argv[]){
the options, in case we needed to access the working directory */
factory_config_file = linphone_gtk_get_factory_config_file();
if (linphone_core_wake_up_possible_already_running_instance(
config_file, addr_to_call) == 0){
g_message("addr_to_call=%s",addr_to_call);
if (linphone_gtk_init_instance(app_name, addr_to_call) == FALSE){
g_warning("Another running instance of linphone has been detected. It has been woken-up.");
g_warning("This instance is going to exit now.");
gdk_threads_leave();
......@@ -1654,7 +1654,7 @@ int main(int argc, char *argv[]){
linphone_gtk_init_liblinphone(config_file, factory_config_file);
g_set_application_name(linphone_gtk_get_ui_config("title","Linphone"));
g_set_application_name(app_name);
pbuf=create_pixbuf(linphone_gtk_get_ui_config("icon",LINPHONE_ICON));
if (pbuf!=NULL) gtk_window_set_default_icon(pbuf);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment