actions.c 36.5 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
83
84
85
86
/*
 * 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;
    }

    return 0;
}


Emmanuel Milou's avatar
Emmanuel Milou committed
87
    void
88
status_bar_display_account ()
89
{
90
    gchar* msg;
91
    account_t* acc;
92
93
94
95
96

    statusbar_pop_message(__MSG_ACCOUNT_DEFAULT);

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

Emmanuel Milou's avatar
Emmanuel Milou committed
112
113

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

    if (quit)
    {
127
128
129
        // Save the history 
        sflphone_save_history ();

Emmanuel Milou's avatar
Emmanuel Milou committed
130
131
132
133
134
135
136
        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
137
138
}

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

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

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

168
169
static hashtable_free(gpointer key, gpointer value, gpointer user_data)
{
170
    g_free(key);
171
172
173
    g_free(value);
}

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
174
/** Internal to actions: Fill account list */
Emmanuel Milou's avatar
Emmanuel Milou committed
175
void sflphone_fill_account_list (void) {
176
177
178
179

    gchar** array;
    gchar** accountID;
    unsigned int i;
180
181
182
	int count;

	count = current_account_get_message_number ();
183

Emmanuel Milou's avatar
Emmanuel Milou committed
184
    account_list_clear ();
185

Emmanuel Milou's avatar
Emmanuel Milou committed
186
    array = (gchar **)dbus_account_list();
187
188
    if(array)
    {
Emmanuel Milou's avatar
Emmanuel Milou committed
189
190
191
192
        for (accountID = array; *accountID; accountID++)
        {
            account_t * a = g_new0(account_t,1);
            a->accountID = g_strdup(*accountID);
193
            a->credential_information = NULL;
Emmanuel Milou's avatar
Emmanuel Milou committed
194
			// TODO Clean codec list QUEUE
Emmanuel Milou's avatar
Emmanuel Milou committed
195
196
197
            account_list_add(a);
        }
        g_strfreev (array);
198
    }
199

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

        /* 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 {
217
218
219
            a->credential_information = NULL;
        }
        
220
        int credential_index;
221
        for(credential_index = 0; credential_index < number_of_credential; credential_index++) {
222
            GHashTable * credential_information = dbus_get_credential (a->accountID, credential_index);
223
            g_ptr_array_add(a->credential_information, credential_information);
224
        }
Emmanuel Milou's avatar
Emmanuel Milou committed
225

226
        gchar * status = g_hash_table_lookup(details, REGISTRATION_STATUS);
Emmanuel Milou's avatar
Emmanuel Milou committed
227
228
229
230
231
232
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
        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;
        }

268
269
270
271
272
273
274
        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);
275
276
277

		// Attach a codec list to each account
		account_create_codec_list (&a);
Emmanuel Milou's avatar
Emmanuel Milou committed
278
279
    }

280
	// Set the current account message number
281
	current_account_set_message_number (count);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
282
283
}

Emmanuel Milou's avatar
Emmanuel Milou committed
284
285
gboolean sflphone_init() {

Emmanuel Milou's avatar
Emmanuel Milou committed
286
287
288
289
290
291
292
293
    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");
294

295
296
297
		// Init icons factory
		init_icon_factory ();

298
299
300
        current_calls = calltab_init(FALSE, CURRENT_CALLS);
        contacts = calltab_init(TRUE, CONTACTS);
        history = calltab_init(TRUE, HISTORY);
301

Emmanuel Milou's avatar
Emmanuel Milou committed
302
        account_list_init ();
303
        codec_capabilities_load ();
Emmanuel Milou's avatar
Emmanuel Milou committed
304
		conferencelist_init ();
305

306
        // Fetch the configured accounts
Emmanuel Milou's avatar
Emmanuel Milou committed
307
        sflphone_fill_account_list ();
308

309
310
311
        // Fetch the ip2ip profile 
        sflphone_fill_ip2ip_profile();
        
312
        // Fetch the audio codecs
313
        // sflphone_fill_codec_list();
314

315
		// Fetch the conference list
316
		// sflphone_fill_conference_list();
317

Emmanuel Milou's avatar
Emmanuel Milou committed
318
319
        return TRUE;
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
320
321
}

322
323
324
325
326
void sflphone_fill_ip2ip_profile(void)
{
    ip2ip_profile = (GHashTable *) dbus_get_ip2_ip_details();
}

Emmanuel Milou's avatar
Emmanuel Milou committed
327
void sflphone_get_ip2ip_properties (GHashTable **properties)
328
{
Emmanuel Milou's avatar
Emmanuel Milou committed
329
	*properties	= ip2ip_profile;
330
331
}

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

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

385
    calltree_update_call(history, selectedCall, NULL);
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
386
387
388
}


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

Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
442
443
}

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

    DEBUG("sflphone_on_hold");
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
459
460
461
462
        {
            case CALL_STATE_CURRENT:
                dbus_hold (selectedCall);
                break;
            case CALL_STATE_RECORD:
                dbus_hold (selectedCall);
                break;

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

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

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

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


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

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

Emmanuel Milou's avatar
Emmanuel Milou committed
525
    void
526
sflphone_current( callable_obj_t * c )
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
527
{
528

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

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

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

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

572
    void
573
574
575
576
577
sflphone_display_transfer_status(const gchar* message)
{
    statusbar_push_message( message , __MSG_ACCOUNT_DEFAULT);
}

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

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

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

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

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

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

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

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

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

677
    callable_obj_t *
areversat's avatar
areversat committed
678
sflphone_new_call()
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
679
{
Julien Bonjean's avatar
Julien Bonjean committed
680

681
    callable_obj_t *c;
682
    callable_obj_t * current_selected_call;
683
    gchar *peer_name, *peer_number;
684

685
    DEBUG("sflphone_new_call");
686
687
688

    current_selected_call = calltab_get_selected_call(current_calls);

689
    if ((current_selected_call != NULL) && (current_selected_call->_confID == NULL))
690
	sflphone_on_hold();
691

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

696
697
698
    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
699

700
    calllist_add (current_calls,c);
701
    calltree_add_call (current_calls, c, NULL);
702
    update_actions();
703

Emmanuel Milou's avatar
Emmanuel Milou committed
704
    return c;
705
706
}

areversat's avatar
areversat committed
707

Emmanuel Milou's avatar
Emmanuel Milou committed
708
    void
areversat's avatar
areversat committed
709
710
sflphone_keypad( guint keyval, gchar * key)
{
711
    callable_obj_t * c = calltab_get_selected_call(current_calls);
Emmanuel Milou's avatar
Emmanuel Milou committed
712
713
714

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

Alexandre Savard's avatar
Alexandre Savard committed
826
827
    }
    else {
828
        sflphone_new_call();
Emmanuel Milou's avatar
Emmanuel Milou committed
829
830
    }
}
831

832
833
834
835
836
837
838
839
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
840

841
static int _place_registered_call(callable_obj_t * c) {
842

843
844
    account_t * current = NULL;
  
845
846
847
848
849
    if(c == NULL) {
        DEBUG("callable_obj_t is NULL in _place_registered_call");
        return -1;
    }
    
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
    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;
    }
    
870
871
872
873
874
    if(g_strcasecmp(c->_accountID, "") != 0) {
        current = account_list_get_by_id(c->_accountID);
    } else {
        current = account_list_get_current();
    }
875

876
    if(current == NULL) { 
877
        DEBUG("Unexpected condition: account_t is NULL in %s at %d for accountID %s", __FILE__, __LINE__, c->_accountID);
878
879
        return -1;
    }   
880
                        
881
882
883
884
885
886
887
888
889
890
    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 );
891
        c->_accountID = current->accountID;
892
893
894
895
896
897
898
899
        dbus_place_call(c);
        notify_current_account( current );
    }        

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

901
902
903
    void
sflphone_place_call ( callable_obj_t * c )
{
904
905
	gchar *msg = "";

906
907
908
909
910
911
    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;
    }
912

913
    if(_is_direct_call(c)) {
914
915
916
917
		msg = g_markup_printf_escaped (_("Direct SIP call"));
        statusbar_pop_message(__MSG_ACCOUNT_DEFAULT);
        statusbar_push_message( msg , __MSG_ACCOUNT_DEFAULT);
        g_free(msg);
918
919
920
921
922
923
924
925
        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;
926
        }
Emmanuel Milou's avatar
Emmanuel Milou committed
927
    }
Pierre-Luc Beaudoin's avatar
Pierre-Luc Beaudoin committed
928
929
}

Alexandre Savard's avatar
Alexandre Savard committed
930

931
    void
932
sflphone_detach_participant(const gchar* callID)
933
{
934
    DEBUG("sflphone detach participant from conference");
935

936
937
    

938
939
    if(callID == NULL) {
        callable_obj_t * selectedCall = calltab_get_selected_call(current_calls);
940
941
942
943
	DEBUG("    sflphone_detach_participant %s\n", selectedCall->_callID);

	calltree_remove_call(current_calls, selectedCall, NULL);
	calltree_add_call(current_calls, selectedCall, NULL);
944