conference_obj.c 9.51 KB
Newer Older
1
/*
2
 *  Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010, 2011 Savoir-Faire Linux Inc.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
 *  Author: Alexandre Savard <alexandre.savard@savoirfairelinux.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 19 20 21 22 23 24 25 26 27 28
 *
 *  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.
29 30 31 32
 */

#include <time.h>

33 34 35 36 37 38
#include "callable_obj.h"
#include "sflphone_const.h"

#include "calltab.h"
#include "calllist.h"

39
conference_obj_t *create_new_conference (conference_state_t state, const gchar* const confID)
40
{
41
    conference_obj_t *new_conf;
42

43 44 45
    if (confID == NULL) {
        ERROR("Conference: Error: Conference ID is NULL while creating new conference");
        return NULL;
46 47 48
    }

    DEBUG ("Conference: Create new conference %s", confID);
49 50

    // Allocate memory
51
    new_conf = g_new0 (conference_obj_t, 1);
52 53 54
    if (!new_conf) {
        ERROR("Conference: Error: Could not allocate data ");
        return NULL;
55
    }
56

Julien Bonjean's avatar
Julien Bonjean committed
57
    // Set state field
58
    new_conf->_state = state;
59 60

    // Set the ID field
61
    new_conf->_confID = g_strdup (confID);
62 63

    new_conf->participant_list = NULL;
64
    new_conf->participant_number = NULL;
65

66 67 68
    new_conf->_recordfile = NULL;
    new_conf->_record_is_playing = FALSE;

69 70
    // set conference timestamp
    time(&new_conf->_time_start);
71

72
    return new_conf;
73 74
}

75
conference_obj_t *create_new_conference_from_details (const gchar *conf_id, GHashTable *details)
Julien Bonjean's avatar
Julien Bonjean committed
76
{
77
    conference_obj_t *new_conf;
78
    gchar** participants;
79
    gchar* state_str;
80

81
    DEBUG ("Conference: Create new conference from details");
82

83 84
    // Allocate memory
    new_conf = g_new0 (conference_obj_t, 1);
85
    if (!new_conf) {
86
        ERROR("Conference: Error: Could not allocate data ");
87
        return NULL;
88
    }
89

90
    new_conf->_confID = g_strdup (conf_id);
91

92 93
    new_conf->_conference_secured = FALSE;
    new_conf->_conf_srtp_enabled = FALSE;
94

95 96 97
    new_conf->participant_list = NULL;

    // get participant list
Julien Bonjean's avatar
Julien Bonjean committed
98
    participants = dbus_get_participant_list (conf_id);
99 100
    if (participants == NULL)
        ERROR("Conference: Error: Could not get participant list");
101 102

    // generate conference participant list
Julien Bonjean's avatar
Julien Bonjean committed
103 104
    conference_participant_list_update (participants, new_conf);

Rafaël Carré's avatar
Rafaël Carré committed
105 106
    g_strfreev(participants);

107
    state_str = g_hash_table_lookup (details, "CONF_STATE");
108

109
    if (g_strcasecmp (state_str, "ACTIVE_ATACHED") == 0)
110
        new_conf->_state = CONFERENCE_STATE_ACTIVE_ATACHED;
111
    else if (g_strcasecmp (state_str, "ACTIVE_ATTACHED_REC") == 0)
112
        new_conf->_state = CONFERENCE_STATE_ACTIVE_ATTACHED_RECORD;
113
    else if (g_strcasecmp (state_str, "ACTIVE_DETACHED") == 0)
114
        new_conf->_state = CONFERENCE_STATE_ACTIVE_DETACHED;
115
    else if (g_strcasecmp (state_str, "ACTIVE_DETACHED_REC") == 0)
116
        new_conf->_state = CONFERENCE_STATE_ACTIVE_DETACHED_RECORD;
117
    else if (g_strcasecmp (state_str, "HOLD") == 0)
118
        new_conf->_state = CONFERENCE_STATE_HOLD;
119
    else if (g_strcasecmp (state_str, "HOLD_REC") == 0)
120
        new_conf->_state = CONFERENCE_STATE_HOLD_RECORD;
121

Rafaël Carré's avatar
Rafaël Carré committed
122

123 124 125
    new_conf->_recordfile = NULL;
    new_conf->_record_is_playing = FALSE;

126
    return new_conf;
127 128
}

129

130 131 132
void free_conference_obj_t (conference_obj_t *c)
{
    g_free (c->_confID);
133

134
    if (c->participant_list)
135
        g_slist_free(c->participant_list);
136

137 138
    g_free (c);
}
139

140 141 142 143 144 145 146 147 148 149 150 151 152
static
void conference_add_participant_number(const gchar *call_id, conference_obj_t *conf)
{
    callable_obj_t *call = calllist_get_call(current_calls, call_id);
    if (!call) {
        ERROR("Conference: Error: Could not find %s", call_id);
        return;
    }

    gchar *number_account = g_strconcat(call->_peer_number, ",", call->_accountID, NULL);

    conf->participant_number = g_slist_append(conf->participant_number, number_account);
}
153

Julien Bonjean's avatar
Julien Bonjean committed
154
void conference_add_participant (const gchar* call_id, conference_obj_t* conf)
155
{
156 157
    DEBUG("Conference: Conference %s, adding participant %s", conf->_confID, call_id);

158
    // store the new participant list after appending participant id
159
    conf->participant_list = g_slist_append (conf->participant_list, (gpointer) g_strdup(call_id));
160 161 162

    // store the phone number of this participant
    conference_add_participant_number(call_id, conf);
163 164
}

Julien Bonjean's avatar
Julien Bonjean committed
165
void conference_remove_participant (const gchar* call_id, conference_obj_t* conf)
166 167
{
    // store the new participant list after removing participant id
Julien Bonjean's avatar
Julien Bonjean committed
168
    conf->participant_list = g_slist_remove (conf->participant_list, (gconstpointer) call_id);
169 170 171
}


Julien Bonjean's avatar
Julien Bonjean committed
172
GSList* conference_next_participant (GSList* participant)
173
{
Julien Bonjean's avatar
Julien Bonjean committed
174
    return g_slist_next (participant);
175 176 177
}


Julien Bonjean's avatar
Julien Bonjean committed
178
void conference_participant_list_update (gchar** participants, conference_obj_t* conf)
179 180 181
{
    gchar* call_id;
    gchar** part;
182
    callable_obj_t *call;
183

184 185
    DEBUG ("Conference: Participant list update");

186
    if (!conf) {
187 188 189 190
    	ERROR("Conference: Error: Conference is NULL");
        return;
    }

191 192 193 194 195 196 197
    for (part = participants; *part; part++) {
        call_id = (gchar *) (*part);
        call = calllist_get_call(current_calls, call_id);
        if(call->_confID != NULL) {
            g_free(call->_confID);
            call->_confID = NULL;
        }
198 199
    }

Julien Bonjean's avatar
Julien Bonjean committed
200 201 202
    if (conf->participant_list) {
        g_slist_free (conf->participant_list);
        conf->participant_list = NULL;
203 204 205
    }

    for (part = participants; *part; part++) {
Julien Bonjean's avatar
Julien Bonjean committed
206
        call_id = (gchar*) (*part);
207 208
        call = calllist_get_call(current_calls, call_id);
        call->_confID = g_strdup(conf->_confID);
Julien Bonjean's avatar
Julien Bonjean committed
209
        conference_add_participant (call_id, conf);
210 211
    }
}
212 213 214

gchar *serialize_history_conference_entry(conference_obj_t *entry)
{
215
    gchar *result = "";
216
    static const gchar * const separator = "|";
217 218 219
    gchar *time_start = "";
    gchar *time_stop = "";
    gchar *peer_name = "";
Alexandre Savard's avatar
Alexandre Savard committed
220 221 222
    gchar *participantstr = "";
    gchar *confID = "";
    GSList *participant_list;
223 224 225
    gint length = 0;
    gint i;

Alexandre Savard's avatar
Alexandre Savard committed
226 227
    confID = entry->_confID;

228 229
    time_start = g_strdup_printf ("%i", (int) entry->_time_start);
    time_stop = g_strdup_printf ("%i", (int) entry->_time_stop);
230

231 232
    peer_name = (entry->_confID == NULL || g_strcasecmp(entry->_confID, "") == 0) ? "empty": entry->_confID;

Alexandre Savard's avatar
Alexandre Savard committed
233 234
    length = g_slist_length(entry->participant_list);
    participant_list = entry->participant_list;
235 236

    for(i = 0; i < length; i++) {
237 238
        const gchar * const tmp = g_slist_nth_data(participant_list, i);
        if (!tmp)
239
            WARN("Conference: Peer number is NULL in conference list");
Alexandre Savard's avatar
Alexandre Savard committed
240
        participantstr = g_strconcat(participantstr, tmp, ";", NULL);
241

242
        DEBUG("Conference: Participant number: %s, concatenation: %s", tmp, participantstr);
243 244
    }

245
    result = g_strconcat("9999", separator,
Alexandre Savard's avatar
Alexandre Savard committed
246
			participantstr, separator, // peer number
247
			peer_name, separator,
248 249
			time_start, separator,
			time_stop, separator,
Alexandre Savard's avatar
Alexandre Savard committed
250
			confID, separator,
251 252 253
			"empty", separator, // peer AccountID
			entry->_recordfile ? entry->_recordfile : "", separator,
			"empty", separator,
254
			"empty", NULL);
255

256
    return result;
257
}
258

259
conference_obj_t *create_conference_history_entry_from_serialized(gchar *entry)
260 261 262
{
    history_state_t history_state = MISSED;
    conference_state_t state = CONFERENCE_STATE_ACTIVE_ATACHED;
263 264 265 266 267 268 269 270
    const gchar *participant = NULL;
    const gchar *name = NULL;
    const gchar *time_start = NULL;
    const gchar *time_stop = NULL;
    const gchar *accountID = NULL;
    const gchar *recordfile = NULL;
    const gchar *confID = NULL;

271
    DEBUG("Conference: Create a conference from serialized form");
272 273 274 275 276 277

    static const gchar * const delim = "|";
    gchar **ptr = g_strsplit(entry, delim, 10);
    gint token = 0;
    while (ptr && token < 10) {
        switch (token) {
278
            case 0:
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 309
                history_state = MISSED;
                break;
            case 1:
                participant = *ptr;
                break;
            case 2:
                name = *ptr;
                break;
            case 3:
                time_start = *ptr;
                break;
            case 4:
                time_stop = *ptr;
                break;
            case 5:
                confID = *ptr;
                break;
            case 6:
                accountID = *ptr;
                break;
            case 7:
                recordfile = *ptr;
                break;
            case 8:
            case 9:
            default:
                break;
        }

        token++;
        ptr++;
310
    }
311

Alexandre Savard's avatar
Alexandre Savard committed
312
    // create a new empty conference
313 314
    conference_obj_t *conf = create_new_conference(state, confID);

315 316
    conf->_time_start = atoi(time_start);
    conf->_time_stop = atoi(time_stop);
317 318 319
    conf->_recordfile = g_strdup(recordfile);

    return conf;
320
}