actions.c 36.7 KB
Newer Older
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
1
/*
2
 *  Copyright (C) 2007 - 2008 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
19
 *  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.
 */
20

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
21
#include <actions.h>
22
#include <dbus/dbus.h>
23
#include <statusicon.h>
Julien Bonjean's avatar
Julien Bonjean committed
24
#include <contacts/searchbar.h>
25
#include "icons/icon_factory.h"
26

27
28
29
30
#include <gtk/gtk.h>
#include <string.h>
#include <glib/gprintf.h>
#include <stdlib.h>
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
31
32
33
#include <sys/types.h>
#include <unistd.h>

34
GHashTable * ip2ip_profile=NULL;
35

Emmanuel Milou's avatar
Emmanuel Milou committed
36
    void
37
sflphone_notify_voice_mail (const gchar* accountID , guint count)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
38
{
39
    gchar *id;
40
41
    gchar *current_id;
	account_t *current;
Emmanuel Milou's avatar
Emmanuel Milou committed
42

43
44
45
46
47
    // 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 ();

    if (g_strcasecmp (id, current_id) != 0 || account_list_get_size() == 0)
48
49
        return;

50
51
52
	// Set the number of voice messages for the current account
	current_account_set_message_number (count);
	current = account_list_get_current ();
53

54
55
	// Update the voicemail tool button
	update_voicemail_status ();
Emmanuel Milou's avatar
Emmanuel Milou committed
56

57
58
	if (current)
		notify_voice_mails (count, current);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
59
60
}

61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
/*
 * 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
83
84
85
86
    if(g_str_has_prefix (c->_peer_number, "sips:")) {
        return 1;
    }

87
88
89
90
    return 0;
}


Emmanuel Milou's avatar
Emmanuel Milou committed
91
    void
92
status_bar_display_account ()
93
{
94
    gchar* msg;
95
    account_t* acc;
96
97
98
99
100

    statusbar_pop_message(__MSG_ACCOUNT_DEFAULT);

    acc = account_list_get_current ();
    if(acc){
101
	status_tray_icon_online(TRUE);
102
103
        msg = g_markup_printf_escaped("%s %s (%s)" ,
                _("Using account"),
104
105
                (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
106
    }
107
108
    else
    {
109
	status_tray_icon_online(FALSE);
110
        msg = g_markup_printf_escaped(_("No registered accounts"));
111
112
113
    }
    statusbar_push_message( msg , __MSG_ACCOUNT_DEFAULT);
    g_free(msg);
114
115
}

Emmanuel Milou's avatar
Emmanuel Milou committed
116
117

    gboolean
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
118
119
sflphone_quit ()
{
Emmanuel Milou's avatar
Emmanuel Milou committed
120
    gboolean quit = FALSE;
Julien Bonjean's avatar
Julien Bonjean committed
121
    guint count = calllist_get_size(current_calls);
Emmanuel Milou's avatar
Emmanuel Milou committed
122
123
124
125
126
127
128
129
130
    if(count > 0){
        quit = main_window_ask_quit();
    }
    else{
        quit = TRUE;
    }

    if (quit)
    {
131
132
133
        // Save the history 
        sflphone_save_history ();

Emmanuel Milou's avatar
Emmanuel Milou committed
134
135
136
137
138
139
140
        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
141
142
}

Emmanuel Milou's avatar
Emmanuel Milou committed
143
    void
144
sflphone_hold (callable_obj_t * c )
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
145
{
146
    c->_state = CALL_STATE_HOLD;
147
    calltree_update_call(current_calls, c, NULL);
148
    update_actions();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
149
150
}

Emmanuel Milou's avatar
Emmanuel Milou committed
151
    void
152
sflphone_ringing(callable_obj_t * c )
153
{
154
    c->_state = CALL_STATE_RINGING;
155
    calltree_update_call(current_calls, c, NULL);
156
    update_actions();
157
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
158

Emmanuel Milou's avatar
Emmanuel Milou committed
159
    void
160
sflphone_hung_up( callable_obj_t * c)
Emmanuel Milou's avatar
Emmanuel Milou committed
161
{
162
    calllist_remove( current_calls, c->_callID);
163
    calltree_remove_call(current_calls, c, NULL);
164
    c->_state = CALL_STATE_DIALING;
165
    call_remove_all_errors(c);
166
    update_actions();
167
#if GTK_CHECK_VERSION(2,10,0)
Emmanuel Milou's avatar
Emmanuel Milou committed
168
    status_tray_icon_blink( FALSE );
169
#endif
Emmanuel Milou's avatar
Emmanuel Milou committed
170
171
}

172
173
static hashtable_free(gpointer key, gpointer value, gpointer user_data)
{
174
    g_free(key);
175
176
177
    g_free(value);
}

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
178
/** Internal to actions: Fill account list */
Emmanuel Milou's avatar
Emmanuel Milou committed
179
    void
180
sflphone_fill_account_list(gboolean toolbarInitialized)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
181
{
182
183
184
185

    gchar** array;
    gchar** accountID;
    unsigned int i;
186
187
188
	int count;

	count = current_account_get_message_number ();
189

Emmanuel Milou's avatar
Emmanuel Milou committed
190
    account_list_clear ( );
191

Emmanuel Milou's avatar
Emmanuel Milou committed
192
    array = (gchar **)dbus_account_list();
193
194
    if(array)
    {
Emmanuel Milou's avatar
Emmanuel Milou committed
195
196
197
198
        for (accountID = array; *accountID; accountID++)
        {
            account_t * a = g_new0(account_t,1);
            a->accountID = g_strdup(*accountID);
199
            a->credential_information = NULL;
Emmanuel Milou's avatar
Emmanuel Milou committed
200
201
202
            account_list_add(a);
        }
        g_strfreev (array);
203
    }
204

Emmanuel Milou's avatar
Emmanuel Milou committed
205
206
207
208
    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);
209
210
        if( details == NULL )
            break;
Emmanuel Milou's avatar
Emmanuel Milou committed
211
        a->properties = details;
212
                        
213
214
215
        /* As this function might be called numberous time, we should free the 
         * previously allocated space to avoid memory leaks.
         */
216
217
218
219
220
221
222

        /* 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 {
223
224
225
            a->credential_information = NULL;
        }
        
226
        int credential_index;
227
228
        for(credential_index = 0; credential_index < number_of_credential; credential_index++) {
            GHashTable * credential_information = dbus_get_credential(a->accountID, credential_index);
229
            g_ptr_array_add(a->credential_information, credential_information);
230
        }
Emmanuel Milou's avatar
Emmanuel Milou committed
231

232
        gchar * status = g_hash_table_lookup(details, REGISTRATION_STATUS);
Emmanuel Milou's avatar
Emmanuel Milou committed
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
        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;
        }
        else
        {
            a->state = ACCOUNT_STATE_INVALID;
        }

274
275
276
277
278
279
280
        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
281
282
    }

283
	// Set the current account message number
284
	current_account_set_message_number (count);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
285
286
}

287
gboolean sflphone_init()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
288
{
Emmanuel Milou's avatar
Emmanuel Milou committed
289
290
291
292
293
294
295
296
    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");
297

298
299
300
		// Init icons factory
		init_icon_factory ();

301
302
303
        current_calls = calltab_init(FALSE, CURRENT_CALLS);
        contacts = calltab_init(TRUE, CONTACTS);
        history = calltab_init(TRUE, HISTORY);
304

Emmanuel Milou's avatar
Emmanuel Milou committed
305
        account_list_init ();
306
        codec_list_init();
307
		conferencelist_init();
308

309
        // Fetch the configured accounts
Emmanuel Milou's avatar
Emmanuel Milou committed
310
        sflphone_fill_account_list(FALSE);
311

312
313
314
        // Fetch the ip2ip profile 
        sflphone_fill_ip2ip_profile();
        
315
        // Fetch the audio codecs
Emmanuel Milou's avatar
Emmanuel Milou committed
316
        sflphone_fill_codec_list();
317

318
		// Fetch the conference list
319
		// sflphone_fill_conference_list();
320

Emmanuel Milou's avatar
Emmanuel Milou committed
321
322
        return TRUE;
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
323
324
}

325
326
327
328
329
void sflphone_fill_ip2ip_profile(void)
{
    ip2ip_profile = (GHashTable *) dbus_get_ip2_ip_details();
}

Emmanuel Milou's avatar
Emmanuel Milou committed
330
void sflphone_get_ip2ip_properties (GHashTable **properties)
331
{
Emmanuel Milou's avatar
Emmanuel Milou committed
332
	*properties	= ip2ip_profile;
333
334
}

Emmanuel Milou's avatar
Emmanuel Milou committed
335
    void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
336
sflphone_hang_up()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
337
{
338
    callable_obj_t * selectedCall = calltab_get_selected_call(current_calls);
339
340
    conference_obj_t * selectedConf = calltab_get_selected_conf(active_calltree);

Emmanuel Milou's avatar
Emmanuel Milou committed
341
342
    if(selectedCall)
    {
343
        switch(selectedCall->_state)
Emmanuel Milou's avatar
Emmanuel Milou committed
344
345
346
347
348
349
        {
            case CALL_STATE_DIALING:
                dbus_hang_up (selectedCall);
                break;
            case CALL_STATE_RINGING:
                dbus_hang_up (selectedCall);
350
                call_remove_all_errors(selectedCall);
351
352
                selectedCall->_state = CALL_STATE_DIALING;
                //selectedCall->_stop = 0;
Emmanuel Milou's avatar
Emmanuel Milou committed
353
354
355
356
                break;
            case CALL_STATE_CURRENT:
            case CALL_STATE_HOLD:
            case CALL_STATE_BUSY:
357
            case CALL_STATE_RECORD:
Emmanuel Milou's avatar
Emmanuel Milou committed
358
                dbus_hang_up (selectedCall);
359
                call_remove_all_errors(selectedCall);
360
                selectedCall->_state = CALL_STATE_DIALING;
361
                set_timestamp (&selectedCall->_time_stop);
Emmanuel Milou's avatar
Emmanuel Milou committed
362
363
364
                break;
            case CALL_STATE_FAILURE:
                dbus_hang_up (selectedCall);
365
                call_remove_all_errors(selectedCall);
366
                selectedCall->_state = CALL_STATE_DIALING;
Emmanuel Milou's avatar
Emmanuel Milou committed
367
368
369
                break;
            case CALL_STATE_INCOMING:
                dbus_refuse (selectedCall);
370
                call_remove_all_errors(selectedCall);
371
                selectedCall->_state = CALL_STATE_DIALING;
372
                DEBUG("from sflphone_hang_up : "); stop_notification();
Emmanuel Milou's avatar
Emmanuel Milou committed
373
374
375
                break;
            case CALL_STATE_TRANSFERT:
                dbus_hang_up (selectedCall);
376
                call_remove_all_errors(selectedCall);
377
                set_timestamp (&selectedCall->_time_stop);
Emmanuel Milou's avatar
Emmanuel Milou committed
378
379
                break;
            default:
380
                WARN("Should not happen in sflphone_hang_up()!");
Emmanuel Milou's avatar
Emmanuel Milou committed
381
382
383
                break;
        }
    }
384
385
386
387
    else if(selectedConf) {
        dbus_hang_up_conference(selectedConf);
    }

388
    calltree_update_call(history, selectedCall, NULL);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
389
390
391
}


Alexandre Savard's avatar
Alexandre Savard committed
392
393
394
395
396
397
398
399
400
401
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
402
    void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
403
404
sflphone_pick_up()
{
Alexandre Savard's avatar
Alexandre Savard committed
405
    DEBUG("sflphone_pick_up\n");
406
407
408
    callable_obj_t * selectedCall = NULL;
    selectedCall = calltab_get_selected_call(active_calltree);
    
Emmanuel Milou's avatar
Emmanuel Milou committed
409
410
    if(selectedCall)
    {
411
        switch(selectedCall->_state)
Emmanuel Milou's avatar
Emmanuel Milou committed
412
413
414
415
416
        {
            case CALL_STATE_DIALING:
                sflphone_place_call (selectedCall);
                break;
            case CALL_STATE_INCOMING:
417
                selectedCall->_history_state = INCOMING;
418
                calltree_update_call( history, selectedCall, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
419
                dbus_accept (selectedCall);
420
                DEBUG("from sflphone_pick_up : "); stop_notification();
Emmanuel Milou's avatar
Emmanuel Milou committed
421
422
423
424
425
426
                break;
            case CALL_STATE_HOLD:
                sflphone_new_call();
                break;
            case CALL_STATE_TRANSFERT:
                dbus_transfert (selectedCall);
427
                set_timestamp (&selectedCall->_time_stop);
Emmanuel Milou's avatar
Emmanuel Milou committed
428
429
430
431
432
433
434
435
436
                break;
            case CALL_STATE_CURRENT:
            case CALL_STATE_RECORD:
                sflphone_new_call();
                break;
            case CALL_STATE_RINGING:
                sflphone_new_call();
                break;
            default:
437
                WARN("Should not happen in sflphone_pick_up()!");
Emmanuel Milou's avatar
Emmanuel Milou committed
438
439
440
                break;
        }
    }
441
442
443
    else {
        sflphone_new_call();
    }
444

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
445
446
}

Emmanuel Milou's avatar
Emmanuel Milou committed
447
    void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
448
449
sflphone_on_hold ()
{
450
    callable_obj_t * selectedCall = calltab_get_selected_call(current_calls);
451
452
453
    conference_obj_t * selectedConf = calltab_get_selected_conf(active_calltree);

    DEBUG("sflphone_on_hold");
Emmanuel Milou's avatar
Emmanuel Milou committed
454
455
    if(selectedCall)
    {
456
        switch(selectedCall->_state)
Emmanuel Milou's avatar
Emmanuel Milou committed
457
458
459
460
461
462
463
464
465
        {
            case CALL_STATE_CURRENT:
                dbus_hold (selectedCall);
                break;
            case CALL_STATE_RECORD:
                dbus_hold (selectedCall);
                break;

            default:
466
                WARN("Should not happen in sflphone_on_hold!");
Emmanuel Milou's avatar
Emmanuel Milou committed
467
468
469
                break;
        }
    }
470
471
472
    else if (selectedConf) {
        dbus_hold_conference(selectedConf);
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
473
474
}

Emmanuel Milou's avatar
Emmanuel Milou committed
475
    void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
476
477
sflphone_off_hold ()
{
478
    DEBUG("sflphone_off_hold");
479
    callable_obj_t * selectedCall = calltab_get_selected_call(current_calls);
480
481
    conference_obj_t * selectedConf = calltab_get_selected_conf(active_calltree);

Emmanuel Milou's avatar
Emmanuel Milou committed
482
483
    if(selectedCall)
    {
484
        switch(selectedCall->_state)
Emmanuel Milou's avatar
Emmanuel Milou committed
485
486
487
488
489
        {
            case CALL_STATE_HOLD:
                dbus_unhold (selectedCall);
                break;
            default:
490
                WARN("Should not happen in sflphone_off_hold ()!");
Emmanuel Milou's avatar
Emmanuel Milou committed
491
492
493
                break;
        }
    }
494
    else if (selectedConf) {
Julien Bonjean's avatar
Julien Bonjean committed
495

496
497
498
499
        
        dbus_unhold_conference(selectedConf);
    }
    /*
500
    if(dbus_get_is_recording(selectedCall))
501
    {
502
        DEBUG("Currently recording!");
503
    }
504
    else
505
    {
506
        DEBUG("Not recording currently");
507
    }
508
    */
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
509
510
511
}


Emmanuel Milou's avatar
Emmanuel Milou committed
512
    void
513
sflphone_fail( callable_obj_t * c )
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
514
{
515
    c->_state = CALL_STATE_FAILURE;
516
    calltree_update_call(current_calls, c, NULL);
517
    update_actions();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
518
519
}

Emmanuel Milou's avatar
Emmanuel Milou committed
520
    void
521
sflphone_busy( callable_obj_t * c )
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
522
{
523
    c->_state = CALL_STATE_BUSY;
524
    calltree_update_call(current_calls, c, NULL);
525
    update_actions();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
526
527
}

Emmanuel Milou's avatar
Emmanuel Milou committed
528
    void
529
sflphone_current( callable_obj_t * c )
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
530
{
531

532
533
    if( c->_state != CALL_STATE_HOLD )
        set_timestamp (&c->_time_start);
534
    c->_state = CALL_STATE_CURRENT;
535
    calltree_update_call(current_calls, c, NULL);
536
    update_actions();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
537
538
}

Emmanuel Milou's avatar
Emmanuel Milou committed
539
    void
540
sflphone_record( callable_obj_t * c )
alexandresavard's avatar
alexandresavard committed
541
{
542
543
    if( c->_state != CALL_STATE_HOLD )
        set_timestamp (&c->_time_start);
544
    c->_state = CALL_STATE_RECORD;
545
    calltree_update_call(current_calls, c, NULL);
546
    update_actions();
alexandresavard's avatar
alexandresavard committed
547
548
}

Emmanuel Milou's avatar
Emmanuel Milou committed
549
    void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
550
sflphone_set_transfert()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
551
{
552
    callable_obj_t * c = calltab_get_selected_call(current_calls);
Emmanuel Milou's avatar
Emmanuel Milou committed
553
554
    if(c)
    {
555
        c->_state = CALL_STATE_TRANSFERT;
556
        c->_trsft_to = g_strdup("");
557
        calltree_update_call(current_calls, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
558
    }
559
    update_actions();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
560
561
}

Emmanuel Milou's avatar
Emmanuel Milou committed
562
    void
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
563
564
sflphone_unset_transfert()
{
565
    callable_obj_t * c = calltab_get_selected_call(current_calls);
Emmanuel Milou's avatar
Emmanuel Milou committed
566
567
    if(c)
    {
568
        c->_state = CALL_STATE_CURRENT;
569
        c->_trsft_to = g_strdup("");
570
        calltree_update_call(current_calls, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
571
    }
572
    update_actions();
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
573
}
Emmanuel Milou's avatar
Emmanuel Milou committed
574

575
    void
576
577
578
579
580
sflphone_display_transfer_status(const gchar* message)
{
    statusbar_push_message( message , __MSG_ACCOUNT_DEFAULT);
}

Emmanuel Milou's avatar
Emmanuel Milou committed
581
    void
582
sflphone_incoming_call (callable_obj_t * c)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
583
{
584
585
	gchar *msg = "";

586
    c->_history_state = MISSED;
Julien Bonjean's avatar
Julien Bonjean committed
587
588
    calllist_add ( current_calls, c );
    calllist_add( history, c );
589
    calltree_add_call( current_calls, c, NULL);
590
    update_actions();
Julien Bonjean's avatar
Julien Bonjean committed
591
    calltree_display (current_calls);
592
593
594
595
596
597
598
599
	
	// 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
600
}
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
601

Emmanuel Milou's avatar
Emmanuel Milou committed
602
    void
603
process_dialing(callable_obj_t * c, guint keyval, gchar * key)
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
604
{
Emmanuel Milou's avatar
Emmanuel Milou committed
605
    // We stop the tone
606
    if(strlen(c->_peer_number) == 0 && c->_state != CALL_STATE_TRANSFERT){
Emmanuel Milou's avatar
Emmanuel Milou committed
607
608
609
        dbus_start_tone( FALSE , 0 );
        //dbus_play_dtmf( key );
    }
610

611
612
    DEBUG("process_dialing : keyval : %i",keyval);
    DEBUG("process_dialing : key : %s",key);
Emmanuel Milou's avatar
Emmanuel Milou committed
613
614
615
616
617
618
619
620
621
622
623
624

    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 */
625
626
                gchar * before = c->_peer_number;
                if(strlen(c->_peer_number) >= 1){
Emmanuel Milou's avatar
Emmanuel Milou committed
627

628
629
630
631
632
633
634
635
636
					if (c->_state == CALL_STATE_TRANSFERT)
					{
						c->_trsft_to = g_strndup (c->_trsft_to, strlen(c->_trsft_to) - 1);
					}
					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
637
                    }
638
					calltree_update_call(current_calls, c, NULL);
Julien Bonjean's avatar
Julien Bonjean committed
639
                }
640
                else if(strlen(c->_peer_number) == 0)
Emmanuel Milou's avatar
Emmanuel Milou committed
641
                {
642
                    if(c->_state != CALL_STATE_TRANSFERT)
Emmanuel Milou's avatar
Emmanuel Milou committed
643
644
645
646
647
648
649
650
651
652
653
654
655
                        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
656
            {
Emmanuel Milou's avatar
Emmanuel Milou committed
657

658
659
660
661
662
663
                if (c->_state == CALL_STATE_TRANSFERT)
                {
                    c->_trsft_to = g_strconcat(c->_trsft_to, key, NULL);
                }
                else
                {
Emmanuel Milou's avatar
Emmanuel Milou committed
664
                    dbus_play_dtmf( key );
665
666
                    c->_peer_number = g_strconcat(c->_peer_number, key, NULL);
                }
Emmanuel Milou's avatar
Emmanuel Milou committed
667

668
                if(c->_state == CALL_STATE_DIALING)
Emmanuel Milou's avatar
Emmanuel Milou committed
669
                {
670
671
                    //g_free(c->_peer_name);
                    //c->_peer_name = g_strconcat("\"\" <", c->_peer_number, ">", NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
672
                }
673
                calltree_update_call(current_calls, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
674
675
676
            }
            break;
    }
677
678
}

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

680
    callable_obj_t *
areversat's avatar
areversat committed
681
sflphone_new_call()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
682
{
Julien Bonjean's avatar
Julien Bonjean committed
683

684
    callable_obj_t *c;
685
    callable_obj_t * current_selected_call;
686
    gchar *peer_name, *peer_number;
687

688
    DEBUG("sflphone_new_call");
689
690
691

    current_selected_call = calltab_get_selected_call(current_calls);

692
    if ((current_selected_call != NULL) && (current_selected_call->_confID == NULL))
693
	sflphone_on_hold();
694

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

699
700
701
    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
702

703
704
    c->_history_state = OUTGOING;

705
    calllist_add (current_calls,c);
706
    calltree_add_call (current_calls, c, NULL);
707
    update_actions();
708

Emmanuel Milou's avatar
Emmanuel Milou committed
709
    return c;
710
711
}

areversat's avatar
areversat committed
712

Emmanuel Milou's avatar
Emmanuel Milou committed
713
    void
areversat's avatar
areversat committed
714
715
sflphone_keypad( guint keyval, gchar * key)
{
716
    callable_obj_t * c = calltab_get_selected_call(current_calls);
Emmanuel Milou's avatar
Emmanuel Milou committed
717
718
719

    if((active_calltree != current_calls) || (active_calltree == current_calls && !c))
    {
720
        DEBUG("Not in a call, not dialing, create a new call");
Emmanuel Milou's avatar
Emmanuel Milou committed
721
722
723
724
725
726
727
728
        //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
729
                calltree_display (current_calls);
Emmanuel Milou's avatar
Emmanuel Milou committed
730
731
732
733
734
735
                process_dialing(sflphone_new_call(), keyval, key);
                break;
        }
    }
    else if(c)
    {
736
        DEBUG("Call is non-zero");
737
        switch(c->_state)
Emmanuel Milou's avatar
Emmanuel Milou committed
738
739
        {
            case CALL_STATE_DIALING: // Currently dialing => edit number
740
                DEBUG("Writing a number");
Emmanuel Milou's avatar
Emmanuel Milou committed
741
742
743
744
745
746
747
748
                process_dialing(c, keyval, key);
                break;
            case CALL_STATE_RECORD:
            case CALL_STATE_CURRENT:
                switch (keyval)
                {
                    case 65307: /* ESCAPE */
                        dbus_hang_up(c);
749
                        set_timestamp (&c->_time_stop);
750
                        calltree_update_call(history, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
751
752
753
754
755
756
757
758
759
760
761
                        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);
762
                            //update_callable_obj_tree(current_calls,c);
Emmanuel Milou's avatar
Emmanuel Milou committed
763
764
765
766
767
768
769
770
771
                        }
                        break;
                }
                break;
            case CALL_STATE_INCOMING:
                switch (keyval)
                {
                    case 65293: /* ENTER */
                    case 65421: /* ENTER numpad */
772
                        c->_history_state = INCOMING;
773
                        calltree_update_call(history, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
774
                        dbus_accept(c);
775
                        DEBUG("from sflphone_keypad ( enter ) : "); stop_notification();
Emmanuel Milou's avatar
Emmanuel Milou committed
776
777
778
                        break;
                    case 65307: /* ESCAPE */
                        dbus_refuse(c);
779
                        DEBUG("from sflphone_keypad ( escape ) : "); stop_notification();
Emmanuel Milou's avatar
Emmanuel Milou committed
780
781
782
783
784
785
786
787
788
                        break;
                }
                break;
            case CALL_STATE_TRANSFERT:
                switch (keyval)
                {
                    case 65293: /* ENTER */
                    case 65421: /* ENTER numpad */
                        dbus_transfert(c);
789
                        set_timestamp (&c->_time_stop);
Emmanuel Milou's avatar
Emmanuel Milou committed
790
791
792
793
                        break;
                    case 65307: /* ESCAPE */
                        sflphone_unset_transfert(c);
                        break;
794
                    default: // When a call is on transfert, typing new numbers will add it to c->_peer_number
Emmanuel Milou's avatar
Emmanuel Milou committed
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
                        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:
817
                //c->_stop = 0;
Emmanuel Milou's avatar
Emmanuel Milou committed
818
819
820
821
                switch (keyval)
                {
                    case 65307: /* ESCAPE */
                        dbus_hang_up(c);
822
                        //c->_stop = 0;
823
                        calltree_update_call(history, c, NULL);
Emmanuel Milou's avatar
Emmanuel Milou committed
824
825
826
827
828
829
                        break;
                }
                break;
            default:
                break;
        }
830

Alexandre Savard's avatar
Alexandre Savard committed
831
832
    }
    else {
833
        sflphone_new_call();
Emmanuel Milou's avatar
Emmanuel Milou committed
834
835
    }
}
836

837
838
839
840
841
842
843
844
static int _place_direct_call(const callable_obj_t * c) {
    if (c->_state == CALL_STATE_DIALING) {
        dbus_place_call (c);
    } else {
        return -1;
    }
    return 0;
}
Julien Bonjean's avatar
Julien Bonjean committed
845

846
static int _place_registered_call(callable_obj_t * c) {
847

848
849
    account_t * current = NULL;
  
850
851
852
853
854
    if(c == NULL) {
        DEBUG("callable_obj_t is NULL in _place_registered_call");
        return -1;
    }
    
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
    if (c->_state != CALL_STATE_DIALING) {
        return -1;
    }
  
    if(g_strcasecmp(c->_peer_number, "") == 0) {
        return -1;
    }
    
    if( account_list_get_size() == 0 ) {
        notify_no_accounts();
        sflphone_fail(c);
        return -1;
    } 
    
    if( account_list_get_by_state( ACCOUNT_STATE_REGISTERED ) == NULL ) {
        notify_no_registered_accounts();
        sflphone_fail(c);
        return -1;
    }
    
875
876
877
878
879
    if(g_strcasecmp(c->_accountID, "") != 0) {
        current = account_list_get_by_id(c->_accountID);
    } else {
        current = account_list_get_current();
    }
880

881
    if(current == NULL) { 
882
        DEBUG("Unexpected condition: account_t is NULL in %s at %d for accountID %s", __FILE__, __LINE__, c->_accountID);
883
884
        return -1;
    }   
885
                        
886
887
888
889
890
891
892
893
894
895
    if(g_strcasecmp(g_hash_table_lookup( current->properties, "Status"),"REGISTERED")==0) {
        /* The call is made with the current account */
        c->_accountID = current->accountID;
        dbus_place_call(c);
    } else {
       /* Place the call with the first registered account
        * and switch the current account.
        * If we are here, we can be sure that there is at least one. 
        */
        current = account_list_get_by_state( ACCOUNT_STATE_REGISTERED );
896
        c->_accountID = current->accountID;
897
898
899
900
901
902
903
904
        dbus_place_call(c);
        notify_current_account( current );
    }        

    c->_history_state = OUTGOING;
    calllist_add(history, c);                
    return 0;
}
905

906
907
908
    void
sflphone_place_call ( callable_obj_t * c )
{
909
910
	gchar *msg = "";

911
912
913
914
915
916
    DEBUG("Placing call with %s @ %s and accountid %s", c->_peer_name, c->_peer_number, c->_accountID);
    
    if(c == NULL) {
        DEBUG("Unexpected condition: callable_obj_t is null in %s at %d", __FILE__, __LINE__);
        return;
    }
917

918
    if(_is_direct_call(c)) {
919
920
921
922
		msg = g_markup_printf_escaped (_("Direct SIP call"));
        statusbar_pop_message(__MSG_ACCOUNT_DEFAULT);
        statusbar_push_message( msg , __MSG_ACCOUNT_DEFAULT);
        g_free(msg);
923
924
925
926
927
928
929
930
        if(_place_direct_call(c) < 0) {
            DEBUG("An error occured while placing direct call in %s at %d", __FILE__, __LINE__);
            return;
        }
    } else {
        if(_place_registered_call(c) < 0) {
            DEBUG("An error occured while placing registered call in %s at %d", __FILE__, __LINE__);
            return;
931
        }
Emmanuel Milou's avatar
Emmanuel Milou committed
932
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
933
934
}

Alexandre Savard's avatar
Alexandre Savard committed
935

936
    void
937
sflphone_detach_participant(const gchar* callID)
938
{
939
    DEBUG("sflphone detach participant from conference");
940

941
942
    

943
944