~ubuntu-branches/ubuntu/trusty/modem-manager-gui/trusty-backports

« back to all changes in this revision

Viewing changes to src/mmguicore.c

  • Committer: Package Import Robot
  • Author(s): Graham Inggs
  • Date: 2013-07-30 12:51:59 UTC
  • Revision ID: package-import@ubuntu.com-20130730125159-flzv882fhuzhmfmi
Tags: upstream-0.0.16
ImportĀ upstreamĀ versionĀ 0.0.16

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *      mmguicore.c
 
3
 *      
 
4
 *      Copyright 2013 Alex <alex@linuxonly.ru>
 
5
 *      
 
6
 *      This program is free software: you can redistribute it and/or modify
 
7
 *      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
 
9
 *      (at your option) any later version.
 
10
 *      
 
11
 *      This program is distributed in the hope that it will be useful,
 
12
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *      GNU General Public License for more details.
 
15
 *      
 
16
 *      You should have received a copy of the GNU General Public License
 
17
 *      along with this program. If not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
#include <glib.h>
 
21
#include <gmodule.h>
 
22
#include <gio/gio.h>
 
23
#include <string.h>
 
24
#include <stdio.h>
 
25
#include <stdlib.h>
 
26
#include <poll.h>
 
27
 
 
28
#include "mmguicore.h"
 
29
#include "encoding.h"
 
30
#include "smsdb.h"
 
31
#include "trafficdb.h"
 
32
#include "netlink.h"
 
33
#include "resources.h"
 
34
 
 
35
#define MMGUI_MIN_SMS_NUMBER_LENGTH      3
 
36
#define MMGUI_MAX_SMS_NUMBER_LENGTH      20
 
37
 
 
38
#define MMGUI_MIN_USSD_REQUEST_LENGTH    1
 
39
#define MMGUI_MAX_USSD_REQUEST_LENGTH    160
 
40
 
 
41
#define MMGUI_THREAD_STOP_CMD            0x00
 
42
 
 
43
gboolean mmguicore_devices_add(mmguicore_t mmguicore, mmguidevice_t device);
 
44
gboolean mmguicore_devices_remove(mmguicore_t mmguicore, guint deviceid);
 
45
gboolean mmguicore_devices_close(mmguicore_t mmguicore);
 
46
void mmguicore_networks_scan_free(GSList *networks);
 
47
static gchar *mmguicore_ussd_gsm7_to_ucs2(gchar *srcstr);
 
48
static void mmguicore_contacts_free(GSList *contacts);
 
49
static guint mmguicore_contacts_enum(mmguicore_t mmguicore);
 
50
static gpointer mmguicore_work_thread(gpointer data);
 
51
static void mmguicore_traffic_count(mmguicore_t mmguicore, guint64 rxbytes, guint64 txbytes);
 
52
static void mmguicore_traffic_zero(mmguicore_t mmguicore);
 
53
static gboolean mmgucore_get_device_traffic(mmguicore_t mmguicore, mmgui_traffic_stats_t stats);
 
54
static void mmguicore_traffic_limits(mmguicore_t mmguicore);
 
55
 
 
56
static void mmguicore_event_callback(enum _mmgui_event event, gpointer mmguicore, gpointer data)
 
57
{
 
58
        mmguicore_t mmguicorelc;
 
59
        gchar *ussdanswer;
 
60
                
 
61
        mmguicorelc = (mmguicore_t)mmguicore;
 
62
        if (mmguicorelc == NULL) return;
 
63
        
 
64
        switch (event) {
 
65
                case MMGUI_EVENT_DEVICE_ADDED:
 
66
                        mmguicore_devices_add(mmguicore, (mmguidevice_t)data);
 
67
                        if (mmguicorelc->extcb != NULL) {
 
68
                                (mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
 
69
                        }
 
70
                        break;
 
71
                case MMGUI_EVENT_DEVICE_REMOVED:
 
72
                        mmguicore_devices_remove(mmguicore, GPOINTER_TO_UINT(data));
 
73
                        if (mmguicorelc->extcb != NULL) {
 
74
                                (mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
 
75
                        }
 
76
                        break;
 
77
                case MMGUI_EVENT_DEVICE_ENABLED_STATUS:
 
78
                        if (mmguicorelc->extcb != NULL) {
 
79
                                (mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
 
80
                        }
 
81
                        break;
 
82
                case MMGUI_EVENT_DEVICE_BLOCKED_STATUS:
 
83
                        if (mmguicorelc->extcb != NULL) {
 
84
                                (mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
 
85
                        }
 
86
                        break;
 
87
                case MMGUI_EVENT_DEVICE_CONNECTION_STATUS:
 
88
                        if (mmguicorelc->extcb != NULL) {
 
89
                                (mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
 
90
                        }
 
91
                        break;
 
92
                
 
93
                case MMGUI_EVENT_SMS_LIST_READY:
 
94
                        if (mmguicorelc->extcb != NULL) {
 
95
                                (mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
 
96
                        }
 
97
                        break;
 
98
                case MMGUI_EVENT_SMS_COMPLETED:
 
99
                        if (mmguicorelc->extcb != NULL) {
 
100
                                (mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
 
101
                        }
 
102
                        break;
 
103
                case MMGUI_EVENT_SMS_SENT:
 
104
                        if (mmguicorelc->extcb != NULL) {
 
105
                                (mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
 
106
                        }
 
107
                        break;
 
108
                case MMGUI_EVENT_USSD_RESULT:
 
109
                        if (mmguicore_ussd_get_encoding(mmguicore) == MMGUI_USSD_ENCODING_GSM7) {
 
110
                                ussdanswer = (gchar *)data;
 
111
                        } else if (mmguicore_ussd_get_encoding(mmguicore) == MMGUI_USSD_ENCODING_UCS2) {
 
112
                                ussdanswer = mmguicore_ussd_gsm7_to_ucs2((gchar *)data);
 
113
                        }
 
114
                        if (mmguicorelc->extcb != NULL) {
 
115
                                (mmguicorelc->extcb)(event, mmguicorelc, ussdanswer, mmguicorelc->userdata);
 
116
                        }
 
117
                        break;
 
118
                case MMGUI_EVENT_SCAN_RESULT:
 
119
                        if (mmguicorelc->extcb != NULL) {
 
120
                                (mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
 
121
                        }
 
122
                        break;
 
123
                case MMGUI_EVENT_SIGNAL_LEVEL_CHANGE:
 
124
                        if (mmguicorelc->extcb != NULL) {
 
125
                                (mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
 
126
                        }
 
127
                        break;
 
128
                case MMGUI_EVENT_NETWORK_MODE_CHANGE:
 
129
                        if (mmguicorelc->extcb != NULL) {
 
130
                                (mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
 
131
                        }
 
132
                        break;
 
133
                case MMGUI_EVENT_NETWORK_REGISTRATION_CHANGE:
 
134
                        if (mmguicorelc->extcb != NULL) {
 
135
                                (mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
 
136
                        }
 
137
                        break;
 
138
                case MMGUI_EVENT_MODEM_ENABLE_RESULT:
 
139
                        /*Update device information*/
 
140
                        if (mmguicorelc->devices_information_func != NULL) {
 
141
                                (mmguicorelc->devices_information_func)(mmguicorelc);
 
142
                        }
 
143
                        if (mmguicorelc->extcb != NULL) {
 
144
                                (mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
 
145
                        }
 
146
                        break;
 
147
                
 
148
                
 
149
                default: 
 
150
                        
 
151
                        break;
 
152
        }
 
153
        
 
154
}
 
155
 
 
156
static void mmguicore_system_services_destroy_notify(gpointer data)
 
157
{
 
158
        if (data != NULL) g_free(data);
 
159
}
 
160
 
 
161
static GHashTable *mmguicore_system_services_enum(void)
 
162
{
 
163
        GDBusConnection *connection;
 
164
        GDBusProxy *proxy;
 
165
        GVariant *services;
 
166
        GError *error;
 
167
        GVariantIter siterl1, siterl2;
 
168
        GVariant *snodel1, *snodel2;
 
169
        gsize snamesize;
 
170
        gchar *servicename;
 
171
        GHashTable *serviceshash;
 
172
        
 
173
        error = NULL;
 
174
        
 
175
        connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
 
176
        
 
177
        if ((connection == NULL) && (error != NULL)) {
 
178
                g_debug("Core error: %s\n", error->message);
 
179
                g_error_free(error);
 
180
                return NULL;
 
181
        }
 
182
        
 
183
        error = NULL;
 
184
        
 
185
        proxy = g_dbus_proxy_new_sync(connection,
 
186
                                                                        G_DBUS_PROXY_FLAGS_NONE,
 
187
                                                                        NULL,
 
188
                                                                        "org.freedesktop.DBus",
 
189
                                                                        "/org/freedesktop/DBus",
 
190
                                                                        "org.freedesktop.DBus",
 
191
                                                                        NULL,
 
192
                                                                        &error);
 
193
        
 
194
        if ((proxy == NULL) && (error != NULL)) {
 
195
                g_debug("Core error: %s\n", error->message);
 
196
                g_error_free(error);
 
197
                g_object_unref(connection);
 
198
                return NULL;
 
199
        }
 
200
        
 
201
        error = NULL;
 
202
        
 
203
        services = g_dbus_proxy_call_sync(proxy,
 
204
                                                                        "ListNames",
 
205
                                                                        NULL,
 
206
                                                                        0,
 
207
                                                                        -1,
 
208
                                                                        NULL,
 
209
                                                                        &error);
 
210
        
 
211
        if ((services == NULL) && (error != NULL)) {
 
212
                g_debug("Core error: %s\n", error->message);
 
213
                g_error_free(error);
 
214
                g_object_unref(proxy);
 
215
                g_object_unref(connection);
 
216
                return NULL;
 
217
        }
 
218
        
 
219
        serviceshash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, mmguicore_system_services_destroy_notify);
 
220
        
 
221
        g_variant_iter_init(&siterl1, services);
 
222
        while ((snodel1 = g_variant_iter_next_value(&siterl1)) != NULL) {
 
223
                g_variant_iter_init(&siterl2, snodel1);
 
224
                while ((snodel2 = g_variant_iter_next_value(&siterl2)) != NULL) {
 
225
                        snamesize = 256;
 
226
                        servicename = g_strdup(g_variant_get_string(snodel2, &snamesize));
 
227
                        g_hash_table_insert(serviceshash, (gpointer)servicename, (gpointer)servicename);
 
228
                        g_variant_unref(snodel2);
 
229
                }
 
230
                g_variant_unref(snodel1);
 
231
    }
 
232
        
 
233
        g_variant_unref(services);
 
234
        g_object_unref(proxy);
 
235
        g_object_unref(connection);
 
236
        
 
237
        return serviceshash;
 
238
 
239
 
 
240
static gint mmguicore_modules_sort(gconstpointer a, gconstpointer b)
 
241
{
 
242
        mmguimodule_t mod1, mod2;
 
243
        
 
244
        mod1 = (mmguimodule_t)a;
 
245
        mod2 = (mmguimodule_t)b;
 
246
        
 
247
        if (mod1->priority == mod2->priority) {
 
248
                if (mod1->identifier == mod2->identifier) {
 
249
                        return 0;
 
250
                } else if (mod1->identifier > mod2->identifier) {
 
251
                        return 1;
 
252
                } else if (mod1->identifier < mod2->identifier) {
 
253
                        return -1;
 
254
                }
 
255
        } else if (mod1->priority > mod2->priority) {
 
256
                return 1;
 
257
        } else if (mod1->priority < mod2->priority) {
 
258
                return -1;
 
259
        }
 
260
}
 
261
 
 
262
guint mmguicore_modules_enum(mmguicore_t mmguicore)
 
263
{
 
264
        GHashTable *services;
 
265
        guint number = 0;
 
266
        GDir *moddir;
 
267
        const gchar *modname;
 
268
        gsize length;
 
269
        const gchar modext[] = ".so";
 
270
        gchar *modpath;
 
271
        GModule *module;
 
272
        mmgui_module_init_func module_init;
 
273
        gboolean applicable;
 
274
        struct _mmguimodule smodule, *dmodule;
 
275
                
 
276
        if (mmguicore == NULL) return 0;
 
277
        
 
278
        services = mmguicore_system_services_enum();
 
279
        
 
280
        if (services == NULL) return 0;
 
281
        
 
282
        moddir = g_dir_open(RESOURCE_MODULES_DIR, 0, NULL);
 
283
        if (moddir != NULL) {
 
284
                while ((modname = g_dir_read_name(moddir)) != NULL) {
 
285
                        //Test file extension and filename length
 
286
                        length = strlen(modname);
 
287
                        if ((length > 3) && (length < 256) && (strncmp((const char *)modname + length - 3, (const char *)&modext, 3) == 0)) {
 
288
                                modpath = g_strconcat(RESOURCE_MODULES_DIR, modname, NULL);
 
289
                                if (g_file_test(modpath, G_FILE_TEST_EXISTS)) {
 
290
                                        //Open module
 
291
                                        module = g_module_open(modpath, G_MODULE_BIND_LAZY);
 
292
                                        if (module != NULL) {
 
293
                                                //Call init function
 
294
                                                if (g_module_symbol(module, "mmgui_module_init", (gpointer*)&module_init)) {
 
295
                                                        if (module_init(&smodule)) {
 
296
                                                                //Test service/file existence
 
297
                                                                applicable = FALSE;
 
298
                                                                switch (smodule.requirement) {
 
299
                                                                        case MMGUI_MODULE_REQUIREMENT_SERVICE:
 
300
                                                                                if (g_hash_table_lookup(services, smodule.servicename) != NULL) {
 
301
                                                                                        applicable = TRUE;
 
302
                                                                                }
 
303
                                                                                break;
 
304
                                                                        case MMGUI_MODULE_REQUIREMENT_FILE:
 
305
                                                                                if (g_file_test(smodule.servicename, G_FILE_TEST_EXISTS)) {
 
306
                                                                                        applicable = TRUE;
 
307
                                                                                }
 
308
                                                                                break;
 
309
                                                                        case MMGUI_MODULE_REQUIREMENT_NONE:
 
310
                                                                                applicable = TRUE;
 
311
                                                                                break;
 
312
                                                                        default:
 
313
                                                                                break;
 
314
                                                                }
 
315
                                                                //Add service to list if applicable
 
316
                                                                if (applicable) {
 
317
                                                                        dmodule = g_malloc0(sizeof(struct _mmguimodule));
 
318
                                                                        memcpy(dmodule, &smodule, sizeof(struct _mmguimodule));
 
319
                                                                        strncpy(dmodule->filename, modname, length);
 
320
                                                                        dmodule->filename[length] = '\0';
 
321
                                                                        mmguicore->modules = g_slist_prepend(mmguicore->modules, dmodule);
 
322
                                                                        g_printf("Module applicable: %s (%s)\n", dmodule->description, dmodule->filename);
 
323
                                                                        number++;
 
324
                                                                }
 
325
                                                        }
 
326
                                                }
 
327
                                                //Close module
 
328
                                                g_module_close(module);
 
329
                                        }
 
330
                                }
 
331
                                g_free(modpath);
 
332
                        }
 
333
                }
 
334
                g_dir_close(moddir);
 
335
        }
 
336
        
 
337
        if (number > 0) {
 
338
                mmguicore->modules = g_slist_sort(mmguicore->modules, mmguicore_modules_sort);
 
339
                mmguicore->modules = g_slist_reverse(mmguicore->modules);
 
340
        }
 
341
        
 
342
        g_hash_table_destroy(services);
 
343
        
 
344
        return number;
 
345
 
346
 
 
347
static gboolean mmguicore_modules_free(mmguicore_t mmguicore)
 
348
{
 
349
        if (mmguicore == NULL) return FALSE;
 
350
        if (mmguicore->modules == NULL) return FALSE;
 
351
        
 
352
        g_slist_free(mmguicore->modules);
 
353
        
 
354
        return TRUE;
 
355
}
 
356
 
 
357
static gboolean mmguicore_modules_mm_open(mmguicore_t mmguicore, mmguimodule_t mmguimodule)
 
358
{
 
359
        gboolean openstatus; 
 
360
        gchar *modulepath;
 
361
        
 
362
        if ((mmguicore == NULL) || (mmguimodule == NULL)) return FALSE;
 
363
        
 
364
        if (mmguimodule->type == MMGUI_MODULE_TYPE_CONNECTION_MANGER) return FALSE;
 
365
        
 
366
        modulepath = g_strconcat(RESOURCE_MODULES_DIR, mmguimodule->filename, NULL);
 
367
        mmguicore->module = g_module_open(modulepath, G_MODULE_BIND_LAZY);
 
368
        if (mmguicore->module != NULL) {
 
369
                openstatus = TRUE;
 
370
                //Module function pointers
 
371
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_open", (gpointer *)&(mmguicore->open_func));
 
372
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_close", (gpointer *)&(mmguicore->close_func));
 
373
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_last_error", (gpointer *)&(mmguicore->last_error_func));
 
374
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_interrupt_operation", (gpointer *)&(mmguicore->interrupt_operation_func));
 
375
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_set_timeout", (gpointer *)&(mmguicore->set_timeout_func));
 
376
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_devices_enum", (gpointer *)&(mmguicore->devices_enum_func));
 
377
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_devices_open", (gpointer *)&(mmguicore->devices_open_func));
 
378
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_devices_close", (gpointer *)&(mmguicore->devices_close_func));
 
379
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_devices_state", (gpointer *)&(mmguicore->devices_state_func));
 
380
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_devices_update_state", (gpointer *)&(mmguicore->devices_update_state_func));
 
381
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_devices_information", (gpointer *)&(mmguicore->devices_information_func));
 
382
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_devices_enable", (gpointer *)&(mmguicore->devices_enable_func));
 
383
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_sms_enum", (gpointer *)&(mmguicore->sms_enum_func));
 
384
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_sms_get", (gpointer *)&(mmguicore->sms_get_func));
 
385
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_sms_delete", (gpointer *)&(mmguicore->sms_delete_func));
 
386
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_sms_send", (gpointer *)&(mmguicore->sms_send_func));
 
387
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_ussd_cancel_session", (gpointer *)&(mmguicore->ussd_cancel_session_func));
 
388
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_ussd_get_state", (gpointer *)&(mmguicore->ussd_get_state_func));
 
389
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_ussd_send", (gpointer *)&(mmguicore->ussd_send_func));
 
390
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_networks_scan", (gpointer *)&(mmguicore->networks_scan_func));
 
391
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_contacts_enum", (gpointer *)&(mmguicore->contacts_enum_func));
 
392
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_contacts_delete", (gpointer *)&(mmguicore->contacts_delete_func));
 
393
                openstatus = openstatus && g_module_symbol(mmguicore->module, "mmgui_module_contacts_add", (gpointer *)&(mmguicore->contacts_add_func));
 
394
                if (!openstatus) {
 
395
                        //Module function pointers
 
396
                        mmguicore->open_func = NULL;
 
397
                        mmguicore->close_func = NULL;
 
398
                        mmguicore->last_error_func = NULL;
 
399
                        mmguicore->interrupt_operation_func = NULL;
 
400
                        mmguicore->set_timeout_func = NULL;
 
401
                        mmguicore->devices_enum_func = NULL;
 
402
                        mmguicore->devices_open_func = NULL;
 
403
                        mmguicore->devices_close_func = NULL;
 
404
                        mmguicore->devices_state_func = NULL;
 
405
                        mmguicore->devices_update_state_func = NULL;
 
406
                        mmguicore->devices_information_func = NULL;
 
407
                        mmguicore->devices_enable_func = NULL;
 
408
                        mmguicore->sms_enum_func = NULL;
 
409
                        mmguicore->sms_get_func = NULL;
 
410
                        mmguicore->sms_delete_func = NULL;
 
411
                        mmguicore->sms_send_func = NULL;
 
412
                        mmguicore->ussd_cancel_session_func = NULL;
 
413
                        mmguicore->ussd_get_state_func = NULL;
 
414
                        mmguicore->ussd_send_func = NULL;
 
415
                        mmguicore->networks_scan_func = NULL;
 
416
                        mmguicore->contacts_enum_func = NULL;
 
417
                        mmguicore->contacts_delete_func = NULL;
 
418
                        mmguicore->contacts_add_func = NULL;
 
419
                        g_module_close(mmguicore->module);
 
420
                        g_printf("Failed to load modem manager: %s\n", mmguimodule->description);
 
421
                }
 
422
        } else {
 
423
                openstatus = FALSE;
 
424
        }
 
425
        g_free(modulepath);
 
426
        
 
427
        if (openstatus) {
 
428
                mmguicore->moduleptr = mmguimodule;
 
429
                (mmguicore->open_func)(mmguicore);
 
430
                g_printf("Modem manager: %s\n", mmguimodule->description);
 
431
        } else {
 
432
                mmguicore->moduleptr = NULL;
 
433
                mmguicore->module = NULL;
 
434
        }
 
435
        
 
436
        return openstatus;
 
437
}
 
438
 
 
439
static gboolean mmguicore_modules_cm_open(mmguicore_t mmguicore, mmguimodule_t mmguimodule)
 
440
{
 
441
        gboolean openstatus; 
 
442
        gchar *modulepath;
 
443
                
 
444
        if ((mmguicore == NULL) || (mmguimodule == NULL)) return FALSE;
 
445
        
 
446
        if (mmguimodule->type == MMGUI_MODULE_TYPE_MODEM_MANAGER) return FALSE;
 
447
        
 
448
        modulepath = g_strconcat(RESOURCE_MODULES_DIR, mmguimodule->filename, NULL);
 
449
        mmguicore->cmodule = g_module_open(modulepath, G_MODULE_BIND_LAZY);
 
450
        if (mmguicore->cmodule != NULL) {
 
451
                openstatus = TRUE;
 
452
                //Module function pointers
 
453
                openstatus = openstatus && g_module_symbol(mmguicore->cmodule, "mmgui_module_connection_open", (gpointer *)&(mmguicore->connection_open_func));
 
454
                openstatus = openstatus && g_module_symbol(mmguicore->cmodule, "mmgui_module_connection_close", (gpointer *)&(mmguicore->connection_close_func));
 
455
                openstatus = openstatus && g_module_symbol(mmguicore->cmodule, "mmgui_module_connection_last_error", (gpointer *)&(mmguicore->connection_last_error_func));
 
456
                openstatus = openstatus && g_module_symbol(mmguicore->cmodule, "mmgui_module_device_connection_open", (gpointer *)&(mmguicore->device_connection_open_func));
 
457
                openstatus = openstatus && g_module_symbol(mmguicore->cmodule, "mmgui_module_device_connection_close", (gpointer *)&(mmguicore->device_connection_close_func));
 
458
                openstatus = openstatus && g_module_symbol(mmguicore->cmodule, "mmgui_module_device_connection_status", (gpointer *)&(mmguicore->device_connection_status_func));
 
459
                openstatus = openstatus && g_module_symbol(mmguicore->cmodule, "mmgui_module_device_connection_timestamp", (gpointer *)&(mmguicore->device_connection_timestamp_func));
 
460
                openstatus = openstatus && g_module_symbol(mmguicore->cmodule, "mmgui_module_device_connection_disconnect", (gpointer *)&(mmguicore->device_connection_disconnect_func));
 
461
                                
 
462
                if (!openstatus) {
 
463
                        //Module function pointers
 
464
                        mmguicore->connection_open_func = NULL;
 
465
                        mmguicore->connection_close_func = NULL;
 
466
                        mmguicore->connection_last_error_func = NULL;
 
467
                        mmguicore->device_connection_open_func = NULL;
 
468
                        mmguicore->device_connection_close_func = NULL;
 
469
                        mmguicore->device_connection_status_func = NULL;
 
470
                        mmguicore->device_connection_timestamp_func = NULL;
 
471
                        mmguicore->device_connection_disconnect_func = NULL;
 
472
                        
 
473
                        g_module_close(mmguicore->cmodule);
 
474
                }
 
475
        } else {
 
476
                openstatus = FALSE;
 
477
        }
 
478
        g_free(modulepath);
 
479
        
 
480
        if (openstatus) {
 
481
                mmguicore->cmoduleptr = mmguimodule;
 
482
                (mmguicore->connection_open_func)(mmguicore);
 
483
                g_printf("Connection manager: %s\n", mmguimodule->description);
 
484
        } else {
 
485
                mmguicore->cmoduleptr = NULL;
 
486
                mmguicore->cmodule = NULL;
 
487
        }
 
488
        
 
489
        return openstatus;
 
490
}
 
491
 
 
492
static gboolean mmguicore_modules_close(mmguicore_t mmguicore)
 
493
{
 
494
        if (mmguicore == NULL) return FALSE;
 
495
        
 
496
        //Modem manager module functions 
 
497
        if (mmguicore->module != NULL) {
 
498
                if (mmguicore->close_func != NULL) {
 
499
                        mmguicore->close_func(mmguicore);
 
500
                }
 
501
                g_module_close(mmguicore->module);
 
502
                mmguicore->module = NULL;
 
503
                //Module function pointers
 
504
                mmguicore->open_func = NULL;
 
505
                mmguicore->close_func = NULL;
 
506
                mmguicore->last_error_func = NULL;
 
507
                mmguicore->devices_enum_func = NULL;
 
508
                mmguicore->devices_open_func = NULL;
 
509
                mmguicore->devices_close_func = NULL;
 
510
                mmguicore->devices_state_func = NULL;
 
511
                mmguicore->devices_update_state_func = NULL;
 
512
                mmguicore->devices_information_func = NULL;
 
513
                mmguicore->devices_enable_func = NULL;
 
514
                mmguicore->sms_enum_func = NULL;
 
515
                mmguicore->sms_get_func = NULL;
 
516
                mmguicore->sms_delete_func = NULL;
 
517
                mmguicore->sms_send_func = NULL;
 
518
                mmguicore->ussd_cancel_session_func = NULL;
 
519
                mmguicore->ussd_get_state_func = NULL;
 
520
                mmguicore->ussd_send_func = NULL;
 
521
                mmguicore->networks_scan_func = NULL;
 
522
                mmguicore->contacts_enum_func = NULL;
 
523
                mmguicore->contacts_delete_func = NULL;
 
524
                mmguicore->contacts_add_func = NULL;
 
525
                
 
526
                mmguicore->moduleptr = NULL;
 
527
        }
 
528
        
 
529
        //Connection manager module functions
 
530
        if (mmguicore->cmodule != NULL) {
 
531
                if (mmguicore->connection_close_func != NULL) {
 
532
                        mmguicore->connection_close_func(mmguicore);
 
533
                }
 
534
                g_module_close(mmguicore->cmodule);
 
535
                mmguicore->cmodule = NULL;
 
536
                //Module function pointers
 
537
                mmguicore->connection_open_func = NULL;
 
538
                mmguicore->connection_close_func = NULL;
 
539
                mmguicore->connection_last_error_func = NULL;
 
540
                mmguicore->device_connection_open_func = NULL;
 
541
                mmguicore->device_connection_close_func = NULL;
 
542
                mmguicore->device_connection_status_func = NULL;
 
543
                mmguicore->device_connection_timestamp_func = NULL;
 
544
                mmguicore->device_connection_disconnect_func = NULL;
 
545
                
 
546
                mmguicore->cmoduleptr = NULL;
 
547
        }
 
548
        
 
549
        return TRUE;
 
550
}
 
551
 
 
552
static gboolean mmguicore_modules_select(mmguicore_t mmguicore)
 
553
{
 
554
        GSList *iterator;
 
555
        mmguimodule_t module;
 
556
        gboolean mmfound, cmfound;
 
557
        
 
558
        if (mmguicore == NULL) return FALSE;
 
559
        if (mmguicore->modules == NULL) return FALSE;
 
560
        
 
561
        if ((mmguicore->module != NULL) || (mmguicore->cmodule != NULL)) {
 
562
                mmguicore_modules_close(mmguicore);
 
563
        }
 
564
        
 
565
        mmfound = FALSE;
 
566
        cmfound = FALSE;
 
567
        
 
568
        for (iterator=mmguicore->modules; iterator; iterator=iterator->next) {
 
569
                module = iterator->data;
 
570
                if ((module->type == MMGUI_MODULE_TYPE_MODEM_MANAGER) && (!mmfound)) {
 
571
                        mmfound = mmguicore_modules_mm_open(mmguicore, module);
 
572
                } else if ((module->type == MMGUI_MODULE_TYPE_CONNECTION_MANGER) && (!cmfound)) {
 
573
                        cmfound = mmguicore_modules_cm_open(mmguicore, module);
 
574
                } else if ((mmfound) && (cmfound)) {
 
575
                        break;
 
576
                }
 
577
        }
 
578
                
 
579
        return mmfound;
 
580
}
 
581
 
 
582
static void mmguicore_devices_free_single(mmguidevice_t device)
 
583
{
 
584
        if (device != NULL) return;
 
585
        
 
586
        if (device->manufacturer != NULL) {
 
587
                g_free(device->manufacturer);
 
588
        }
 
589
        if (device->model != NULL) {
 
590
                g_free(device->model);
 
591
        }
 
592
        if (device->version != NULL) {
 
593
                g_free(device->version);
 
594
        }
 
595
        if (device->port != NULL) {
 
596
                g_free(device->port);
 
597
        }
 
598
        if (device->objectpath != NULL) {
 
599
                g_free(device->objectpath);
 
600
        }
 
601
        if (device->sysfspath != NULL) {
 
602
                g_free(device->sysfspath);
 
603
        }
 
604
        if (device->internalid != NULL) {
 
605
                g_free(device->internalid);
 
606
        }
 
607
        if (device->persistentid != NULL) {
 
608
                g_free(device->persistentid);
 
609
        }
 
610
        if (device->imei != NULL) {
 
611
                g_free(device->imei);
 
612
        }
 
613
        if (device->imsi != NULL) {
 
614
                g_free(device->imsi);
 
615
        }
 
616
        if (device->operatorcode != NULL) {
 
617
                g_free(device->operatorcode);
 
618
        }
 
619
}
 
620
 
 
621
static void mmguicore_devices_free_foreach(gpointer data, gpointer user_data)
 
622
{
 
623
        mmguidevice_t device;
 
624
        
 
625
        if (data != NULL) return;
 
626
        
 
627
        device = (mmguidevice_t)data;
 
628
        
 
629
        mmguicore_devices_free_single(device);
 
630
}
 
631
 
 
632
static void mmguicore_devices_free(mmguicore_t mmguicore)
 
633
{
 
634
        if (mmguicore == NULL) return;
 
635
        
 
636
        g_slist_foreach(mmguicore->devices, mmguicore_devices_free_foreach, NULL);
 
637
                
 
638
        g_slist_free(mmguicore->devices);
 
639
        
 
640
        mmguicore->devices = NULL;
 
641
}
 
642
 
 
643
gboolean mmguicore_devices_enum(mmguicore_t mmguicore)
 
644
{
 
645
        GSList *iterator;
 
646
        mmguidevice_t device;
 
647
        
 
648
        if ((mmguicore == NULL) || (mmguicore->devices_enum_func == NULL)) return FALSE;
 
649
        
 
650
        if (mmguicore->devices != NULL) {
 
651
                mmguicore_devices_free(mmguicore);
 
652
        }
 
653
        
 
654
        (mmguicore->devices_enum_func)(mmguicore, &(mmguicore->devices));
 
655
        
 
656
        for (iterator=mmguicore->devices; iterator; iterator=iterator->next) {
 
657
                device = iterator->data;
 
658
                printf("Device: %s, %s, %s [%u] [%s]\n", device->manufacturer, device->model, device->version, device->id, device->persistentid);
 
659
        }
 
660
                
 
661
        return TRUE;
 
662
}
 
663
 
 
664
gboolean mmguicore_devices_add(mmguicore_t mmguicore, mmguidevice_t device)
 
665
{
 
666
        if ((mmguicore == NULL) || (device == NULL)) return FALSE;
 
667
        
 
668
        mmguicore->devices = g_slist_append(mmguicore->devices, device);
 
669
        
 
670
        g_printf("Device successfully added\n");
 
671
        
 
672
        return TRUE;
 
673
}
 
674
 
 
675
static gint mmguicore_devices_remove_compare(gconstpointer a, gconstpointer b)
 
676
{
 
677
        mmguidevice_t device;
 
678
        guint id;
 
679
        
 
680
        device = (mmguidevice_t)a;
 
681
        id = GPOINTER_TO_UINT(b);
 
682
        
 
683
        if (device->id < id) {
 
684
                return 1;
 
685
        } else if (device->id > id) {
 
686
                return -1;
 
687
        } else {
 
688
                return 0;
 
689
        }
 
690
}
 
691
 
 
692
gboolean mmguicore_devices_remove(mmguicore_t mmguicore, guint deviceid)
 
693
{
 
694
        GSList *deviceptr;
 
695
        
 
696
        if (mmguicore == NULL) return FALSE;
 
697
        if (mmguicore->devices == NULL) return FALSE;
 
698
        
 
699
        deviceptr = g_slist_find_custom(mmguicore->devices, GUINT_TO_POINTER(deviceid), mmguicore_devices_remove_compare);
 
700
        
 
701
        if (deviceptr != NULL) {
 
702
                if (mmguicore->device != NULL) {
 
703
                        if (mmguicore->device->id == deviceid) {
 
704
                                //Close currently opened device
 
705
                                mmguicore_devices_close(mmguicore);
 
706
                        }
 
707
                }
 
708
                //Remove device structure from list
 
709
                mmguicore->devices = g_slist_remove(mmguicore->devices, deviceptr->data);
 
710
                //Free device structure
 
711
                mmguicore_devices_free_single(deviceptr->data);
 
712
                //g_printf("Device successfully removed\n");
 
713
                return TRUE;
 
714
        } else {
 
715
                return FALSE;
 
716
        }
 
717
}
 
718
 
 
719
static gint mmguicore_devices_open_compare(gconstpointer a, gconstpointer b)
 
720
{
 
721
        mmguidevice_t device;
 
722
        guint id;
 
723
        
 
724
        device = (mmguidevice_t)a;
 
725
        id = GPOINTER_TO_UINT(b);
 
726
        
 
727
        if (device->id < id) {
 
728
                return 1;
 
729
        } else if (device->id > id) {
 
730
                return -1;
 
731
        } else {
 
732
                return 0;
 
733
        }
 
734
}
 
735
 
 
736
gboolean mmguicore_devices_open(mmguicore_t mmguicore, guint deviceid, gboolean openfirst)
 
737
{
 
738
        GSList *deviceptr;
 
739
        
 
740
        if (mmguicore == NULL) return FALSE;
 
741
        if ((mmguicore->devices == NULL) || (mmguicore->devices_open_func == NULL)) return FALSE;
 
742
        
 
743
        deviceptr = g_slist_find_custom(mmguicore->devices, GUINT_TO_POINTER(deviceid), mmguicore_devices_open_compare);
 
744
        
 
745
        if (deviceptr != NULL) {
 
746
                //Test currently opened device
 
747
                if (mmguicore->device != NULL) {
 
748
                        if (mmguicore->device->id == deviceid) {
 
749
                                //Already opened
 
750
                                return TRUE;
 
751
                        } else {
 
752
                                //Close currently opened device
 
753
                                mmguicore_devices_close(mmguicore);
 
754
                        }
 
755
                }
 
756
                if ((mmguicore->devices_open_func)(mmguicore, deviceptr->data)) {
 
757
                        mmguicore->device = deviceptr->data;
 
758
                        //Update device information
 
759
                        if (mmguicore->devices_information_func != NULL) {
 
760
                                (mmguicore->devices_information_func)(mmguicore);
 
761
                                //Open SMS database
 
762
                                mmguicore->device->smsdb = mmgui_smsdb_open(mmguicore->device->persistentid, mmguicore->device->internalid);
 
763
                                //Open traffic database
 
764
                                mmguicore->device->trafficdb = mmgui_trafficdb_open(mmguicore->device->persistentid, mmguicore->device->internalid);
 
765
                                //Open contacts
 
766
                                mmguicore_contacts_enum(mmguicore);
 
767
                                //For Huawei modem USSD answers must be converted
 
768
                                if (g_ascii_strcasecmp(mmguicore->device->manufacturer, "huawei") == 0) {
 
769
                                        mmguicore->device->ussdencoding = MMGUI_USSD_ENCODING_UCS2;
 
770
                                } else {
 
771
                                        mmguicore->device->ussdencoding = MMGUI_USSD_ENCODING_GSM7;
 
772
                                }
 
773
                        }
 
774
                        //Open connection statistics source
 
775
                        if (mmguicore->device_connection_open_func != NULL) {
 
776
                                (mmguicore->device_connection_open_func)(mmguicore, deviceptr->data);
 
777
                        }
 
778
                        g_printf("Device successfully opened\n");
 
779
                        return TRUE;
 
780
                }
 
781
        } else if ((openfirst) && (deviceptr == NULL) && (mmguicore->devices != NULL)) {
 
782
                //Open first available device if specified is not found
 
783
                if (mmguicore->devices->data != NULL) {
 
784
                        if (mmguicore->device != NULL) {
 
785
                                //Close currently opened device
 
786
                                mmguicore_devices_close(mmguicore);
 
787
                        }
 
788
                        
 
789
                        if ((mmguicore->devices_open_func)(mmguicore, mmguicore->devices->data)) {
 
790
                                mmguicore->device = mmguicore->devices->data;
 
791
                                //Update device information
 
792
                                if (mmguicore->devices_information_func != NULL) {
 
793
                                        (mmguicore->devices_information_func)(mmguicore);
 
794
                                        //Open SMS database
 
795
                                        mmguicore->device->smsdb = mmgui_smsdb_open(mmguicore->device->persistentid, mmguicore->device->internalid);
 
796
                                        //Open traffic database
 
797
                                        mmguicore->device->trafficdb = mmgui_trafficdb_open(mmguicore->device->persistentid, mmguicore->device->internalid);
 
798
                                        //Open contacts
 
799
                                        mmguicore_contacts_enum(mmguicore);
 
800
                                        //For Huawei modem USSD answers must be converted
 
801
                                        if (g_ascii_strcasecmp(mmguicore->device->manufacturer, "huawei") == 0) {
 
802
                                                mmguicore->device->ussdencoding = MMGUI_USSD_ENCODING_UCS2;
 
803
                                        } else {
 
804
                                                mmguicore->device->ussdencoding = MMGUI_USSD_ENCODING_GSM7;
 
805
                                        }
 
806
                                }
 
807
                                //Open connection statistics source
 
808
                                if (mmguicore->device_connection_open_func != NULL) {
 
809
                                        (mmguicore->device_connection_open_func)(mmguicore, mmguicore->devices->data);
 
810
                                }
 
811
                                g_printf("First available device successfully opened\n");
 
812
                                return TRUE;
 
813
                        }
 
814
                }
 
815
        }
 
816
        
 
817
        return FALSE;
 
818
}
 
819
 
 
820
gboolean mmguicore_devices_close(mmguicore_t mmguicore)
 
821
{
 
822
        gboolean result;
 
823
        
 
824
        #if GLIB_CHECK_VERSION(2,32,0)
 
825
                g_mutex_lock(&mmguicore->workthreadmutex);
 
826
        #else
 
827
                g_mutex_lock(mmguicore->workthreadmutex);
 
828
        #endif
 
829
        
 
830
        result = FALSE; 
 
831
        
 
832
        if (mmguicore->device != NULL) {
 
833
                if ((mmguicore->devices_close_func)(mmguicore)) {
 
834
                        //Close SMS database
 
835
                        mmguicore->device->smscaps = MMGUI_SMS_CAPS_NONE;
 
836
                        mmgui_smsdb_close(mmguicore->device->smsdb);
 
837
                        mmguicore->device->smsdb = NULL;
 
838
                        //Close contacts
 
839
                        mmguicore->device->contactscaps = MMGUI_CONTACTS_CAPS_NONE;
 
840
                        mmguicore_contacts_free(mmguicore->device->contactslist);
 
841
                        mmguicore->device->contactslist = NULL;
 
842
                        //Info
 
843
                        if (mmguicore->device->operatorname != NULL) {
 
844
                                g_free(mmguicore->device->operatorname);
 
845
                                mmguicore->device->operatorname = NULL;
 
846
                        }
 
847
                        if (mmguicore->device->operatorcode != NULL) {
 
848
                                g_free(mmguicore->device->operatorcode);
 
849
                                mmguicore->device->operatorcode = NULL;
 
850
                        }
 
851
                        if (mmguicore->device->imei != NULL) {
 
852
                                g_free(mmguicore->device->imei);
 
853
                                mmguicore->device->imei = NULL;
 
854
                        }
 
855
                        if (mmguicore->device->imsi != NULL) {
 
856
                                g_free(mmguicore->device->imsi);
 
857
                                mmguicore->device->imsi = NULL;
 
858
                        }
 
859
                        //USSD
 
860
                        mmguicore->device->ussdcaps = MMGUI_USSD_CAPS_NONE;
 
861
                        mmguicore->device->ussdencoding = MMGUI_USSD_ENCODING_GSM7;
 
862
                        //Location
 
863
                        mmguicore->device->locationcaps = MMGUI_LOCATION_CAPS_NONE;
 
864
                        memset(mmguicore->device->loc3gppdata, 0, sizeof(mmguicore->device->loc3gppdata));
 
865
                        memset(mmguicore->device->locgpsdata, 0, sizeof(mmguicore->device->locgpsdata));
 
866
                        //Scan
 
867
                        mmguicore->device->scancaps = MMGUI_SCAN_CAPS_NONE;
 
868
                        //Close traffic database session
 
869
                        mmgui_trafficdb_session_close(mmguicore->device->trafficdb);
 
870
                        //Close traffic database
 
871
                        mmgui_trafficdb_close(mmguicore->device->trafficdb);
 
872
                        mmguicore->device->trafficdb = NULL;
 
873
                        //Traffic
 
874
                        mmguicore->device->rxbytes = 0;
 
875
                        mmguicore->device->txbytes = 0;
 
876
                        mmguicore->device->sessiontime = 0;
 
877
                        mmguicore->device->speedchecktime = 0;
 
878
                        mmguicore->device->smschecktime = 0;
 
879
                        mmguicore->device->speedindex = 0;
 
880
                        mmguicore->device->connected = FALSE;
 
881
                        memset(mmguicore->device->speedvalues, 0, sizeof(mmguicore->device->speedvalues));
 
882
                        memset(mmguicore->device->interface, 0, sizeof(mmguicore->device->interface));
 
883
                        //Zero traffic values in UI
 
884
                        mmguicore_traffic_zero(mmguicore);
 
885
                        //Close connection state source
 
886
                        if (mmguicore->device_connection_close_func != NULL) {
 
887
                                (mmguicore->device_connection_close_func)(mmguicore);
 
888
                        }
 
889
                        //Device
 
890
                        mmguicore->device = NULL;
 
891
                        //Successfully closed
 
892
                        g_printf("Device successfully closed\n");
 
893
                        result = TRUE;
 
894
                }
 
895
        }
 
896
        
 
897
        #if GLIB_CHECK_VERSION(2,32,0)
 
898
                g_mutex_unlock(&mmguicore->workthreadmutex);
 
899
        #else
 
900
                g_mutex_unlock(mmguicore->workthreadmutex);
 
901
        #endif
 
902
        
 
903
        return result;
 
904
}
 
905
 
 
906
gboolean mmguicore_devices_enable(mmguicore_t mmguicore, gboolean enabled)
 
907
{
 
908
        if (mmguicore == NULL) return FALSE;
 
909
        if ((mmguicore->device == NULL) || (mmguicore->devices_enable_func == NULL)) return FALSE;
 
910
        
 
911
        return (mmguicore->devices_enable_func)(mmguicore, enabled);
 
912
}
 
913
 
 
914
GSList *mmguicore_devices_get_list(mmguicore_t mmguicore)
 
915
{
 
916
        if (mmguicore == NULL) return NULL;
 
917
        
 
918
        return mmguicore->devices;
 
919
}
 
920
 
 
921
mmguidevice_t mmguicore_devices_get_current(mmguicore_t mmguicore)
 
922
{
 
923
        if (mmguicore == NULL) return NULL;
 
924
        
 
925
        return mmguicore->device;
 
926
}
 
927
 
 
928
gboolean mmguicore_devices_get_enabled(mmguicore_t mmguicore)
 
929
{
 
930
        if (mmguicore == NULL) return FALSE;
 
931
        if ((mmguicore->device == NULL) || (mmguicore->devices_state_func == NULL)) return FALSE;
 
932
        
 
933
        return (mmguicore->devices_state_func)(mmguicore, MMGUI_DEVICE_STATE_REQUEST_ENABLED);
 
934
}
 
935
 
 
936
gboolean mmguicore_devices_get_locked(mmguicore_t mmguicore)
 
937
{
 
938
        if (mmguicore == NULL) return FALSE;
 
939
        if ((mmguicore->device == NULL) || (mmguicore->devices_state_func == NULL)) return FALSE;
 
940
        
 
941
        return (mmguicore->devices_state_func)(mmguicore, MMGUI_DEVICE_STATE_REQUEST_LOCKED);
 
942
}
 
943
 
 
944
gboolean mmguicore_devices_get_registered(mmguicore_t mmguicore)
 
945
{
 
946
        if (mmguicore == NULL) return FALSE;
 
947
        if ((mmguicore->device == NULL) || (mmguicore->devices_state_func == NULL)) return FALSE;
 
948
        
 
949
        return (mmguicore->devices_state_func)(mmguicore, MMGUI_DEVICE_STATE_REQUEST_REGISTERED);
 
950
}
 
951
 
 
952
gboolean mmguicore_devices_get_connected(mmguicore_t mmguicore)
 
953
{
 
954
        if (mmguicore == NULL) return FALSE;
 
955
        if (mmguicore->device == NULL) return FALSE;
 
956
        
 
957
        return mmguicore->device->connected;
 
958
}
 
959
 
 
960
gboolean mmguicore_devices_update_device_state(mmguicore_t mmguicore)
 
961
{
 
962
        gboolean updated;
 
963
        
 
964
        if (mmguicore == NULL) return FALSE;
 
965
        if ((mmguicore->device == NULL) || (mmguicore->devices_update_state_func == NULL)) return FALSE;
 
966
        
 
967
        updated = FALSE;
 
968
        
 
969
        updated = (mmguicore->devices_update_state_func)(mmguicore);
 
970
        
 
971
        return updated;
 
972
}
 
973
 
 
974
const gchar *mmguicore_devices_get_identifier(mmguicore_t mmguicore)
 
975
{
 
976
        if (mmguicore == NULL) return NULL;
 
977
        if (mmguicore->device == NULL) return NULL;
 
978
        
 
979
        return (const gchar *)mmguicore->device->persistentid;
 
980
}
 
981
 
 
982
const gchar *mmguicore_devices_get_internal_identifier(mmguicore_t mmguicore)
 
983
{
 
984
        if (mmguicore == NULL) return NULL;
 
985
        if (mmguicore->device == NULL) return NULL;
 
986
        
 
987
        return (const gchar *)mmguicore->device->internalid;
 
988
}
 
989
 
 
990
gpointer mmguicore_devices_get_sms_db(mmguicore_t mmguicore)
 
991
{
 
992
        if (mmguicore == NULL) return NULL;
 
993
        if (mmguicore->device == NULL) return NULL;
 
994
        
 
995
        return (gpointer)mmguicore->device->smsdb;
 
996
}
 
997
 
 
998
gpointer mmguicore_devices_get_traffic_db(mmguicore_t mmguicore)
 
999
{
 
1000
        if (mmguicore == NULL) return NULL;
 
1001
        if (mmguicore->device == NULL) return NULL;
 
1002
        
 
1003
        return (gpointer)mmguicore->device->trafficdb;
 
1004
}
 
1005
 
 
1006
gboolean mmguicore_devices_get_connection_status(mmguicore_t mmguicore)
 
1007
{
 
1008
        if (mmguicore == NULL) return FALSE;
 
1009
        if ((mmguicore->device == NULL) || (mmguicore->device_connection_status_func == NULL)) return FALSE;
 
1010
        
 
1011
        return (mmguicore->device_connection_status_func)(mmguicore);
 
1012
}
 
1013
 
 
1014
guint64 mmguicore_devices_get_connection_timestamp(mmguicore_t mmguicore)
 
1015
{
 
1016
        guint64 timestamp;
 
1017
        
 
1018
        timestamp = (guint64)time(NULL);
 
1019
        
 
1020
        if (mmguicore == NULL) return timestamp;
 
1021
        if ((mmguicore->device == NULL) || (mmguicore->device_connection_timestamp_func == NULL)) return timestamp;
 
1022
        
 
1023
        timestamp = (mmguicore->device_connection_timestamp_func)(mmguicore);
 
1024
        
 
1025
        return timestamp;
 
1026
}
 
1027
 
 
1028
guint mmguicore_devices_get_current_operation(mmguicore_t mmguicore)
 
1029
{
 
1030
        if (mmguicore == NULL) return MMGUI_DEVICE_OPERATION_IDLE;
 
1031
        if (mmguicore->device == NULL) return MMGUI_DEVICE_OPERATION_IDLE;
 
1032
        
 
1033
        return  mmguicore->device->operation;
 
1034
}
 
1035
 
 
1036
guint mmguicore_location_get_capabilities(mmguicore_t mmguicore)
 
1037
{
 
1038
        if (mmguicore == NULL) return MMGUI_LOCATION_CAPS_NONE;
 
1039
        if (mmguicore->device == NULL) return MMGUI_LOCATION_CAPS_NONE;
 
1040
                
 
1041
        return mmguicore->device->locationcaps;
 
1042
}
 
1043
 
 
1044
guint mmguicore_sms_get_capabilities(mmguicore_t mmguicore)
 
1045
{
 
1046
        if (mmguicore == NULL) return MMGUI_SMS_CAPS_NONE;
 
1047
        if (mmguicore->device == NULL) return MMGUI_SMS_CAPS_NONE;
 
1048
                
 
1049
        return mmguicore->device->smscaps;
 
1050
}
 
1051
 
 
1052
static gint mmguicore_sms_sort_index_compare(gconstpointer a, gconstpointer b)
 
1053
{
 
1054
        mmgui_sms_message_t message1, message2;
 
1055
        guint id1, id2;
 
1056
        
 
1057
        message1 = (mmgui_sms_message_t)a;
 
1058
        message2 = (mmgui_sms_message_t)b;
 
1059
        
 
1060
        id1 = mmgui_smsdb_message_get_identifier(message1);
 
1061
        id2 = mmgui_smsdb_message_get_identifier(message2);
 
1062
        
 
1063
        if (id1 < id2) {
 
1064
                return -1;
 
1065
        } else if (id1 > id2) {
 
1066
                return 1;
 
1067
        } else {
 
1068
                return 0;
 
1069
        }
 
1070
}
 
1071
 
 
1072
static gint mmguicore_sms_sort_timestamp_compare(gconstpointer a, gconstpointer b)
 
1073
{
 
1074
        mmgui_sms_message_t message1, message2;
 
1075
        time_t ts1, ts2;
 
1076
        
 
1077
        message1 = (mmgui_sms_message_t)a;
 
1078
        message2 = (mmgui_sms_message_t)b;
 
1079
        
 
1080
        ts1 = mmgui_smsdb_message_get_timestamp(message1);
 
1081
        ts2 = mmgui_smsdb_message_get_timestamp(message2);
 
1082
        
 
1083
        if (difftime(ts1, ts2) < 0.0) {
 
1084
                return -1;
 
1085
        } else if (difftime(ts1, ts2) > 0.0) {
 
1086
                return 1;
 
1087
        } else {
 
1088
                return 0;
 
1089
        }
 
1090
}
 
1091
 
 
1092
static void mmguicore_sms_merge_foreach(gpointer data, gpointer user_data)
 
1093
{
 
1094
        mmgui_sms_message_t curmessage, srcmessage;
 
1095
        const gchar *srcnumber, *curnumber;
 
1096
        time_t srcts, curts;
 
1097
        gboolean srcbinary, curbinary;
 
1098
        guint ident;
 
1099
        const gchar *text;
 
1100
        
 
1101
        curmessage = (mmgui_sms_message_t)data;
 
1102
        srcmessage = (mmgui_sms_message_t)user_data;
 
1103
        
 
1104
        if ((srcmessage == NULL) || (srcmessage == curmessage) || (mmgui_smsdb_message_get_read(curmessage))) return;
 
1105
        
 
1106
        /*Number*/
 
1107
        srcnumber = mmgui_smsdb_message_get_number(srcmessage);
 
1108
        curnumber = mmgui_smsdb_message_get_number(curmessage);
 
1109
        /*Timestamp*/
 
1110
        srcts = mmgui_smsdb_message_get_timestamp(srcmessage);
 
1111
        curts = mmgui_smsdb_message_get_timestamp(curmessage);
 
1112
        /*Binary format*/
 
1113
        srcbinary = mmgui_smsdb_message_get_binary(srcmessage);
 
1114
        curbinary = mmgui_smsdb_message_get_binary(curmessage);
 
1115
        
 
1116
        if ((g_str_equal(srcnumber, curnumber)) && (srcbinary == curbinary)) {
 
1117
                if (abs((gint)difftime(srcts, curts)) <= 5) {
 
1118
                        //Copy identifier
 
1119
                        ident = mmgui_smsdb_message_get_identifier(curmessage);
 
1120
                        mmgui_smsdb_message_set_identifier(srcmessage, ident, TRUE);
 
1121
                        //Copy decoded text
 
1122
                        text = mmgui_smsdb_message_get_text(curmessage);
 
1123
                        if (!srcbinary) {
 
1124
                                mmgui_smsdb_message_set_text(srcmessage, text, TRUE);
 
1125
                        } else {
 
1126
                                mmgui_smsdb_message_set_binary(srcmessage, FALSE);
 
1127
                                mmgui_smsdb_message_set_text(srcmessage, text, TRUE);
 
1128
                                mmgui_smsdb_message_set_binary(srcmessage, TRUE);
 
1129
                        }
 
1130
                        //Mark message obsolete
 
1131
                        mmgui_smsdb_message_set_read(curmessage, TRUE);
 
1132
                }
 
1133
        }
 
1134
}
 
1135
 
 
1136
GSList *mmguicore_sms_enum(mmguicore_t mmguicore, gboolean concatenation)
 
1137
{
 
1138
        GSList *messages;
 
1139
        guint nummessages;
 
1140
        GSList *iterator;
 
1141
        mmgui_sms_message_t message;
 
1142
        
 
1143
        if ((mmguicore == NULL) || (mmguicore->sms_enum_func == NULL)) return NULL;
 
1144
        
 
1145
        messages = NULL;
 
1146
        
 
1147
        nummessages = (mmguicore->sms_enum_func)(mmguicore, &messages);
 
1148
        
 
1149
        if (nummessages > 1) {
 
1150
                if (concatenation) {
 
1151
                        //Sort messages by index
 
1152
                        messages = g_slist_sort(messages, mmguicore_sms_sort_index_compare);
 
1153
                        //Try to concatenate every message and mark already concatenated with 'read' flag
 
1154
                        for (iterator=messages; iterator; iterator=iterator->next) {
 
1155
                                message = iterator->data;
 
1156
                                if (!mmgui_smsdb_message_get_read(message)) {
 
1157
                                        g_slist_foreach(messages, mmguicore_sms_merge_foreach, message);
 
1158
                                }
 
1159
                        }
 
1160
                }
 
1161
                //After all, sort messages by timestamp
 
1162
                messages = g_slist_sort(messages, mmguicore_sms_sort_timestamp_compare);
 
1163
        }
 
1164
        
 
1165
        return messages;
 
1166
}
 
1167
 
 
1168
mmgui_sms_message_t mmguicore_sms_get(mmguicore_t mmguicore, guint index)
 
1169
{
 
1170
        mmgui_sms_message_t message;
 
1171
        
 
1172
        if ((mmguicore == NULL) || (mmguicore->sms_get_func == NULL)) return NULL;
 
1173
        
 
1174
        message = (mmguicore->sms_get_func)(mmguicore, index);
 
1175
        
 
1176
        return message;
 
1177
}
 
1178
 
 
1179
gboolean mmguicore_sms_delete(mmguicore_t mmguicore, guint index)
 
1180
{
 
1181
        if ((mmguicore == NULL) || (mmguicore->sms_delete_func == NULL)) return FALSE;
 
1182
        
 
1183
        return (mmguicore->sms_delete_func)(mmguicore, index);
 
1184
}
 
1185
 
 
1186
gboolean mmguicore_sms_validate_number(const gchar *number)
 
1187
{
 
1188
        gboolean validated;
 
1189
        gsize length, digitlength, i;
 
1190
        
 
1191
        validated = TRUE;
 
1192
        
 
1193
        if ((number != NULL) && (number[0] != '\0')) {
 
1194
                length = strlen(number);
 
1195
                if (number[0] == '+') {
 
1196
                        digitlength = length-1;
 
1197
                } else {
 
1198
                        digitlength = length;
 
1199
                } 
 
1200
                if ((digitlength < MMGUI_MIN_SMS_NUMBER_LENGTH) || (digitlength > MMGUI_MAX_SMS_NUMBER_LENGTH)) {
 
1201
                        validated = FALSE;
 
1202
                } else {
 
1203
                        for (i=0; i<length; i++) {
 
1204
                                if (((!isdigit(number[i])) && (number[i] != '+')) || ((i != 0) && (number[i] == '+'))) {
 
1205
                                        validated = FALSE;
 
1206
                                        break;
 
1207
                                }
 
1208
                        }
 
1209
                }
 
1210
        } else {
 
1211
                validated = FALSE;
 
1212
        }
 
1213
        
 
1214
        return validated;
 
1215
}
 
1216
 
 
1217
gboolean mmguicore_sms_send(mmguicore_t mmguicore, gchar *number, gchar *text)
 
1218
{
 
1219
        if ((mmguicore == NULL) || (mmguicore->sms_send_func == NULL)) return FALSE;
 
1220
        
 
1221
        if ((number == NULL) || (text == NULL)) return FALSE;
 
1222
        
 
1223
        if ((!mmguicore_sms_validate_number(number)) || (text[0] == '\0')) return FALSE;
 
1224
        
 
1225
        return (mmguicore->sms_send_func)(mmguicore, number, text);
 
1226
}
 
1227
 
 
1228
guint mmguicore_ussd_get_capabilities(mmguicore_t mmguicore)
 
1229
{
 
1230
        if (mmguicore == NULL) return MMGUI_USSD_CAPS_NONE;
 
1231
        if (mmguicore->device == NULL) return MMGUI_USSD_CAPS_NONE;
 
1232
                
 
1233
        return mmguicore->device->ussdcaps;
 
1234
}
 
1235
 
 
1236
static gchar *mmguicore_ussd_gsm7_to_ucs2(gchar *srcstr)
 
1237
{
 
1238
        gchar *decstr1, *decstr2;
 
1239
        gsize strsize;
 
1240
        gboolean srcstrvalid;
 
1241
        
 
1242
        if (srcstr == NULL) return NULL;
 
1243
        
 
1244
        decstr1 = g_strdup(srcstr);
 
1245
        strsize = strlen(srcstr);
 
1246
        
 
1247
        srcstrvalid = g_utf8_validate((const gchar *)srcstr, -1, (const gchar **)NULL);
 
1248
        
 
1249
        if (strsize > 0) {
 
1250
                /*Map UTF8 symbols using GSM7 table*/
 
1251
                decstr2 = utf8_map_gsm7(decstr1, strsize, &strsize);
 
1252
                if (decstr2 != NULL) {
 
1253
                        /*Free temporary string and go next step*/
 
1254
                        g_free(decstr1);
 
1255
                } else {
 
1256
                        /*Return undecoded hash*/
 
1257
                        return decstr1;
 
1258
                }
 
1259
                /*Translate UTF8 to GSM7*/
 
1260
                decstr1 = utf8_to_gsm7(decstr2, strsize, &strsize);
 
1261
                if (decstr1 != NULL) {
 
1262
                        /*Free temporary string and go next step*/
 
1263
                        g_free(decstr2);
 
1264
                } else {
 
1265
                        /*String not decoded*/
 
1266
                        if (srcstrvalid) {
 
1267
                                /*Return valid source string*/
 
1268
                                g_free(decstr2);
 
1269
                                return g_strdup(srcstr);
 
1270
                        } else {
 
1271
                                /*Return undecoded hash*/
 
1272
                                return decstr2;
 
1273
                        }
 
1274
                }
 
1275
                /*Translate UCS2 to UTF8*/      
 
1276
                decstr2 = ucs2_to_utf8(decstr1, strsize, &strsize);
 
1277
                if (decstr2 != NULL) {
 
1278
                        if (g_utf8_validate((const gchar *)decstr2, -1, (const gchar **)NULL)) {
 
1279
                                /*Decoded string validated*/
 
1280
                                g_free(decstr1);
 
1281
                                return decstr2;
 
1282
                        } else {
 
1283
                                /*Decoded string not validated*/
 
1284
                                g_free(decstr2);
 
1285
                                if (srcstrvalid) {
 
1286
                                        /*Return valid source string*/
 
1287
                                        g_free(decstr1);
 
1288
                                        return g_strdup(srcstr);
 
1289
                                } else {
 
1290
                                        /*Return undecoded hash*/
 
1291
                                        return decstr1;
 
1292
                                }
 
1293
                        }
 
1294
                } else {
 
1295
                        /*String not decoded*/
 
1296
                        if (srcstrvalid) {
 
1297
                                /*Return valid source string*/
 
1298
                                g_free(decstr1);
 
1299
                                return g_strdup(srcstr);
 
1300
                        } else {
 
1301
                                /*Return undecoded hash*/
 
1302
                                return decstr1;
 
1303
                        }
 
1304
                }
 
1305
        }
 
1306
}
 
1307
 
 
1308
enum _mmgui_ussd_validation mmguicore_ussd_validate_request(gchar *request)
 
1309
{
 
1310
        enum _mmgui_ussd_validation statusid;
 
1311
        gsize length, i;
 
1312
        gboolean wrongsym;
 
1313
        
 
1314
        statusid = MMGUI_USSD_VALIDATION_INVALID;
 
1315
        
 
1316
        if ((request == NULL) && (request[0] == '\0')) return statusid;
 
1317
        
 
1318
        length = strlen(request);
 
1319
        
 
1320
        if (length > MMGUI_MAX_USSD_REQUEST_LENGTH) return statusid;
 
1321
        
 
1322
        if ((request[0] == '*') && (request[length-1] == '#') && (length > 2)) {
 
1323
                wrongsym = FALSE;
 
1324
                for (i=0; i<length; i++) {
 
1325
                        if ((!isdigit(request[i])) && (request[i] != '*') && (request[i] != '#')) {
 
1326
                                wrongsym = TRUE;
 
1327
                                break;
 
1328
                        }
 
1329
                }
 
1330
                if (!wrongsym) {
 
1331
                        statusid = MMGUI_USSD_VALIDATION_REQUEST;
 
1332
                } else {
 
1333
                        statusid = MMGUI_USSD_VALIDATION_RESPONSE;
 
1334
                }
 
1335
        } else {
 
1336
                statusid = MMGUI_USSD_VALIDATION_RESPONSE;
 
1337
        }
 
1338
        
 
1339
        return statusid;
 
1340
}
 
1341
 
 
1342
gboolean mmguicore_ussd_cancel_session(mmguicore_t mmguicore)
 
1343
{
 
1344
        if ((mmguicore == NULL) || (mmguicore->ussd_cancel_session_func == NULL)) return FALSE;
 
1345
        
 
1346
        return (mmguicore->ussd_cancel_session_func)(mmguicore);
 
1347
}
 
1348
 
 
1349
enum _mmgui_ussd_state mmguicore_ussd_get_state(mmguicore_t mmguicore)
 
1350
{
 
1351
        enum _mmgui_ussd_state stateid;
 
1352
        
 
1353
        stateid = MMGUI_USSD_STATE_UNKNOWN;
 
1354
        
 
1355
        if ((mmguicore == NULL) || (mmguicore->ussd_get_state_func == NULL)) return stateid;
 
1356
        
 
1357
        stateid = (mmguicore->ussd_get_state_func)(mmguicore);
 
1358
        
 
1359
        return stateid;
 
1360
}
 
1361
 
 
1362
gboolean mmguicore_ussd_send(mmguicore_t mmguicore, gchar *request)
 
1363
{
 
1364
        enum _mmgui_ussd_validation validationid;
 
1365
        
 
1366
        if ((mmguicore == NULL) || (mmguicore->ussd_send_func == NULL)) return FALSE;
 
1367
        
 
1368
        if (request == NULL) return FALSE;
 
1369
        
 
1370
        validationid = mmguicore_ussd_validate_request(request);
 
1371
        
 
1372
        return (mmguicore->ussd_send_func)(mmguicore, request, validationid);
 
1373
}
 
1374
 
 
1375
gboolean mmguicore_ussd_set_encoding(mmguicore_t mmguicore, enum _mmgui_ussd_encoding encoding)
 
1376
{
 
1377
        if ((mmguicore == NULL) || (mmguicore->device == NULL)) return FALSE;
 
1378
        
 
1379
        mmguicore->device->ussdencoding = encoding;
 
1380
        
 
1381
        return TRUE;
 
1382
}
 
1383
 
 
1384
enum _mmgui_ussd_encoding mmguicore_ussd_get_encoding(mmguicore_t mmguicore)
 
1385
{
 
1386
        if ((mmguicore == NULL) || (mmguicore->device == NULL)) return MMGUI_USSD_ENCODING_GSM7;
 
1387
        
 
1388
        return mmguicore->device->ussdencoding;
 
1389
}
 
1390
 
 
1391
guint mmguicore_newtworks_scan_get_capabilities(mmguicore_t mmguicore)
 
1392
{
 
1393
        if (mmguicore == NULL) return MMGUI_SCAN_CAPS_NONE;
 
1394
        if (mmguicore->device == NULL) return MMGUI_SCAN_CAPS_NONE;
 
1395
                
 
1396
        return mmguicore->device->scancaps;
 
1397
}
 
1398
 
 
1399
static void mmguicore_networks_scan_free_foreach(gpointer data, gpointer user_data)
 
1400
{
 
1401
        mmgui_scanned_network_t network;
 
1402
        
 
1403
        if (data == NULL) return;
 
1404
        
 
1405
        network = (mmgui_scanned_network_t)data;
 
1406
        
 
1407
        if (network->operator_long != NULL) {
 
1408
                g_free(network->operator_long);
 
1409
        }
 
1410
        
 
1411
        if (network->operator_short != NULL) {
 
1412
                g_free(network->operator_short);
 
1413
        }
 
1414
}
 
1415
 
 
1416
void mmguicore_networks_scan_free(GSList *networks)
 
1417
{
 
1418
        if (networks == NULL) return;
 
1419
        
 
1420
        g_slist_foreach(networks, mmguicore_networks_scan_free_foreach, NULL);
 
1421
        
 
1422
        g_slist_free(networks);
 
1423
}
 
1424
 
 
1425
gboolean mmguicore_networks_scan(mmguicore_t mmguicore)
 
1426
{
 
1427
        if ((mmguicore == NULL) || (mmguicore->networks_scan_func == NULL)) return FALSE;
 
1428
        
 
1429
        return (mmguicore->networks_scan_func)(mmguicore);
 
1430
}
 
1431
 
 
1432
guint mmguicore_contacts_get_capabilities(mmguicore_t mmguicore)
 
1433
{
 
1434
        if (mmguicore == NULL) return MMGUI_CONTACTS_CAPS_NONE;
 
1435
        if (mmguicore->device == NULL) return MMGUI_CONTACTS_CAPS_NONE;
 
1436
                
 
1437
        return mmguicore->device->contactscaps;
 
1438
}
 
1439
 
 
1440
void mmguicore_contacts_free_single(mmgui_contact_t contact, gboolean freestruct)
 
1441
{
 
1442
        if (contact == NULL) return;
 
1443
        
 
1444
        if (contact->name != NULL) {
 
1445
                g_free(contact->name);
 
1446
        }
 
1447
        if (contact->number != NULL) {
 
1448
                g_free(contact->number);
 
1449
        }
 
1450
        if (contact->email != NULL) {
 
1451
                g_free(contact->email);
 
1452
        }
 
1453
        if (contact->group != NULL) {
 
1454
                g_free(contact->group);
 
1455
        }
 
1456
        if (contact->name2 != NULL) {
 
1457
                g_free(contact->name2);
 
1458
        }
 
1459
        if (contact->number2 != NULL) {
 
1460
                g_free(contact->number2);
 
1461
        }
 
1462
        //Free contact structure
 
1463
        if (freestruct) {
 
1464
                g_free(contact);
 
1465
        }
 
1466
}
 
1467
 
 
1468
static void mmguicore_contacts_free_foreach(gpointer data, gpointer user_data)
 
1469
{
 
1470
        mmgui_contact_t contact;
 
1471
        
 
1472
        if (data == NULL) return;
 
1473
        
 
1474
        contact = (mmgui_contact_t)data;
 
1475
        
 
1476
        mmguicore_contacts_free_single(contact, FALSE);
 
1477
}
 
1478
 
 
1479
static void mmguicore_contacts_free(GSList *contacts)
 
1480
{
 
1481
        if (contacts == NULL) return;
 
1482
        
 
1483
        g_slist_foreach(contacts, mmguicore_contacts_free_foreach, NULL);
 
1484
        
 
1485
        g_slist_free(contacts);
 
1486
}
 
1487
 
 
1488
static guint mmguicore_contacts_enum(mmguicore_t mmguicore)
 
1489
{
 
1490
        guint numcontacts;
 
1491
        
 
1492
        if ((mmguicore == NULL) || (mmguicore->contacts_enum_func == NULL)) return 0;
 
1493
        if (mmguicore->device == NULL) return 0;
 
1494
        
 
1495
        if (mmguicore->device->contactslist != NULL) {
 
1496
                mmguicore_contacts_free(mmguicore->device->contactslist);
 
1497
                mmguicore->device->contactslist = NULL;
 
1498
        }
 
1499
        
 
1500
        numcontacts = (mmguicore->contacts_enum_func)(mmguicore, &(mmguicore->device->contactslist));
 
1501
                
 
1502
        return numcontacts;
 
1503
}
 
1504
 
 
1505
GSList *mmguicore_contacts_list(mmguicore_t mmguicore)
 
1506
{
 
1507
        if (mmguicore == NULL) return NULL;
 
1508
        if (mmguicore->device == NULL) return NULL;
 
1509
        if (!(mmguicore->device->contactscaps & MMGUI_CONTACTS_CAPS_EXPORT)) return NULL;
 
1510
        
 
1511
        return mmguicore->device->contactslist;
 
1512
}
 
1513
 
 
1514
static gint mmguicore_contacts_get_compare(gconstpointer a, gconstpointer b)
 
1515
{
 
1516
        mmgui_contact_t contact;
 
1517
        guint id;
 
1518
        
 
1519
        contact = (mmgui_contact_t)a;
 
1520
        id = GPOINTER_TO_UINT(b);
 
1521
        
 
1522
        if (contact->id < id) {
 
1523
                return 1;
 
1524
        } else if (contact->id > id) {
 
1525
                return -1;
 
1526
        } else {
 
1527
                return 0;
 
1528
        }
 
1529
}
 
1530
 
 
1531
mmgui_contact_t mmguicore_contacts_get(mmguicore_t mmguicore, guint index)
 
1532
{
 
1533
        GSList *contactptr;
 
1534
        mmgui_contact_t contact;
 
1535
        
 
1536
        if (mmguicore == NULL) return NULL;
 
1537
        if (mmguicore->device == NULL) return NULL;
 
1538
        if (!(mmguicore->device->contactscaps & MMGUI_CONTACTS_CAPS_EXPORT)) return NULL;
 
1539
        
 
1540
        contactptr = g_slist_find_custom(mmguicore->device->contactslist, GUINT_TO_POINTER(index), mmguicore_contacts_get_compare);
 
1541
        
 
1542
        if (contactptr != NULL) {
 
1543
                contact = (mmgui_contact_t)contactptr->data;
 
1544
                return contact;
 
1545
        } else {
 
1546
                return NULL;
 
1547
        }
 
1548
}
 
1549
 
 
1550
static gint mmguicore_contacts_delete_compare(gconstpointer a, gconstpointer b)
 
1551
{
 
1552
        mmgui_contact_t contact;
 
1553
        guint id;
 
1554
        
 
1555
        contact = (mmgui_contact_t)a;
 
1556
        id = GPOINTER_TO_UINT(b);
 
1557
        
 
1558
        if (contact->id < id) {
 
1559
                return 1;
 
1560
        } else if (contact->id > id) {
 
1561
                return -1;
 
1562
        } else {
 
1563
                return 0;
 
1564
        }
 
1565
}
 
1566
 
 
1567
gboolean mmguicore_contacts_delete(mmguicore_t mmguicore, guint index)
 
1568
{
 
1569
        gboolean result;
 
1570
        GSList *contactptr;
 
1571
        
 
1572
        if ((mmguicore == NULL) || (mmguicore->contacts_delete_func == NULL)) return FALSE;
 
1573
        if (mmguicore->device == NULL) return FALSE;
 
1574
        if (!(mmguicore->device->contactscaps & MMGUI_CONTACTS_CAPS_EDIT)) return FALSE;
 
1575
        
 
1576
        result = (mmguicore->contacts_delete_func)(mmguicore, index);
 
1577
        
 
1578
        if (result) {
 
1579
                contactptr = g_slist_find_custom(mmguicore->device->contactslist, GUINT_TO_POINTER(index), mmguicore_contacts_delete_compare);
 
1580
                if (contactptr != NULL) {
 
1581
                        //Remove contact from list
 
1582
                        mmguicore_contacts_free_single(contactptr->data, FALSE);
 
1583
                        mmguicore->device->contactslist = g_slist_remove(mmguicore->device->contactslist, contactptr->data);
 
1584
                }
 
1585
                return TRUE;
 
1586
        } else {
 
1587
                return FALSE;
 
1588
        } 
 
1589
}
 
1590
 
 
1591
gboolean mmguicore_contacts_add(mmguicore_t mmguicore, mmgui_contact_t contact)
 
1592
{
 
1593
        gint index;
 
1594
        
 
1595
        if ((mmguicore == NULL) || (contact == NULL) || (mmguicore->contacts_add_func == NULL)) return FALSE;
 
1596
        if ((contact->name == NULL) || (contact->number == NULL)) return FALSE;
 
1597
        if ((!mmguicore_sms_validate_number(contact->number)) || (contact->name[0] == '\0')) return FALSE;
 
1598
        if (!(mmguicore->device->contactscaps & MMGUI_CONTACTS_CAPS_EDIT)) return FALSE;
 
1599
        
 
1600
        index = (mmguicore->contacts_add_func)(mmguicore, contact);
 
1601
        
 
1602
        if (index > -1) {
 
1603
                mmguicore->device->contactslist = g_slist_append(mmguicore->device->contactslist, contact);
 
1604
                return TRUE;
 
1605
        } else {
 
1606
                return FALSE;
 
1607
        }
 
1608
}
 
1609
 
 
1610
GHashTable *mmguicore_connections_sync(mmguicore_t mmguicore)
 
1611
{
 
1612
        GHashTableIter iter;
 
1613
        gpointer key, value, extvalue;
 
1614
        GSList *inslist, *rmlist, *iterator;
 
1615
        mmgui_ext_connection_t extconnection;
 
1616
        mmgui_netlink_connection_t nlconnection;
 
1617
        
 
1618
        if (mmguicore == NULL) return NULL;
 
1619
        if ((mmguicore->netlink == NULL) || (mmguicore->connections == NULL)) return NULL;
 
1620
        
 
1621
        #if GLIB_CHECK_VERSION(2,32,0)
 
1622
                g_mutex_lock(&mmguicore->connsyncmutex);
 
1623
        #else
 
1624
                g_mutex_lock(mmguicore->connsyncmutex);
 
1625
        #endif
 
1626
        
 
1627
        inslist = NULL;
 
1628
        rmlist = NULL;
 
1629
        
 
1630
        g_hash_table_iter_init(&iter, mmguicore->connections);
 
1631
        while (g_hash_table_iter_next(&iter, &key, &value)) {
 
1632
                extconnection = (mmgui_ext_connection_t)value;
 
1633
                extconnection->existsflag = FALSE;
 
1634
        }
 
1635
        
 
1636
        g_hash_table_iter_init(&iter, mmguicore->netlink->connections);
 
1637
        while (g_hash_table_iter_next(&iter, &key, &value)) {
 
1638
                nlconnection = (mmgui_netlink_connection_t)value;
 
1639
                extvalue = g_hash_table_lookup(mmguicore->connections, key);
 
1640
                if (nlconnection != NULL) {
 
1641
                        if (extvalue != NULL) {
 
1642
                                extconnection = (mmgui_ext_connection_t)extvalue;
 
1643
                                extconnection->state = nlconnection->state;
 
1644
                                extconnection->dqueue = nlconnection->dqueue;
 
1645
                                extconnection->existsflag = TRUE;
 
1646
                        } else {
 
1647
                                extconnection = g_new0(struct _mmgui_ext_connection, 1);
 
1648
                                extconnection->state = nlconnection->state;
 
1649
                                extconnection->family = nlconnection->family;
 
1650
                                extconnection->srcport = nlconnection->srcport;
 
1651
                                extconnection->dqueue = nlconnection->dqueue;
 
1652
                                extconnection->inode = nlconnection->inode;
 
1653
                                extconnection->userid = nlconnection->userid;
 
1654
                                extconnection->apppid = nlconnection->apppid;
 
1655
                                extconnection->appname = g_strdup(nlconnection->appname);
 
1656
                                extconnection->dsthostname = g_strdup(nlconnection->dsthostname);
 
1657
                                memcpy(extconnection->srcaddr, nlconnection->srcaddr, sizeof(extconnection->srcaddr));
 
1658
                                memcpy(extconnection->dstaddr, nlconnection->dstaddr, sizeof(extconnection->dstaddr));
 
1659
                                extconnection->existsflag = TRUE;
 
1660
                                inslist = g_slist_prepend(inslist, extconnection);
 
1661
                        }
 
1662
                }
 
1663
        }
 
1664
        
 
1665
        if (inslist != NULL) {
 
1666
                for (iterator=inslist; iterator; iterator=iterator->next) {
 
1667
                        extconnection = (mmgui_ext_connection_t)iterator->data;
 
1668
                        g_hash_table_insert(mmguicore->connections, (gpointer)&extconnection->inode, extconnection);
 
1669
                }
 
1670
                g_slist_free(inslist);
 
1671
        }
 
1672
        
 
1673
        g_hash_table_iter_init(&iter, mmguicore->connections);
 
1674
        while (g_hash_table_iter_next(&iter, &key, &value)) {
 
1675
                extconnection = (mmgui_ext_connection_t)value;
 
1676
                if (!extconnection->existsflag) {
 
1677
                        rmlist = g_slist_prepend(rmlist, extconnection);
 
1678
                } else {
 
1679
                        extconnection->existsflag = FALSE;
 
1680
                }
 
1681
        }
 
1682
        
 
1683
        if (rmlist != NULL) {
 
1684
                for (iterator=rmlist; iterator; iterator=iterator->next) {
 
1685
                        extconnection = (mmgui_ext_connection_t)iterator->data;
 
1686
                        g_hash_table_remove(mmguicore->connections, (gpointer)&extconnection->inode);
 
1687
                }
 
1688
                g_slist_free(rmlist);
 
1689
        }
 
1690
        
 
1691
        #if GLIB_CHECK_VERSION(2,32,0)
 
1692
                g_mutex_unlock(&mmguicore->connsyncmutex);
 
1693
        #else
 
1694
                g_mutex_unlock(mmguicore->connsyncmutex);
 
1695
        #endif
 
1696
        
 
1697
        return mmguicore->connections;
 
1698
}
 
1699
 
 
1700
static void mmguicore_connections_hash_destroy(gpointer data)
 
1701
{
 
1702
        mmgui_ext_connection_t connection;
 
1703
        
 
1704
        connection = (mmgui_ext_connection_t)data;
 
1705
        
 
1706
        if (connection->appname != NULL) {
 
1707
                g_free(connection->appname);
 
1708
        }
 
1709
        
 
1710
        if (connection->dsthostname != NULL) {
 
1711
                g_free(connection->dsthostname);
 
1712
        }
 
1713
        
 
1714
        if (connection != NULL) {
 
1715
                g_free(connection);
 
1716
        }
 
1717
}
 
1718
 
 
1719
gchar *mmguicore_get_last_error(mmguicore_t mmguicore)
 
1720
{
 
1721
        if ((mmguicore == NULL) || (mmguicore->last_error_func == NULL)) return NULL;
 
1722
        
 
1723
        return (mmguicore->last_error_func)(mmguicore);
 
1724
}
 
1725
 
 
1726
gchar *mmguicore_get_last_connection_error(mmguicore_t mmguicore)
 
1727
{
 
1728
        if ((mmguicore == NULL) || (mmguicore->connection_last_error_func == NULL)) return NULL;
 
1729
        
 
1730
        return (mmguicore->connection_last_error_func)(mmguicore);
 
1731
}
 
1732
 
 
1733
gboolean mmguicore_interrupt_operation(mmguicore_t mmguicore)
 
1734
{
 
1735
        if ((mmguicore == NULL) || (mmguicore->interrupt_operation_func == NULL)) return FALSE;
 
1736
        
 
1737
        return (mmguicore->interrupt_operation_func)(mmguicore);
 
1738
}
 
1739
 
 
1740
mmguicore_t mmguicore_new(mmgui_event_ext_callback callback, mmgui_traffic_limits_t limits, gpointer userdata)
 
1741
{
 
1742
        mmguicore_t mmguicore;
 
1743
        
 
1744
        mmguicore = g_new0(struct _mmguicore, 1);
 
1745
        //Modules
 
1746
        mmguicore->modules = NULL;
 
1747
        //Modem manager module
 
1748
        mmguicore->module = NULL;
 
1749
        mmguicore->moduleptr = NULL;
 
1750
        mmguicore->module = NULL;
 
1751
        //Connection manager module
 
1752
        mmguicore->cmodule = NULL;
 
1753
        mmguicore->cmoduleptr = NULL;
 
1754
        mmguicore->cmodule = NULL;
 
1755
        //Modem manager module functions
 
1756
        mmguicore->open_func = NULL;
 
1757
        mmguicore->close_func = NULL;
 
1758
        mmguicore->last_error_func = NULL;
 
1759
        mmguicore->interrupt_operation_func = NULL;
 
1760
        mmguicore->set_timeout_func = NULL;
 
1761
        mmguicore->devices_enum_func = NULL;
 
1762
        mmguicore->devices_open_func = NULL;
 
1763
        mmguicore->devices_close_func = NULL;
 
1764
        mmguicore->devices_state_func = NULL;
 
1765
        mmguicore->devices_update_state_func = NULL;
 
1766
        mmguicore->devices_information_func = NULL;
 
1767
        mmguicore->devices_enable_func = NULL;
 
1768
        mmguicore->sms_enum_func = NULL;
 
1769
        mmguicore->sms_get_func = NULL;
 
1770
        mmguicore->sms_delete_func = NULL;
 
1771
        mmguicore->sms_send_func = NULL;
 
1772
        mmguicore->ussd_cancel_session_func = NULL;
 
1773
        mmguicore->ussd_get_state_func = NULL;
 
1774
        mmguicore->ussd_send_func = NULL;
 
1775
        mmguicore->networks_scan_func = NULL;
 
1776
        mmguicore->contacts_enum_func = NULL;
 
1777
        mmguicore->contacts_delete_func = NULL;
 
1778
        mmguicore->contacts_add_func = NULL;
 
1779
        //Connection manager module functions
 
1780
        mmguicore->connection_open_func = NULL;
 
1781
        mmguicore->connection_close_func = NULL;
 
1782
        mmguicore->connection_last_error_func = NULL;
 
1783
        mmguicore->device_connection_open_func = NULL;
 
1784
        mmguicore->device_connection_close_func = NULL;
 
1785
        mmguicore->device_connection_status_func = NULL;
 
1786
        mmguicore->device_connection_timestamp_func = NULL;
 
1787
        mmguicore->device_connection_disconnect_func = NULL;
 
1788
        //Devices
 
1789
        mmguicore->devices = NULL;
 
1790
        mmguicore->device = NULL;
 
1791
        //Internal callback
 
1792
        mmguicore->eventcb = mmguicore_event_callback;
 
1793
        //External callback
 
1794
        mmguicore->extcb = callback;
 
1795
        //Traffic limits
 
1796
        mmguicore->limits = limits;
 
1797
        //User data pointer
 
1798
        mmguicore->userdata = userdata;
 
1799
        //Open netlink interface
 
1800
        mmguicore->netlink = mmgui_netlink_open();
 
1801
        //Create connections hash table
 
1802
        mmguicore->connections = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, (GDestroyNotify)mmguicore_connections_hash_destroy);
 
1803
        //Enumerate available modules
 
1804
        if (!mmguicore_modules_enum(mmguicore)) {
 
1805
                g_free(mmguicore);
 
1806
                g_debug("No modules found\n");
 
1807
                return NULL;
 
1808
        }
 
1809
        
 
1810
        //Select module
 
1811
        if (!mmguicore_modules_select(mmguicore)) {
 
1812
                mmguicore_modules_close(mmguicore);
 
1813
                mmguicore_modules_free(mmguicore);
 
1814
                g_free(mmguicore);
 
1815
                return NULL;
 
1816
        }
 
1817
        //Work thread
 
1818
        if (pipe(mmguicore->workthreadctl) == 0) {
 
1819
                #if GLIB_CHECK_VERSION(2,32,0)
 
1820
                        g_mutex_init(&mmguicore->workthreadmutex);
 
1821
                        g_mutex_init(&mmguicore->connsyncmutex);
 
1822
                #else
 
1823
                        mmguicore->workthreadmutex = g_mutex_new();
 
1824
                        mmguicore->connsyncmutex = g_mutex_new();
 
1825
                #endif
 
1826
                
 
1827
                #if GLIB_CHECK_VERSION(2,32,0)
 
1828
                        mmguicore->workthread = g_thread_new("Modem Manager GUI work thread", mmguicore_work_thread, mmguicore);
 
1829
                #else 
 
1830
                        mmguicore->workthread = g_thread_create(mmguicore_work_thread, mmguicore, TRUE, NULL);
 
1831
                #endif
 
1832
        } else {
 
1833
                mmguicore->workthread = NULL;
 
1834
        }
 
1835
        
 
1836
        return mmguicore;
 
1837
}
 
1838
 
 
1839
void mmguicore_close(mmguicore_t mmguicore)
 
1840
{
 
1841
        guint workthreadcmd;
 
1842
        
 
1843
        if (mmguicore == NULL) return;
 
1844
        
 
1845
        //Close opened device
 
1846
        mmguicore_devices_close(mmguicore);
 
1847
        
 
1848
        //Stop work thread
 
1849
        workthreadcmd = MMGUI_THREAD_STOP_CMD;
 
1850
        
 
1851
        if (mmguicore->workthread != NULL) {
 
1852
                //Lock mutex
 
1853
                #if GLIB_CHECK_VERSION(2,32,0)
 
1854
                        g_mutex_lock(&mmguicore->workthreadmutex);
 
1855
                #else
 
1856
                        g_mutex_lock(mmguicore->workthreadmutex);
 
1857
                #endif
 
1858
                //Send command for thread termination
 
1859
                if (write(mmguicore->workthreadctl[0], &workthreadcmd, sizeof(workthreadcmd)) > 0) {
 
1860
                        //Wait for thread termination
 
1861
                        g_thread_join(mmguicore->workthread);
 
1862
                        //Close thread control pipe
 
1863
                        close(mmguicore->workthreadctl[0]);
 
1864
                        //Drop mutex
 
1865
                        #if GLIB_CHECK_VERSION(2,32,0)
 
1866
                                g_mutex_clear(&mmguicore->workthreadmutex);
 
1867
                                g_mutex_clear(&mmguicore->connsyncmutex);
 
1868
                        #else
 
1869
                                g_mutex_free(mmguicore->workthreadmutex);
 
1870
                                g_mutex_free(mmguicore->connsyncmutex);
 
1871
                        #endif
 
1872
                }
 
1873
        }
 
1874
        
 
1875
        //Close netlink interface
 
1876
        mmgui_netlink_close(mmguicore->netlink);
 
1877
        //Destroy connections hash table
 
1878
        g_hash_table_destroy(mmguicore->connections);
 
1879
        //Close opened modules
 
1880
        mmguicore_modules_close(mmguicore);
 
1881
        //Free modules list
 
1882
        mmguicore_modules_free(mmguicore);
 
1883
        
 
1884
        g_free(mmguicore);
 
1885
}
 
1886
 
 
1887
static gpointer mmguicore_work_thread(gpointer data)
 
1888
{
 
1889
        mmguicore_t mmguicore;
 
1890
        //Shared buffer
 
1891
        gchar databuf[8192];
 
1892
        //Polling variables
 
1893
        guint activesockets;
 
1894
        gint pollstatus;
 
1895
        gint recvbytes;
 
1896
        struct pollfd pollfds[3];
 
1897
        //Work thread control
 
1898
        gint ctlfd, ctlfdnum;
 
1899
        gint workthreadcmd;
 
1900
        //Interface monitoring
 
1901
        gint intfd, intfdnum;
 
1902
        struct iovec intiov = {databuf, sizeof(databuf)};
 
1903
        struct msghdr intmsg;
 
1904
        //Connections monitoring
 
1905
        gint connfd, connfdnum;
 
1906
        struct iovec conniov = {databuf, sizeof(databuf)};
 
1907
        struct msghdr connmsg;
 
1908
        //Events
 
1909
        struct _mmgui_netlink_interface_event event;
 
1910
        time_t ifstatetime, currenttime;
 
1911
        gboolean oldstate;
 
1912
        gchar oldinterface[IFNAMSIZ];
 
1913
                
 
1914
        
 
1915
        mmguicore = (mmguicore_t)data;
 
1916
        
 
1917
        if (mmguicore == NULL) return NULL;
 
1918
        
 
1919
        activesockets = 0;
 
1920
        
 
1921
        ctlfd = mmguicore->workthreadctl[1];
 
1922
        
 
1923
        if (ctlfd != -1) {
 
1924
                ctlfdnum = activesockets;
 
1925
                pollfds[ctlfdnum].fd = ctlfd;
 
1926
                pollfds[ctlfdnum].events = POLLIN;
 
1927
                activesockets++;
 
1928
        }
 
1929
        
 
1930
        intfd = mmgui_netlink_get_interfaces_monitoring_socket_fd(mmguicore->netlink);
 
1931
        
 
1932
        if (intfd != -1) {
 
1933
                intfdnum = activesockets;
 
1934
                pollfds[intfdnum].fd = intfd;
 
1935
                pollfds[intfdnum].events = POLLIN;
 
1936
                intmsg.msg_name = (void *)mmgui_netlink_get_interfaces_monitoring_socket_address(mmguicore->netlink);
 
1937
                intmsg.msg_namelen = sizeof(struct sockaddr_nl);
 
1938
                intmsg.msg_iov = &intiov;
 
1939
                intmsg.msg_iovlen = 1;
 
1940
                intmsg.msg_control = NULL;
 
1941
                intmsg.msg_controllen = 0;
 
1942
                intmsg.msg_flags = 0;
 
1943
                activesockets++;
 
1944
        }
 
1945
        
 
1946
        connfd = mmgui_netlink_get_connections_monitoring_socket_fd(mmguicore->netlink);
 
1947
        
 
1948
        if (connfd != -1) {
 
1949
                connfdnum = activesockets;
 
1950
                pollfds[connfdnum].fd = connfd;
 
1951
                pollfds[connfdnum].events = POLLIN;
 
1952
                connmsg.msg_name = (void *)mmgui_netlink_get_connections_monitoring_socket_address(mmguicore->netlink);
 
1953
                connmsg.msg_namelen = sizeof(struct sockaddr_nl);
 
1954
                connmsg.msg_iov = &conniov;
 
1955
                connmsg.msg_iovlen = 1;
 
1956
                connmsg.msg_control = NULL;
 
1957
                connmsg.msg_controllen = 0;
 
1958
                connmsg.msg_flags = 0;
 
1959
                activesockets++;
 
1960
        }
 
1961
        
 
1962
        //First we have to get device state
 
1963
        ifstatetime = time(NULL);
 
1964
        
 
1965
        while (TRUE) {
 
1966
                pollstatus = poll(pollfds, activesockets, 1000);
 
1967
                
 
1968
                if (pollstatus > 0) {
 
1969
                        //Work thread control
 
1970
                        if (pollfds[ctlfdnum].revents & POLLIN) {
 
1971
                                recvbytes = read(ctlfd, &workthreadcmd, sizeof(workthreadcmd));
 
1972
                                if (recvbytes > 0) {
 
1973
                                        if (workthreadcmd == MMGUI_THREAD_STOP_CMD) {
 
1974
                                                //Terminate thread
 
1975
                                                break;
 
1976
                                        }
 
1977
                                } else {
 
1978
                                        g_debug("Work thread: Control command not received\n");
 
1979
                                }
 
1980
                        }
 
1981
                }
 
1982
                
 
1983
                //Lock mutex and work with device in safe mode
 
1984
                #if GLIB_CHECK_VERSION(2,32,0)
 
1985
                        g_mutex_lock(&mmguicore->workthreadmutex);
 
1986
                #else
 
1987
                        g_mutex_lock(mmguicore->workthreadmutex);
 
1988
                #endif
 
1989
                
 
1990
                currenttime = time(NULL);
 
1991
                
 
1992
                if (mmguicore->device != NULL) {
 
1993
                        if (abs((gint)difftime(ifstatetime, currenttime)) <= 5) {
 
1994
                                //Save old values
 
1995
                                g_debug("Requesting network interface state information\n");
 
1996
                                oldstate = mmguicore->device->connected;
 
1997
                                strncpy(oldinterface, mmguicore->device->interface, sizeof(oldinterface));
 
1998
                                //Request new information
 
1999
                                if (mmguicore_devices_get_connection_status(mmguicore)) {
 
2000
                                        g_debug("Got new interface state\n");
 
2001
                                        if ((oldstate != mmguicore->device->connected) || (!g_str_equal(oldinterface, mmguicore->device->interface))) {
 
2002
                                                //State changed, no need to request information more
 
2003
                                                ifstatetime = 0;
 
2004
                                                //Zero values on disconnect
 
2005
                                                if (!mmguicore->device->connected) {
 
2006
                                                        //Close traffic database session
 
2007
                                                        mmgui_trafficdb_session_close(mmguicore->device->trafficdb);
 
2008
                                                        //Zero traffic values in UI
 
2009
                                                        mmguicore_traffic_zero(mmguicore);
 
2010
                                                        /*Device disconnect signal*/
 
2011
                                                        if (mmguicore->extcb != NULL) {
 
2012
                                                                (mmguicore->extcb)(MMGUI_EVENT_DEVICE_CONNECTION_STATUS, mmguicore, GUINT_TO_POINTER(FALSE), mmguicore->userdata);
 
2013
                                                        }
 
2014
                                                } else {
 
2015
                                                        /*Get session start timestamp*/
 
2016
                                                        mmguicore->device->sessionstarttime = (time_t)mmguicore_devices_get_connection_timestamp(mmguicore);
 
2017
                                                        mmguicore->device->sessiontime = llabs((gint64)difftime(currenttime, mmguicore->device->sessionstarttime));
 
2018
                                                        g_debug("Session start time: %" G_GUINT64_FORMAT ", duration: %" G_GUINT64_FORMAT "\n", (guint64)mmguicore->device->sessionstarttime, mmguicore->device->sessiontime);
 
2019
                                                        //Open traffic database session
 
2020
                                                        mmgui_trafficdb_session_new(mmguicore->device->trafficdb, mmguicore->device->sessionstarttime);
 
2021
                                                        /*Device connect signal*/
 
2022
                                                        if (mmguicore->extcb != NULL) {
 
2023
                                                                (mmguicore->extcb)(MMGUI_EVENT_DEVICE_CONNECTION_STATUS, mmguicore, GUINT_TO_POINTER(TRUE), mmguicore->userdata);
 
2024
                                                        }
 
2025
                                                }
 
2026
                                                g_debug("Interface state changed\n");
 
2027
                                        }
 
2028
                                }
 
2029
                        }
 
2030
                }
 
2031
                
 
2032
                if (pollstatus == 0) {
 
2033
                        //Timeout - request data
 
2034
                        if (mmguicore->device != NULL) {
 
2035
                                if (mmguicore->device->connected) {
 
2036
                                        mmgui_netlink_request_interface_statistics(mmguicore->netlink, mmguicore->device->interface);
 
2037
                                        mmgui_netlink_request_connections_list(mmguicore->netlink, AF_INET | AF_INET6);
 
2038
                                }
 
2039
                        }
 
2040
                } else if (pollstatus > 0) {
 
2041
                        //New data available
 
2042
                        //Interface monitoring
 
2043
                        if (pollfds[intfdnum].revents & POLLIN) {
 
2044
                                recvbytes = recvmsg(intfd, &intmsg, 0);
 
2045
                                if (recvbytes) {
 
2046
                                        if (mmgui_netlink_read_interface_event(mmguicore->netlink, databuf, recvbytes, &event)) {
 
2047
                                                //Traffic statisctics available
 
2048
                                                if (event.type & MMGUI_NETLINK_INTERFACE_EVENT_TYPE_STATS) {
 
2049
                                                        if (mmguicore->device != NULL) {
 
2050
                                                                if ((mmguicore->device->connected) && (g_str_equal(mmguicore->device->interface, event.ifname))) {
 
2051
                                                                        //Count traffic
 
2052
                                                                        mmguicore_traffic_count(mmguicore, event.rxbytes, event.txbytes);
 
2053
                                                                }
 
2054
                                                        }
 
2055
                                                }
 
2056
                                                //Interface created
 
2057
                                                if (event.type & MMGUI_NETLINK_INTERFACE_EVENT_TYPE_ADD) {
 
2058
                                                        g_debug("Created network interface event\n");
 
2059
                                                        if (mmguicore->device != NULL) {
 
2060
                                                                if (!mmguicore->device->connected) {
 
2061
                                                                        g_debug("Created network interface event signal\n");
 
2062
                                                                        ifstatetime = time(NULL);
 
2063
                                                                }
 
2064
                                                        }
 
2065
                                                }
 
2066
                                                //Interface removed
 
2067
                                                if (event.type & MMGUI_NETLINK_INTERFACE_EVENT_TYPE_REMOVE) {
 
2068
                                                        g_debug("Removed network interface event\n");
 
2069
                                                        if (mmguicore->device != NULL) {
 
2070
                                                                if ((mmguicore->device->connected) && (g_str_equal(mmguicore->device->interface, event.ifname))) {
 
2071
                                                                        g_debug("Removed network interface event signal\n");
 
2072
                                                                        ifstatetime = time(NULL);
 
2073
                                                                }
 
2074
                                                        }
 
2075
                                                }       
 
2076
                                        }
 
2077
                                } else {
 
2078
                                        g_debug("Work thread: interface event not received\n");
 
2079
                                }
 
2080
                        }
 
2081
                        //Connections monitoring
 
2082
                        if (pollfds[connfdnum].revents & POLLIN) {
 
2083
                                recvbytes = recvmsg(connfd, &connmsg, 0);
 
2084
                                if (recvbytes) {
 
2085
                                        #if GLIB_CHECK_VERSION(2,32,0)
 
2086
                                                g_mutex_lock(&mmguicore->connsyncmutex);
 
2087
                                        #else
 
2088
                                                g_mutex_lock(mmguicore->connsyncmutex);
 
2089
                                        #endif
 
2090
                                        if (mmgui_netlink_read_connections_list(mmguicore->netlink, databuf, recvbytes)) {
 
2091
                                                if (mmguicore->extcb != NULL) {
 
2092
                                                        (mmguicore->extcb)(MMGUI_EVENT_UPDATE_CONNECTIONS_LIST, mmguicore, mmgui_netlink_get_connections_list(mmguicore->netlink), mmguicore->userdata);
 
2093
                                                }
 
2094
                                        }
 
2095
                                        #if GLIB_CHECK_VERSION(2,32,0)
 
2096
                                                g_mutex_unlock(&mmguicore->connsyncmutex);
 
2097
                                        #else
 
2098
                                                g_mutex_unlock(mmguicore->connsyncmutex);
 
2099
                                        #endif
 
2100
                                } else {
 
2101
                                        g_debug("Work thread: connections data not received\n");
 
2102
                                }
 
2103
                        }
 
2104
                        
 
2105
                }
 
2106
                
 
2107
                //Update internal device state
 
2108
                mmguicore_devices_update_device_state(mmguicore);
 
2109
                
 
2110
                //Handle traffic limits
 
2111
                mmguicore_traffic_limits(mmguicore);
 
2112
                
 
2113
                //Unlock mutex after work finished
 
2114
                #if GLIB_CHECK_VERSION(2,32,0)
 
2115
                        g_mutex_unlock(&mmguicore->workthreadmutex);
 
2116
                #else
 
2117
                        g_mutex_unlock(mmguicore->workthreadmutex);
 
2118
                #endif
 
2119
        }
 
2120
        //Close thread control pipe descriptor
 
2121
        close(mmguicore->workthreadctl[1]);
 
2122
        
 
2123
        return NULL;
 
2124
}
 
2125
 
 
2126
static void mmguicore_traffic_count(mmguicore_t mmguicore, guint64 rxbytes, guint64 txbytes)
 
2127
{
 
2128
        mmguidevice_t device;
 
2129
        time_t currenttime;
 
2130
        guint timeframe;
 
2131
        struct _mmgui_traffic_update trafficupd;
 
2132
        
 
2133
        if (mmguicore == NULL) return;
 
2134
        
 
2135
        device = mmguicore->device;
 
2136
        if (device == NULL) return;     
 
2137
        
 
2138
        currenttime = time(NULL);
 
2139
        
 
2140
        if ((device->connected) && (device->rxbytes <= rxbytes) && (device->txbytes <= txbytes)) {
 
2141
                if (device->speedchecktime != 0) {
 
2142
                        //Time period for speed calculation
 
2143
                        timeframe = (guint)difftime(currenttime, device->speedchecktime);
 
2144
                        device->sessiontime += timeframe;
 
2145
                        if (device->speedindex < MMGUI_SPEED_VALUES_NUMBER) {
 
2146
                                //Add new speed value
 
2147
                                device->speedvalues[0][device->speedindex] = (gfloat)((rxbytes - device->rxbytes)*8)/(gfloat)(timeframe*1024);
 
2148
                                device->speedvalues[1][device->speedindex] = (gfloat)((txbytes - device->txbytes)*8)/(gfloat)(timeframe*1024);
 
2149
                                device->speedindex++;
 
2150
                        } else {
 
2151
                                //Move speed values and add new one
 
2152
                                memmove(&device->speedvalues[0][0], &device->speedvalues[0][1], sizeof(device->speedvalues[0]) - sizeof(device->speedvalues[0][0]));
 
2153
                                memmove(&device->speedvalues[1][0], &device->speedvalues[1][1], sizeof(device->speedvalues[1]) - sizeof(device->speedvalues[1][0]));
 
2154
                                device->speedvalues[0][MMGUI_SPEED_VALUES_NUMBER-1] = (gfloat)((rxbytes - device->rxbytes)*8)/(gfloat)(timeframe*1024);
 
2155
                                device->speedvalues[1][MMGUI_SPEED_VALUES_NUMBER-1] = (gfloat)((txbytes - device->txbytes)*8)/(gfloat)(timeframe*1024);
 
2156
                        }
 
2157
                        
 
2158
                        /*Update database*/
 
2159
                        trafficupd.fullrxbytes = device->rxbytes;
 
2160
                        trafficupd.fulltxbytes = device->txbytes;
 
2161
                        trafficupd.fulltime = device->sessiontime;
 
2162
                        trafficupd.deltarxbytes = rxbytes - device->rxbytes;
 
2163
                        trafficupd.deltatxbytes = txbytes - device->txbytes;
 
2164
                        trafficupd.deltaduration = timeframe;
 
2165
                        
 
2166
                        mmgui_trafficdb_traffic_update(mmguicore->device->trafficdb, &trafficupd);
 
2167
                }
 
2168
                //Update traffic count
 
2169
                device->rxbytes = rxbytes;
 
2170
                device->txbytes = txbytes;
 
2171
        }
 
2172
        
 
2173
        //Set last update time
 
2174
        device->speedchecktime = currenttime;
 
2175
        //Callback
 
2176
        if (mmguicore->extcb != NULL) {
 
2177
                (mmguicore->extcb)(MMGUI_EVENT_NET_STATUS, mmguicore, device, mmguicore->userdata);
 
2178
        }
 
2179
}
 
2180
 
 
2181
static void mmguicore_traffic_zero(mmguicore_t mmguicore)
 
2182
{
 
2183
        mmguidevice_t device;
 
2184
                
 
2185
        if (mmguicore == NULL) return;
 
2186
        
 
2187
        device = mmguicore->device;
 
2188
        if (device == NULL) return;     
 
2189
        
 
2190
        //Zero speed values if device is not connected anymore
 
2191
        mmguicore->device->speedindex = 0;
 
2192
        mmguicore->device->speedvalues[0][0] = 0.0;
 
2193
        mmguicore->device->speedvalues[1][0] = 0.0;
 
2194
        mmguicore->device->rxbytes = 0;
 
2195
        mmguicore->device->txbytes = 0;
 
2196
        //Set last update time
 
2197
        mmguicore->device->speedchecktime = time(NULL);
 
2198
        //Callback
 
2199
        if (mmguicore->extcb != NULL) {
 
2200
                (mmguicore->extcb)(MMGUI_EVENT_NET_STATUS, mmguicore, NULL, mmguicore->userdata);
 
2201
        }
 
2202
}
 
2203
 
 
2204
static void mmguicore_traffic_limits(mmguicore_t mmguicore)
 
2205
{
 
2206
        if (mmguicore == NULL) return;
 
2207
        
 
2208
        if ((mmguicore->limits != NULL) && (mmguicore->device != NULL)) {
 
2209
                //Traffic limit
 
2210
                if (mmguicore->limits->trafficenabled) {
 
2211
                        if ((!mmguicore->limits->trafficexecuted) && (mmguicore->limits->trafficfull < (mmguicore->device->rxbytes + mmguicore->device->txbytes))) {
 
2212
                                mmguicore->limits->trafficexecuted = TRUE;
 
2213
                                if (mmguicore->limits->trafficaction == MMGUI_EVENT_ACTION_DISCONNECT) {
 
2214
                                        if (mmguicore->device_connection_disconnect_func != NULL) {
 
2215
                                                (mmguicore->device_connection_disconnect_func)(mmguicore);
 
2216
                                        }
 
2217
                                }
 
2218
                                //Callback
 
2219
                                if (mmguicore->extcb != NULL) {
 
2220
                                        (mmguicore->extcb)(MMGUI_EVENT_TRAFFIC_LIMIT, mmguicore, NULL, mmguicore->userdata);
 
2221
                                }
 
2222
                        }
 
2223
                }
 
2224
                
 
2225
                //Time limit
 
2226
                if (mmguicore->limits->timeenabled) {
 
2227
                        if ((!mmguicore->limits->timeexecuted) && (mmguicore->limits->timefull < mmguicore->device->sessiontime)) {
 
2228
                                mmguicore->limits->timeexecuted = TRUE;
 
2229
                                if (mmguicore->limits->timeaction == MMGUI_EVENT_ACTION_DISCONNECT) {
 
2230
                                        if (mmguicore->device_connection_disconnect_func != NULL) {
 
2231
                                                (mmguicore->device_connection_disconnect_func)(mmguicore);
 
2232
                                        }
 
2233
                                }
 
2234
                                //Callback
 
2235
                                if (mmguicore->extcb != NULL) {
 
2236
                                        (mmguicore->extcb)(MMGUI_EVENT_TIME_LIMIT, mmguicore, NULL, mmguicore->userdata);
 
2237
                                }
 
2238
                        }
 
2239
                }
 
2240
        }
 
2241
}