actions.c 39.5 KB
Newer Older
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
1
/*
2
 *  Copyright (C) 2004, 2005, 2006, 2009, 2008, 2009, 2010 Savoir-Faire Linux Inc.
3
 *  Author: Emmanuel Milou <emmanuel.milou@savoirfairelinux.com>
4
 *  Author: Pierre-Luc Beaudoin <pierre-luc.beaudoin@savoirfairelinux.com>
Emmanuel Milou's avatar
Emmanuel Milou committed
5
 *
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
6 7
 *  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
8
 *  the Free Software Foundation; either version 3 of the License, or
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
9
 *  (at your option) any later version.
Emmanuel Milou's avatar
Emmanuel Milou committed
10
 *
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
11 12 13 14
 *  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.
Emmanuel Milou's avatar
Emmanuel Milou committed
15
 *
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
16 17 18
 *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
19 20 21 22 23 24 25 26 27 28 29
 *
 *  Additional permission under GNU GPL version 3 section 7:
 *
 *  If you modify this program, or any covered work, by linking or
 *  combining it with the OpenSSL project's OpenSSL library (or a
 *  modified version of that library), containing parts covered by the
 *  terms of the OpenSSL or SSLeay licenses, Savoir-Faire Linux Inc.
 *  grants you additional permission to convey the resulting work.
 *  Corresponding Source for a non-source form of such a combination
 *  shall include the source code for the parts of OpenSSL used as well
 *  as that of the covered work.
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
30
 */
31

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
32
#include <actions.h>
33
#include <dbus/dbus.h>
34
#include <statusicon.h>
Julien Bonjean's avatar
Julien Bonjean committed
35
#include <contacts/searchbar.h>
36
#include "icons/icon_factory.h"
37

38 39 40 41
#include <gtk/gtk.h>
#include <string.h>
#include <glib/gprintf.h>
#include <stdlib.h>
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
42 43 44
#include <sys/types.h>
#include <unistd.h>

45 46 47 48 49 50 51 52 53 54 55
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <linux/if.h>



56
GHashTable * ip2ip_profile=NULL;
57

Emmanuel Milou's avatar
Emmanuel Milou committed
58
    void
59
sflphone_notify_voice_mail (const gchar* accountID , guint count)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
60
{
61
    gchar *id;
62
    gchar *current_id;
63
    account_t *current;
Emmanuel Milou's avatar
Emmanuel Milou committed
64

65 66 67 68
    // We want to notify only the current account; ie the first in the list
    id = g_strdup (accountID);
    current_id = account_list_get_current_id ();

69 70
    DEBUG("sflphone_notify_voice_mail begin");

71
    if (g_strcasecmp (id, current_id) != 0 || account_list_get_size() == 0)
72 73
        return;

74 75 76 77 78 79
    // Set the number of voice messages for the current account
    current_account_set_message_number (count);
    current = account_list_get_current ();

    // Update the voicemail tool button
    update_voicemail_status ();
80

81 82
    if (current)
      notify_voice_mails (count, current);
Emmanuel Milou's avatar
Emmanuel Milou committed
83

84
    DEBUG("sflphone_notify_voice_mail end");
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
85 86
}

87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
/*
 * Place a call with the current account.
 * If there is no default account selected, place a call with the first
 * registered account of the account list
 * Else, check if it an IP call. if not, popup an error message
 */
 
static gboolean _is_direct_call(callable_obj_t * c) {

    if(g_strcasecmp(c->_accountID, EMPTY_ENTRY) == 0) {
        if(!g_str_has_prefix (c->_peer_number, "sip:")) {
            gchar * new_number = g_strconcat("sip:", c->_peer_number, NULL);
            g_free(c->_peer_number);
            c->_peer_number = new_number;
        }
        return 1;
    }

    if(g_str_has_prefix (c->_peer_number, "sip:")) {
        return 1;
    }

Alexandre Savard's avatar
Alexandre Savard committed
109 110 111 112
    if(g_str_has_prefix (c->_peer_number, "sips:")) {
        return 1;
    }

113 114 115 116
    return 0;
}


Emmanuel Milou's avatar
Emmanuel Milou committed
117
    void
118
status_bar_display_account ()
119
{
120
    gchar* msg;
121
    account_t* acc;
122 123 124

    statusbar_pop_message(__MSG_ACCOUNT_DEFAULT);

125 126
    DEBUG("status_bar_display_account begin");

127 128
    acc = account_list_get_current ();
    if(acc){
129
	status_tray_icon_online(TRUE);
130 131
        msg = g_markup_printf_escaped("%s %s (%s)" ,
                _("Using account"),
132 133
                (gchar*)g_hash_table_lookup( acc->properties , ACCOUNT_ALIAS),
                (gchar*)g_hash_table_lookup( acc->properties , ACCOUNT_TYPE));
Emmanuel Milou's avatar
Emmanuel Milou committed
134
    }
135 136
    else
    {
137
	status_tray_icon_online(FALSE);
138
        msg = g_markup_printf_escaped(_("No registered accounts"));
139 140 141
    }
    statusbar_push_message( msg , __MSG_ACCOUNT_DEFAULT);
    g_free(msg);
142 143

    DEBUG("status_bar_display_account_end");
144 145
}

Emmanuel Milou's avatar
Emmanuel Milou committed
146 147

    gboolean
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
148 149
sflphone_quit ()
{
Emmanuel Milou's avatar
Emmanuel Milou committed
150
    gboolean quit = FALSE;
Julien Bonjean's avatar
Julien Bonjean committed
151
    guint count = calllist_get_size(current_calls);
Emmanuel Milou's avatar
Emmanuel Milou committed
152 153 154 155 156 157 158 159 160
    if(count > 0){
        quit = main_window_ask_quit();
    }
    else{
        quit = TRUE;
    }

    if (quit)
    {
161 162 163
        // Save the history 
        sflphone_save_history ();

Emmanuel Milou's avatar
Emmanuel Milou committed
164 165 166 167 168 169 170
        dbus_unregister(getpid());
        dbus_clean ();
        //call_list_clean(); TODO
        //account_list_clean()
        gtk_main_quit ();
    }
    return quit;
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
171 172
}

Emmanuel Milou's avatar
Emmanuel Milou committed
173
    void
174
sflphone_hold (callable_obj_t * c )
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
175
{
176
    c->_state = CALL_STATE_HOLD;
177
    calltree_update_call(current_calls, c, NULL);
178
    update_actions();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
179 180
}

Emmanuel Milou's avatar
Emmanuel Milou committed
181
    void
182
sflphone_ringing(callable_obj_t * c )
183
{
184
    c->_state = CALL_STATE_RINGING;
185
    calltree_update_call(current_calls, c, NULL);
186
    update_actions();
187
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
188

Emmanuel Milou's avatar
Emmanuel Milou committed
189
    void
190
sflphone_hung_up( callable_obj_t * c)
Emmanuel Milou's avatar
Emmanuel Milou committed
191
{
192 193
    DEBUG("Actions: SFLphone hungup");

194
    calllist_remove( current_calls, c->_callID);
195
    calltree_remove_call(current_calls, c, NULL);
196
    c->_state = CALL_STATE_DIALING;
197
    call_remove_all_errors(c);
198
    update_actions();
199
#if GTK_CHECK_VERSION(2,10,0)
Emmanuel Milou's avatar
Emmanuel Milou committed
200
    status_tray_icon_blink( FALSE );
201
#endif
202
    free_callable_obj_t(c);
Emmanuel Milou's avatar
Emmanuel Milou committed
203 204
}

205 206
static hashtable_free(gpointer key, gpointer value, gpointer user_data)
{
207
    g_free(key);
208 209 210
    g_free(value);
}

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
211
/** Internal to actions: Fill account list */
Emmanuel Milou's avatar
Emmanuel Milou committed
212
void sflphone_fill_account_list (void) {
213 214 215 216

    gchar** array;
    gchar** accountID;
    unsigned int i;
217 218
    int count;
    GQueue *codeclist;
219

220 221 222
    DEBUG("SFLphone: Fill account list");
    
    count = current_account_get_message_number ();
223

Emmanuel Milou's avatar
Emmanuel Milou committed
224
    account_list_clear ();
225

Emmanuel Milou's avatar
Emmanuel Milou committed
226
    array = (gchar **)dbus_account_list();
227 228
    if(array)
    {
229 230 231 232
      /*
        if(!(*accountID))
	  DEBUG("hhhhhhhhhmmmmmmmmmmmm");
      */
233
      
Emmanuel Milou's avatar
Emmanuel Milou committed
234 235 236 237
        for (accountID = array; *accountID; accountID++)
        {
            account_t * a = g_new0(account_t,1);
            a->accountID = g_strdup(*accountID);
238
	    DEBUG("------------------- Account ID %s", a->accountID);
239
            a->credential_information = NULL;
Emmanuel Milou's avatar
Emmanuel Milou committed
240
			// TODO Clean codec list QUEUE
Emmanuel Milou's avatar
Emmanuel Milou committed
241 242 243
            account_list_add(a);
        }
        g_strfreev (array);
244
    }
245

Emmanuel Milou's avatar
Emmanuel Milou committed
246 247 248 249
    for( i = 0; i < account_list_get_size(); i++)
    {
        account_t  * a = account_list_get_nth (i);
        GHashTable * details = (GHashTable *) dbus_account_details(a->accountID);
250 251
        if( details == NULL )
            break;
Emmanuel Milou's avatar
Emmanuel Milou committed
252
        a->properties = details;
253
                        
254 255 256
        /* As this function might be called numberous time, we should free the 
         * previously allocated space to avoid memory leaks.
         */
257 258 259 260 261 262

        /* Fill the actual array of credentials */
        int number_of_credential = dbus_get_number_of_credential(a->accountID);
        if(number_of_credential) {
            a->credential_information = g_ptr_array_new();
        } else {
263 264 265
            a->credential_information = NULL;
        }
        
266
        int credential_index;
267
        for(credential_index = 0; credential_index < number_of_credential; credential_index++) {
268
            GHashTable * credential_information = dbus_get_credential (a->accountID, credential_index);
269
            g_ptr_array_add(a->credential_information, credential_information);
270
        }
Emmanuel Milou's avatar
Emmanuel Milou committed
271

272
        gchar * status = g_hash_table_lookup(details, REGISTRATION_STATUS);
Emmanuel Milou's avatar
Emmanuel Milou committed
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308
        if(strcmp(status, "REGISTERED") == 0)
        {
            a->state = ACCOUNT_STATE_REGISTERED;
        }
        else if(strcmp(status, "UNREGISTERED") == 0)
        {
            a->state = ACCOUNT_STATE_UNREGISTERED;
        }
        else if(strcmp(status, "TRYING") == 0)
        {
            a->state = ACCOUNT_STATE_TRYING;
        }
        else if(strcmp(status, "ERROR") == 0)
        {
            a->state = ACCOUNT_STATE_ERROR;
        }
        else if(strcmp( status , "ERROR_AUTH") == 0 )
        {
            a->state = ACCOUNT_STATE_ERROR_AUTH;
        }
        else if(strcmp( status , "ERROR_NETWORK") == 0 )
        {
            a->state = ACCOUNT_STATE_ERROR_NETWORK;
        }
        else if(strcmp( status , "ERROR_HOST") == 0 )
        {
            a->state = ACCOUNT_STATE_ERROR_HOST;
        }
        else if(strcmp( status , "ERROR_CONF_STUN") == 0 )
        {
            a->state = ACCOUNT_STATE_ERROR_CONF_STUN;
        }
        else if(strcmp( status , "ERROR_EXIST_STUN") == 0 )
        {
            a->state = ACCOUNT_STATE_ERROR_EXIST_STUN;
        }
309 310 311
		else if (strcmp (status, "READY") == 0) {
			a->state = IP2IP_PROFILE_STATUS;
		}
Emmanuel Milou's avatar
Emmanuel Milou committed
312 313 314 315 316
        else
        {
            a->state = ACCOUNT_STATE_INVALID;
        }

317 318 319 320 321 322 323
        gchar * code = NULL;
        code = g_hash_table_lookup(details, REGISTRATION_STATE_CODE);
        if (code != NULL) {
            a->protocol_state_code = atoi(code);
        }
        g_free(a->protocol_state_description);
        a->protocol_state_description = g_hash_table_lookup(details, REGISTRATION_STATE_DESCRIPTION);
Emmanuel Milou's avatar
Emmanuel Milou committed
324 325
    }

326 327 328 329
    // Set the current account message number
    current_account_set_message_number (count);
    
    sflphone_fill_codec_list ();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
330 331
}

Emmanuel Milou's avatar
Emmanuel Milou committed
332 333
gboolean sflphone_init() {

Emmanuel Milou's avatar
Emmanuel Milou committed
334 335 336 337 338 339 340 341
    if(!dbus_connect ()){

        main_window_error_message(_("Unable to connect to the SFLphone server.\nMake sure the daemon is running."));
        return FALSE;
    }
    else
    {
        dbus_register(getpid(), "Gtk+ Client");
342

343 344 345
		// Init icons factory
		init_icon_factory ();

346 347 348
        current_calls = calltab_init(FALSE, CURRENT_CALLS);
        contacts = calltab_init(TRUE, CONTACTS);
        history = calltab_init(TRUE, HISTORY);
349

Emmanuel Milou's avatar
Emmanuel Milou committed
350
        account_list_init ();
351
        codec_capabilities_load ();
Emmanuel Milou's avatar
Emmanuel Milou committed
352
		conferencelist_init ();
353

354
        // Fetch the configured accounts
Emmanuel Milou's avatar
Emmanuel Milou committed
355
        sflphone_fill_account_list ();
356

357 358 359
        // Fetch the ip2ip profile 
        sflphone_fill_ip2ip_profile();
        
360
		// Fetch the conference list
361
		// sflphone_fill_conference_list();
362

Emmanuel Milou's avatar
Emmanuel Milou committed
363 364
        return TRUE;
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
365 366
}

367 368 369 370 371
void sflphone_fill_ip2ip_profile(void)
{
    ip2ip_profile = (GHashTable *) dbus_get_ip2_ip_details();
}

Emmanuel Milou's avatar
Emmanuel Milou committed
372
void sflphone_get_ip2ip_properties (GHashTable **properties)
373
{
Emmanuel Milou's avatar
Emmanuel Milou committed
374
	*properties	= ip2ip_profile;
375 376
}

Emmanuel Milou's avatar
Emmanuel Milou committed
377
    void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
378
sflphone_hang_up()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
379
{
380
    callable_obj_t * selectedCall = calltab_get_selected_call(current_calls);
381 382
    conference_obj_t * selectedConf = calltab_get_selected_conf(active_calltree);

Emmanuel Milou's avatar
Emmanuel Milou committed
383 384
    if(selectedCall)
    {
385
        switch(selectedCall->_state)
Emmanuel Milou's avatar
Emmanuel Milou committed
386 387 388 389 390 391
        {
            case CALL_STATE_DIALING:
                dbus_hang_up (selectedCall);
                break;
            case CALL_STATE_RINGING:
                dbus_hang_up (selectedCall);
392
                call_remove_all_errors(selectedCall);
393 394
                selectedCall->_state = CALL_STATE_DIALING;
                //selectedCall->_stop = 0;
Emmanuel Milou's avatar
Emmanuel Milou committed
395 396 397 398
                break;
            case CALL_STATE_CURRENT:
            case CALL_STATE_HOLD:
            case CALL_STATE_BUSY:
399
            case CALL_STATE_RECORD:
Emmanuel Milou's avatar
Emmanuel Milou committed
400
                dbus_hang_up (selectedCall);
401
                call_remove_all_errors(selectedCall);
402
                selectedCall->_state = CALL_STATE_DIALING;
403
                set_timestamp (&selectedCall->_time_stop);
Emmanuel Milou's avatar
Emmanuel Milou committed
404 405 406
                break;
            case CALL_STATE_FAILURE:
                dbus_hang_up (selectedCall);
407
                call_remove_all_errors(selectedCall);
408
                selectedCall->_state = CALL_STATE_DIALING;
Emmanuel Milou's avatar
Emmanuel Milou committed
409 410 411
                break;
            case CALL_STATE_INCOMING:
                dbus_refuse (selectedCall);
412
                call_remove_all_errors(selectedCall);
413
                selectedCall->_state = CALL_STATE_DIALING;
414
                DEBUG("from sflphone_hang_up : "); stop_notification();
Emmanuel Milou's avatar
Emmanuel Milou committed
415 416 417
                break;
            case CALL_STATE_TRANSFERT:
                dbus_hang_up (selectedCall);
418
                call_remove_all_errors(selectedCall);
419
                set_timestamp (&selectedCall->_time_stop);
Emmanuel Milou's avatar
Emmanuel Milou committed
420 421
                break;
            default:
422
                WARN("Should not happen in sflphone_hang_up()!");
Emmanuel Milou's avatar
Emmanuel Milou committed
423 424 425
                break;
        }
    }
426 427 428 429
    else if(selectedConf) {
        dbus_hang_up_conference(selectedConf);
    }

430
    calltree_update_call(history, selectedCall, NULL);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
431 432 433
}


Alexandre Savard's avatar
Alexandre Savard committed
434 435 436 437 438 439 440 441 442 443
void
sflphone_conference_hang_up()
{
    conference_obj_t * selectedConf = calltab_get_selected_conf();

    if(selectedConf)
	dbus_hang_up_conference(selectedConf);
}


Emmanuel Milou's avatar
Emmanuel Milou committed
444
    void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
445 446
sflphone_pick_up()
{
Alexandre Savard's avatar
Alexandre Savard committed
447
    DEBUG("sflphone_pick_up\n");
448 449 450
    callable_obj_t * selectedCall = NULL;
    selectedCall = calltab_get_selected_call(active_calltree);
    
Emmanuel Milou's avatar
Emmanuel Milou committed
451 452
    if(selectedCall)
    {
453
        switch(selectedCall->_state)
Emmanuel Milou's avatar
Emmanuel Milou committed
454 455 456 457 458
        {
            case CALL_STATE_DIALING:
                sflphone_place_call (selectedCall);
                break;
            case CALL_STATE_INCOMING:
459
                selectedCall->_history_state = INCOMING;
460
                calltree_update_call( history, selectedCall, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
461
                dbus_accept (selectedCall);
462
                DEBUG("from sflphone_pick_up : "); stop_notification();
Emmanuel Milou's avatar
Emmanuel Milou committed
463 464 465 466 467 468
                break;
            case CALL_STATE_HOLD:
                sflphone_new_call();
                break;
            case CALL_STATE_TRANSFERT:
                dbus_transfert (selectedCall);
469
                set_timestamp (&selectedCall->_time_stop);
Emmanuel Milou's avatar
Emmanuel Milou committed
470 471 472 473 474 475 476 477 478
                break;
            case CALL_STATE_CURRENT:
            case CALL_STATE_RECORD:
                sflphone_new_call();
                break;
            case CALL_STATE_RINGING:
                sflphone_new_call();
                break;
            default:
479
                WARN("Should not happen in sflphone_pick_up()!");
Emmanuel Milou's avatar
Emmanuel Milou committed
480 481 482
                break;
        }
    }
483 484 485
    else {
        sflphone_new_call();
    }
486

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
487 488
}

Emmanuel Milou's avatar
Emmanuel Milou committed
489
    void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
490 491
sflphone_on_hold ()
{
492
    callable_obj_t * selectedCall = calltab_get_selected_call(current_calls);
493 494 495
    conference_obj_t * selectedConf = calltab_get_selected_conf(active_calltree);

    DEBUG("sflphone_on_hold");
Emmanuel Milou's avatar
Emmanuel Milou committed
496 497
    if(selectedCall)
    {
498
        switch(selectedCall->_state)
Emmanuel Milou's avatar
Emmanuel Milou committed
499 500 501 502 503 504 505 506 507
        {
            case CALL_STATE_CURRENT:
                dbus_hold (selectedCall);
                break;
            case CALL_STATE_RECORD:
                dbus_hold (selectedCall);
                break;

            default:
508
                WARN("Should not happen in sflphone_on_hold!");
Emmanuel Milou's avatar
Emmanuel Milou committed
509 510 511
                break;
        }
    }
512 513 514
    else if (selectedConf) {
        dbus_hold_conference(selectedConf);
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
515 516
}

Emmanuel Milou's avatar
Emmanuel Milou committed
517
    void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
518 519
sflphone_off_hold ()
{
520
    DEBUG("sflphone_off_hold");
521
    callable_obj_t * selectedCall = calltab_get_selected_call(current_calls);
522 523
    conference_obj_t * selectedConf = calltab_get_selected_conf(active_calltree);

Emmanuel Milou's avatar
Emmanuel Milou committed
524 525
    if(selectedCall)
    {
526
        switch(selectedCall->_state)
Emmanuel Milou's avatar
Emmanuel Milou committed
527 528 529 530 531
        {
            case CALL_STATE_HOLD:
                dbus_unhold (selectedCall);
                break;
            default:
532
                WARN("Should not happen in sflphone_off_hold ()!");
Emmanuel Milou's avatar
Emmanuel Milou committed
533 534 535
                break;
        }
    }
536
    else if (selectedConf) {
Julien Bonjean's avatar
Julien Bonjean committed
537

538 539 540
        
        dbus_unhold_conference(selectedConf);
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
541 542 543
}


Emmanuel Milou's avatar
Emmanuel Milou committed
544
    void
545
sflphone_fail( callable_obj_t * c )
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
546
{
547
    c->_state = CALL_STATE_FAILURE;
548
    calltree_update_call(current_calls, c, NULL);
549
    update_actions();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
550 551
}

Emmanuel Milou's avatar
Emmanuel Milou committed
552
    void
553
sflphone_busy( callable_obj_t * c )
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
554
{
555
    c->_state = CALL_STATE_BUSY;
556
    calltree_update_call(current_calls, c, NULL);
557
    update_actions();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
558 559
}

Emmanuel Milou's avatar
Emmanuel Milou committed
560
    void
561
sflphone_current( callable_obj_t * c )
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
562
{
563

564 565
    if( c->_state != CALL_STATE_HOLD )
        set_timestamp (&c->_time_start);
566
    c->_state = CALL_STATE_CURRENT;
567
    calltree_update_call(current_calls, c, NULL);
568
    update_actions();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
569 570
}

Emmanuel Milou's avatar
Emmanuel Milou committed
571
    void
572
sflphone_record( callable_obj_t * c )
alexandresavard's avatar
alexandresavard committed
573
{
574
    if( c->_state != CALL_STATE_HOLD )
575
      set_timestamp (&c->_time_start);
576
    c->_state = CALL_STATE_RECORD;
577
    calltree_update_call(current_calls, c, NULL);
578
    update_actions();
alexandresavard's avatar
alexandresavard committed
579 580
}

Emmanuel Milou's avatar
Emmanuel Milou committed
581
    void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
582
sflphone_set_transfert()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
583
{
584
    callable_obj_t * c = calltab_get_selected_call(current_calls);
Emmanuel Milou's avatar
Emmanuel Milou committed
585 586
    if(c)
    {
587
        c->_state = CALL_STATE_TRANSFERT;
588
        c->_trsft_to = g_strdup("");
589
        calltree_update_call(current_calls, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
590
    }
591
    update_actions();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
592 593
}

Emmanuel Milou's avatar
Emmanuel Milou committed
594
    void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
595 596
sflphone_unset_transfert()
{
597
    callable_obj_t * c = calltab_get_selected_call(current_calls);
Emmanuel Milou's avatar
Emmanuel Milou committed
598 599
    if(c)
    {
600
        c->_state = CALL_STATE_CURRENT;
601
        c->_trsft_to = g_strdup("");
602
        calltree_update_call(current_calls, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
603
    }
604
    update_actions();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
605
}
Emmanuel Milou's avatar
Emmanuel Milou committed
606

607
    void
608 609 610 611 612
sflphone_display_transfer_status(const gchar* message)
{
    statusbar_push_message( message , __MSG_ACCOUNT_DEFAULT);
}

Emmanuel Milou's avatar
Emmanuel Milou committed
613
    void
614
sflphone_incoming_call (callable_obj_t * c)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
615
{
616 617
	gchar *msg = "";

618
    c->_history_state = MISSED;
Julien Bonjean's avatar
Julien Bonjean committed
619 620
    calllist_add ( current_calls, c );
    calllist_add( history, c );
621
    calltree_add_call( current_calls, c, NULL);
622
    update_actions();
Julien Bonjean's avatar
Julien Bonjean committed
623
    calltree_display (current_calls);
624 625 626 627 628 629 630 631
	
	// Change the status bar if we are dealing with a direct SIP call
    if(_is_direct_call(c)) {
		msg = g_markup_printf_escaped (_("Direct SIP call"));
        statusbar_pop_message(__MSG_ACCOUNT_DEFAULT);
        statusbar_push_message( msg , __MSG_ACCOUNT_DEFAULT);
        g_free(msg);
	}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
632
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
633

Emmanuel Milou's avatar
Emmanuel Milou committed
634
    void
635
process_dialing(callable_obj_t * c, guint keyval, gchar * key)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
636
{
Emmanuel Milou's avatar
Emmanuel Milou committed
637
    // We stop the tone
638
    if(strlen(c->_peer_number) == 0 && c->_state != CALL_STATE_TRANSFERT){
Emmanuel Milou's avatar
Emmanuel Milou committed
639 640 641
        dbus_start_tone( FALSE , 0 );
        //dbus_play_dtmf( key );
    }
642

643 644
    DEBUG("process_dialing : keyval : %i",keyval);
    DEBUG("process_dialing : key : %s",key);
Emmanuel Milou's avatar
Emmanuel Milou committed
645 646 647 648 649 650 651 652 653 654 655 656

    switch (keyval)
    {
        case 65293: /* ENTER */
        case 65421: /* ENTER numpad */
            sflphone_place_call(c);
            break;
        case 65307: /* ESCAPE */
            sflphone_hang_up(c);
            break;
        case 65288: /* BACKSPACE */
            {  /* Brackets mandatory because of local vars */
657 658
                gchar * before = c->_peer_number;
                if(strlen(c->_peer_number) >= 1){
Emmanuel Milou's avatar
Emmanuel Milou committed
659

660 661
					if (c->_state == CALL_STATE_TRANSFERT)
					{
662 663 664
                                                // Process backspace if and only if string not NULL
                                                if(strlen(c->_trsft_to) > 0)
                                                     c->_trsft_to = g_strndup (c->_trsft_to, strlen(c->_trsft_to) - 1);
665 666 667 668 669 670
					}
					else
					{
						c->_peer_number = g_strndup(c->_peer_number, strlen(c->_peer_number) -1);
						g_free(before);
						DEBUG("TO: backspace %s", c->_peer_number);
Emmanuel Milou's avatar
Emmanuel Milou committed
671
                    }
672
					calltree_update_call(current_calls, c, NULL);
Julien Bonjean's avatar
Julien Bonjean committed
673
                }
674
                else if(strlen(c->_peer_number) == 0)
Emmanuel Milou's avatar
Emmanuel Milou committed
675
                {
676
                    if(c->_state != CALL_STATE_TRANSFERT)
Emmanuel Milou's avatar
Emmanuel Milou committed
677 678 679 680 681 682 683 684 685 686 687 688 689
                        dbus_hang_up(c);
                }
            }
            break;
        case 65289: /* TAB */
        case 65513: /* ALT */
        case 65507: /* CTRL */
        case 65515: /* SUPER */
        case 65509: /* CAPS */
            break;
        default:
            // if (keyval < 255 || (keyval >65453 && keyval < 65466))
            if (keyval < 127 || (keyval > 65400 && keyval < 65466))
Julien Bonjean's avatar
Julien Bonjean committed
690
            {
Emmanuel Milou's avatar
Emmanuel Milou committed
691

692 693 694 695 696 697
                if (c->_state == CALL_STATE_TRANSFERT)
                {
                    c->_trsft_to = g_strconcat(c->_trsft_to, key, NULL);
                }
                else
                {
Emmanuel Milou's avatar
Emmanuel Milou committed
698
                    dbus_play_dtmf( key );
699 700
                    c->_peer_number = g_strconcat(c->_peer_number, key, NULL);
                }
Emmanuel Milou's avatar
Emmanuel Milou committed
701

702
                if(c->_state == CALL_STATE_DIALING)
Emmanuel Milou's avatar
Emmanuel Milou committed
703
                {
704 705
                    //g_free(c->_peer_name);
                    //c->_peer_name = g_strconcat("\"\" <", c->_peer_number, ">", NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
706
                }
707
                calltree_update_call(current_calls, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
708 709 710
            }
            break;
    }
711 712
}

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
713

714
    callable_obj_t *
areversat's avatar
areversat committed
715
sflphone_new_call()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
716
{
Julien Bonjean's avatar
Julien Bonjean committed
717

718
    callable_obj_t *c;
719
    callable_obj_t * current_selected_call;
720
    gchar *peer_name, *peer_number;
721

722
    DEBUG("sflphone_new_call");
723 724 725

    current_selected_call = calltab_get_selected_call(current_calls);

726
    if ((current_selected_call != NULL) && (current_selected_call->_confID == NULL))
727
	sflphone_on_hold();
728

Emmanuel Milou's avatar
Emmanuel Milou committed
729
    // Play a tone when creating a new call
Julien Bonjean's avatar
Julien Bonjean committed
730
    if( calllist_get_size(current_calls) == 0 )
731
        dbus_start_tone( TRUE , (current_account_has_new_message ()  > 0)? TONE_WITH_MESSAGE : TONE_WITHOUT_MESSAGE) ;
Emmanuel Milou's avatar
Emmanuel Milou committed
732

733 734 735
    peer_number = g_strdup("");
    peer_name = g_strdup ("");
    create_new_call (CALL, CALL_STATE_DIALING, "", "", peer_name, peer_number, &c);
Emmanuel Milou's avatar
Emmanuel Milou committed
736

737 738
    c->_history_state = OUTGOING;

739
    calllist_add (current_calls,c);
740
    calltree_add_call (current_calls, c, NULL);
741
    update_actions();
742

Emmanuel Milou's avatar
Emmanuel Milou committed
743
    return c;
744 745
}

areversat's avatar
areversat committed
746

Emmanuel Milou's avatar
Emmanuel Milou committed
747
    void
areversat's avatar
areversat committed
748 749
sflphone_keypad( guint keyval, gchar * key)
{
750
    callable_obj_t * c = calltab_get_selected_call(current_calls);
Emmanuel Milou's avatar
Emmanuel Milou committed
751 752 753

    if((active_calltree != current_calls) || (active_calltree == current_calls && !c))
    {
754
        DEBUG("Not in a call, not dialing, create a new call");
Emmanuel Milou's avatar
Emmanuel Milou committed
755 756 757 758 759 760 761 762
        //dbus_play_dtmf(key);
        switch (keyval)
        {
            case 65293: /* ENTER */
            case 65421: /* ENTER numpad */
            case 65307: /* ESCAPE */
                break;
            default:
Julien Bonjean's avatar
Julien Bonjean committed
763
                calltree_display (current_calls);
Emmanuel Milou's avatar
Emmanuel Milou committed
764 765 766 767 768 769
                process_dialing(sflphone_new_call(), keyval, key);
                break;
        }
    }
    else if(c)
    {
770
        DEBUG("Call is non-zero");
771
        switch(c->_state)
Emmanuel Milou's avatar
Emmanuel Milou committed
772 773
        {
            case CALL_STATE_DIALING: // Currently dialing => edit number
774
                DEBUG("Writing a number");
Emmanuel Milou's avatar
Emmanuel Milou committed
775 776 777 778 779 780 781 782
                process_dialing(c, keyval, key);
                break;
            case CALL_STATE_RECORD:
            case CALL_STATE_CURRENT:
                switch (keyval)
                {
                    case 65307: /* ESCAPE */
                        dbus_hang_up(c);
783
                        set_timestamp (&c->_time_stop);
784
                        calltree_update_call(history, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
785 786 787 788 789 790 791 792 793 794 795
                        break;
                    default:
                        // To play the dtmf when calling mail box for instance
                        dbus_play_dtmf(key);
                        if (keyval < 255 || (keyval >65453 && keyval < 65466))
                        {
                            //gchar * temp = g_strconcat(call_get_number(c), key, NULL);
                            //gchar * before = c->from;
                            //c->from = g_strconcat("\"",call_get_name(c) ,"\" <", temp, ">", NULL);
                            //g_free(before);
                            //g_free(temp);
796
                            //update_callable_obj_tree(current_calls,c);
Emmanuel Milou's avatar
Emmanuel Milou committed
797 798 799 800 801 802 803 804 805
                        }
                        break;
                }
                break;
            case CALL_STATE_INCOMING:
                switch (keyval)
                {
                    case 65293: /* ENTER */
                    case 65421: /* ENTER numpad */
806
                        c->_history_state = INCOMING;
807
                        calltree_update_call(history, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
808
                        dbus_accept(c);
809
                        DEBUG("from sflphone_keypad ( enter ) : "); stop_notification();
Emmanuel Milou's avatar
Emmanuel Milou committed
810 811 812
                        break;
                    case 65307: /* ESCAPE */
                        dbus_refuse(c);
813
                        DEBUG("from sflphone_keypad ( escape ) : "); stop_notification();
Emmanuel Milou's avatar
Emmanuel Milou committed
814 815 816 817 818 819 820 821 822
                        break;
                }
                break;
            case CALL_STATE_TRANSFERT:
                switch (keyval)
                {
                    case 65293: /* ENTER */
                    case 65421: /* ENTER numpad */
                        dbus_transfert(c);
823
                        set_timestamp (&c->_time_stop);
Emmanuel Milou's avatar
Emmanuel Milou committed
824 825 826 827
                        break;
                    case 65307: /* ESCAPE */
                        sflphone_unset_transfert(c);
                        break;
828
                    default: // When a call is on transfert, typing new numbers will add it to c->_peer_number
Emmanuel Milou's avatar
Emmanuel Milou committed
829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850
                        process_dialing(c, keyval, key);
                        break;
                }
                break;
            case CALL_STATE_HOLD:
                switch (keyval)
                {
                    case 65293: /* ENTER */
                    case 65421: /* ENTER numpad */
                        dbus_unhold(c);
                        break;
                    case 65307: /* ESCAPE */
                        dbus_hang_up(c);
                        break;
                    default: // When a call is on hold, typing new numbers will create a new call
                        process_dialing(sflphone_new_call(), keyval, key);
                        break;
                }
                break;
            case CALL_STATE_RINGING:
            case CALL_STATE_BUSY:
            case CALL_STATE_FAILURE:
851
                //c->_stop = 0;
Emmanuel Milou's avatar
Emmanuel Milou committed
852 853 854 855
                switch (keyval)
                {
                    case 65307: /* ESCAPE */
                        dbus_hang_up(c);
856
                        //c->_stop = 0;
857
                        calltree_update_call(history, c, NULL);