4
* Copyright 2013 Alex <alex@linuxonly.ru>
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.
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.
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/>.
28
#include "mmguicore.h"
31
#include "trafficdb.h"
33
#include "resources.h"
35
#define MMGUI_MIN_SMS_NUMBER_LENGTH 3
36
#define MMGUI_MAX_SMS_NUMBER_LENGTH 20
38
#define MMGUI_MIN_USSD_REQUEST_LENGTH 1
39
#define MMGUI_MAX_USSD_REQUEST_LENGTH 160
41
#define MMGUI_THREAD_STOP_CMD 0x00
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);
56
static void mmguicore_event_callback(enum _mmgui_event event, gpointer mmguicore, gpointer data)
58
mmguicore_t mmguicorelc;
61
mmguicorelc = (mmguicore_t)mmguicore;
62
if (mmguicorelc == NULL) return;
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);
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);
77
case MMGUI_EVENT_DEVICE_ENABLED_STATUS:
78
if (mmguicorelc->extcb != NULL) {
79
(mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
82
case MMGUI_EVENT_DEVICE_BLOCKED_STATUS:
83
if (mmguicorelc->extcb != NULL) {
84
(mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
87
case MMGUI_EVENT_DEVICE_CONNECTION_STATUS:
88
if (mmguicorelc->extcb != NULL) {
89
(mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
93
case MMGUI_EVENT_SMS_LIST_READY:
94
if (mmguicorelc->extcb != NULL) {
95
(mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
98
case MMGUI_EVENT_SMS_COMPLETED:
99
if (mmguicorelc->extcb != NULL) {
100
(mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
103
case MMGUI_EVENT_SMS_SENT:
104
if (mmguicorelc->extcb != NULL) {
105
(mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
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);
114
if (mmguicorelc->extcb != NULL) {
115
(mmguicorelc->extcb)(event, mmguicorelc, ussdanswer, mmguicorelc->userdata);
118
case MMGUI_EVENT_SCAN_RESULT:
119
if (mmguicorelc->extcb != NULL) {
120
(mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
123
case MMGUI_EVENT_SIGNAL_LEVEL_CHANGE:
124
if (mmguicorelc->extcb != NULL) {
125
(mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
128
case MMGUI_EVENT_NETWORK_MODE_CHANGE:
129
if (mmguicorelc->extcb != NULL) {
130
(mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
133
case MMGUI_EVENT_NETWORK_REGISTRATION_CHANGE:
134
if (mmguicorelc->extcb != NULL) {
135
(mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
138
case MMGUI_EVENT_MODEM_ENABLE_RESULT:
139
/*Update device information*/
140
if (mmguicorelc->devices_information_func != NULL) {
141
(mmguicorelc->devices_information_func)(mmguicorelc);
143
if (mmguicorelc->extcb != NULL) {
144
(mmguicorelc->extcb)(event, mmguicorelc, data, mmguicorelc->userdata);
156
static void mmguicore_system_services_destroy_notify(gpointer data)
158
if (data != NULL) g_free(data);
161
static GHashTable *mmguicore_system_services_enum(void)
163
GDBusConnection *connection;
167
GVariantIter siterl1, siterl2;
168
GVariant *snodel1, *snodel2;
171
GHashTable *serviceshash;
175
connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
177
if ((connection == NULL) && (error != NULL)) {
178
g_debug("Core error: %s\n", error->message);
185
proxy = g_dbus_proxy_new_sync(connection,
186
G_DBUS_PROXY_FLAGS_NONE,
188
"org.freedesktop.DBus",
189
"/org/freedesktop/DBus",
190
"org.freedesktop.DBus",
194
if ((proxy == NULL) && (error != NULL)) {
195
g_debug("Core error: %s\n", error->message);
197
g_object_unref(connection);
203
services = g_dbus_proxy_call_sync(proxy,
211
if ((services == NULL) && (error != NULL)) {
212
g_debug("Core error: %s\n", error->message);
214
g_object_unref(proxy);
215
g_object_unref(connection);
219
serviceshash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, mmguicore_system_services_destroy_notify);
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) {
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);
230
g_variant_unref(snodel1);
233
g_variant_unref(services);
234
g_object_unref(proxy);
235
g_object_unref(connection);
240
static gint mmguicore_modules_sort(gconstpointer a, gconstpointer b)
242
mmguimodule_t mod1, mod2;
244
mod1 = (mmguimodule_t)a;
245
mod2 = (mmguimodule_t)b;
247
if (mod1->priority == mod2->priority) {
248
if (mod1->identifier == mod2->identifier) {
250
} else if (mod1->identifier > mod2->identifier) {
252
} else if (mod1->identifier < mod2->identifier) {
255
} else if (mod1->priority > mod2->priority) {
257
} else if (mod1->priority < mod2->priority) {
262
guint mmguicore_modules_enum(mmguicore_t mmguicore)
264
GHashTable *services;
267
const gchar *modname;
269
const gchar modext[] = ".so";
272
mmgui_module_init_func module_init;
274
struct _mmguimodule smodule, *dmodule;
276
if (mmguicore == NULL) return 0;
278
services = mmguicore_system_services_enum();
280
if (services == NULL) return 0;
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)) {
291
module = g_module_open(modpath, G_MODULE_BIND_LAZY);
292
if (module != NULL) {
294
if (g_module_symbol(module, "mmgui_module_init", (gpointer*)&module_init)) {
295
if (module_init(&smodule)) {
296
//Test service/file existence
298
switch (smodule.requirement) {
299
case MMGUI_MODULE_REQUIREMENT_SERVICE:
300
if (g_hash_table_lookup(services, smodule.servicename) != NULL) {
304
case MMGUI_MODULE_REQUIREMENT_FILE:
305
if (g_file_test(smodule.servicename, G_FILE_TEST_EXISTS)) {
309
case MMGUI_MODULE_REQUIREMENT_NONE:
315
//Add service to list 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);
328
g_module_close(module);
338
mmguicore->modules = g_slist_sort(mmguicore->modules, mmguicore_modules_sort);
339
mmguicore->modules = g_slist_reverse(mmguicore->modules);
342
g_hash_table_destroy(services);
347
static gboolean mmguicore_modules_free(mmguicore_t mmguicore)
349
if (mmguicore == NULL) return FALSE;
350
if (mmguicore->modules == NULL) return FALSE;
352
g_slist_free(mmguicore->modules);
357
static gboolean mmguicore_modules_mm_open(mmguicore_t mmguicore, mmguimodule_t mmguimodule)
362
if ((mmguicore == NULL) || (mmguimodule == NULL)) return FALSE;
364
if (mmguimodule->type == MMGUI_MODULE_TYPE_CONNECTION_MANGER) return FALSE;
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) {
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));
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);
428
mmguicore->moduleptr = mmguimodule;
429
(mmguicore->open_func)(mmguicore);
430
g_printf("Modem manager: %s\n", mmguimodule->description);
432
mmguicore->moduleptr = NULL;
433
mmguicore->module = NULL;
439
static gboolean mmguicore_modules_cm_open(mmguicore_t mmguicore, mmguimodule_t mmguimodule)
444
if ((mmguicore == NULL) || (mmguimodule == NULL)) return FALSE;
446
if (mmguimodule->type == MMGUI_MODULE_TYPE_MODEM_MANAGER) return FALSE;
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) {
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));
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;
473
g_module_close(mmguicore->cmodule);
481
mmguicore->cmoduleptr = mmguimodule;
482
(mmguicore->connection_open_func)(mmguicore);
483
g_printf("Connection manager: %s\n", mmguimodule->description);
485
mmguicore->cmoduleptr = NULL;
486
mmguicore->cmodule = NULL;
492
static gboolean mmguicore_modules_close(mmguicore_t mmguicore)
494
if (mmguicore == NULL) return FALSE;
496
//Modem manager module functions
497
if (mmguicore->module != NULL) {
498
if (mmguicore->close_func != NULL) {
499
mmguicore->close_func(mmguicore);
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;
526
mmguicore->moduleptr = NULL;
529
//Connection manager module functions
530
if (mmguicore->cmodule != NULL) {
531
if (mmguicore->connection_close_func != NULL) {
532
mmguicore->connection_close_func(mmguicore);
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;
546
mmguicore->cmoduleptr = NULL;
552
static gboolean mmguicore_modules_select(mmguicore_t mmguicore)
555
mmguimodule_t module;
556
gboolean mmfound, cmfound;
558
if (mmguicore == NULL) return FALSE;
559
if (mmguicore->modules == NULL) return FALSE;
561
if ((mmguicore->module != NULL) || (mmguicore->cmodule != NULL)) {
562
mmguicore_modules_close(mmguicore);
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)) {
582
static void mmguicore_devices_free_single(mmguidevice_t device)
584
if (device != NULL) return;
586
if (device->manufacturer != NULL) {
587
g_free(device->manufacturer);
589
if (device->model != NULL) {
590
g_free(device->model);
592
if (device->version != NULL) {
593
g_free(device->version);
595
if (device->port != NULL) {
596
g_free(device->port);
598
if (device->objectpath != NULL) {
599
g_free(device->objectpath);
601
if (device->sysfspath != NULL) {
602
g_free(device->sysfspath);
604
if (device->internalid != NULL) {
605
g_free(device->internalid);
607
if (device->persistentid != NULL) {
608
g_free(device->persistentid);
610
if (device->imei != NULL) {
611
g_free(device->imei);
613
if (device->imsi != NULL) {
614
g_free(device->imsi);
616
if (device->operatorcode != NULL) {
617
g_free(device->operatorcode);
621
static void mmguicore_devices_free_foreach(gpointer data, gpointer user_data)
623
mmguidevice_t device;
625
if (data != NULL) return;
627
device = (mmguidevice_t)data;
629
mmguicore_devices_free_single(device);
632
static void mmguicore_devices_free(mmguicore_t mmguicore)
634
if (mmguicore == NULL) return;
636
g_slist_foreach(mmguicore->devices, mmguicore_devices_free_foreach, NULL);
638
g_slist_free(mmguicore->devices);
640
mmguicore->devices = NULL;
643
gboolean mmguicore_devices_enum(mmguicore_t mmguicore)
646
mmguidevice_t device;
648
if ((mmguicore == NULL) || (mmguicore->devices_enum_func == NULL)) return FALSE;
650
if (mmguicore->devices != NULL) {
651
mmguicore_devices_free(mmguicore);
654
(mmguicore->devices_enum_func)(mmguicore, &(mmguicore->devices));
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);
664
gboolean mmguicore_devices_add(mmguicore_t mmguicore, mmguidevice_t device)
666
if ((mmguicore == NULL) || (device == NULL)) return FALSE;
668
mmguicore->devices = g_slist_append(mmguicore->devices, device);
670
g_printf("Device successfully added\n");
675
static gint mmguicore_devices_remove_compare(gconstpointer a, gconstpointer b)
677
mmguidevice_t device;
680
device = (mmguidevice_t)a;
681
id = GPOINTER_TO_UINT(b);
683
if (device->id < id) {
685
} else if (device->id > id) {
692
gboolean mmguicore_devices_remove(mmguicore_t mmguicore, guint deviceid)
696
if (mmguicore == NULL) return FALSE;
697
if (mmguicore->devices == NULL) return FALSE;
699
deviceptr = g_slist_find_custom(mmguicore->devices, GUINT_TO_POINTER(deviceid), mmguicore_devices_remove_compare);
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);
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");
719
static gint mmguicore_devices_open_compare(gconstpointer a, gconstpointer b)
721
mmguidevice_t device;
724
device = (mmguidevice_t)a;
725
id = GPOINTER_TO_UINT(b);
727
if (device->id < id) {
729
} else if (device->id > id) {
736
gboolean mmguicore_devices_open(mmguicore_t mmguicore, guint deviceid, gboolean openfirst)
740
if (mmguicore == NULL) return FALSE;
741
if ((mmguicore->devices == NULL) || (mmguicore->devices_open_func == NULL)) return FALSE;
743
deviceptr = g_slist_find_custom(mmguicore->devices, GUINT_TO_POINTER(deviceid), mmguicore_devices_open_compare);
745
if (deviceptr != NULL) {
746
//Test currently opened device
747
if (mmguicore->device != NULL) {
748
if (mmguicore->device->id == deviceid) {
752
//Close currently opened device
753
mmguicore_devices_close(mmguicore);
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);
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);
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;
771
mmguicore->device->ussdencoding = MMGUI_USSD_ENCODING_GSM7;
774
//Open connection statistics source
775
if (mmguicore->device_connection_open_func != NULL) {
776
(mmguicore->device_connection_open_func)(mmguicore, deviceptr->data);
778
g_printf("Device successfully opened\n");
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);
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);
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);
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;
804
mmguicore->device->ussdencoding = MMGUI_USSD_ENCODING_GSM7;
807
//Open connection statistics source
808
if (mmguicore->device_connection_open_func != NULL) {
809
(mmguicore->device_connection_open_func)(mmguicore, mmguicore->devices->data);
811
g_printf("First available device successfully opened\n");
820
gboolean mmguicore_devices_close(mmguicore_t mmguicore)
824
#if GLIB_CHECK_VERSION(2,32,0)
825
g_mutex_lock(&mmguicore->workthreadmutex);
827
g_mutex_lock(mmguicore->workthreadmutex);
832
if (mmguicore->device != NULL) {
833
if ((mmguicore->devices_close_func)(mmguicore)) {
835
mmguicore->device->smscaps = MMGUI_SMS_CAPS_NONE;
836
mmgui_smsdb_close(mmguicore->device->smsdb);
837
mmguicore->device->smsdb = NULL;
839
mmguicore->device->contactscaps = MMGUI_CONTACTS_CAPS_NONE;
840
mmguicore_contacts_free(mmguicore->device->contactslist);
841
mmguicore->device->contactslist = NULL;
843
if (mmguicore->device->operatorname != NULL) {
844
g_free(mmguicore->device->operatorname);
845
mmguicore->device->operatorname = NULL;
847
if (mmguicore->device->operatorcode != NULL) {
848
g_free(mmguicore->device->operatorcode);
849
mmguicore->device->operatorcode = NULL;
851
if (mmguicore->device->imei != NULL) {
852
g_free(mmguicore->device->imei);
853
mmguicore->device->imei = NULL;
855
if (mmguicore->device->imsi != NULL) {
856
g_free(mmguicore->device->imsi);
857
mmguicore->device->imsi = NULL;
860
mmguicore->device->ussdcaps = MMGUI_USSD_CAPS_NONE;
861
mmguicore->device->ussdencoding = MMGUI_USSD_ENCODING_GSM7;
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));
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;
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);
890
mmguicore->device = NULL;
891
//Successfully closed
892
g_printf("Device successfully closed\n");
897
#if GLIB_CHECK_VERSION(2,32,0)
898
g_mutex_unlock(&mmguicore->workthreadmutex);
900
g_mutex_unlock(mmguicore->workthreadmutex);
906
gboolean mmguicore_devices_enable(mmguicore_t mmguicore, gboolean enabled)
908
if (mmguicore == NULL) return FALSE;
909
if ((mmguicore->device == NULL) || (mmguicore->devices_enable_func == NULL)) return FALSE;
911
return (mmguicore->devices_enable_func)(mmguicore, enabled);
914
GSList *mmguicore_devices_get_list(mmguicore_t mmguicore)
916
if (mmguicore == NULL) return NULL;
918
return mmguicore->devices;
921
mmguidevice_t mmguicore_devices_get_current(mmguicore_t mmguicore)
923
if (mmguicore == NULL) return NULL;
925
return mmguicore->device;
928
gboolean mmguicore_devices_get_enabled(mmguicore_t mmguicore)
930
if (mmguicore == NULL) return FALSE;
931
if ((mmguicore->device == NULL) || (mmguicore->devices_state_func == NULL)) return FALSE;
933
return (mmguicore->devices_state_func)(mmguicore, MMGUI_DEVICE_STATE_REQUEST_ENABLED);
936
gboolean mmguicore_devices_get_locked(mmguicore_t mmguicore)
938
if (mmguicore == NULL) return FALSE;
939
if ((mmguicore->device == NULL) || (mmguicore->devices_state_func == NULL)) return FALSE;
941
return (mmguicore->devices_state_func)(mmguicore, MMGUI_DEVICE_STATE_REQUEST_LOCKED);
944
gboolean mmguicore_devices_get_registered(mmguicore_t mmguicore)
946
if (mmguicore == NULL) return FALSE;
947
if ((mmguicore->device == NULL) || (mmguicore->devices_state_func == NULL)) return FALSE;
949
return (mmguicore->devices_state_func)(mmguicore, MMGUI_DEVICE_STATE_REQUEST_REGISTERED);
952
gboolean mmguicore_devices_get_connected(mmguicore_t mmguicore)
954
if (mmguicore == NULL) return FALSE;
955
if (mmguicore->device == NULL) return FALSE;
957
return mmguicore->device->connected;
960
gboolean mmguicore_devices_update_device_state(mmguicore_t mmguicore)
964
if (mmguicore == NULL) return FALSE;
965
if ((mmguicore->device == NULL) || (mmguicore->devices_update_state_func == NULL)) return FALSE;
969
updated = (mmguicore->devices_update_state_func)(mmguicore);
974
const gchar *mmguicore_devices_get_identifier(mmguicore_t mmguicore)
976
if (mmguicore == NULL) return NULL;
977
if (mmguicore->device == NULL) return NULL;
979
return (const gchar *)mmguicore->device->persistentid;
982
const gchar *mmguicore_devices_get_internal_identifier(mmguicore_t mmguicore)
984
if (mmguicore == NULL) return NULL;
985
if (mmguicore->device == NULL) return NULL;
987
return (const gchar *)mmguicore->device->internalid;
990
gpointer mmguicore_devices_get_sms_db(mmguicore_t mmguicore)
992
if (mmguicore == NULL) return NULL;
993
if (mmguicore->device == NULL) return NULL;
995
return (gpointer)mmguicore->device->smsdb;
998
gpointer mmguicore_devices_get_traffic_db(mmguicore_t mmguicore)
1000
if (mmguicore == NULL) return NULL;
1001
if (mmguicore->device == NULL) return NULL;
1003
return (gpointer)mmguicore->device->trafficdb;
1006
gboolean mmguicore_devices_get_connection_status(mmguicore_t mmguicore)
1008
if (mmguicore == NULL) return FALSE;
1009
if ((mmguicore->device == NULL) || (mmguicore->device_connection_status_func == NULL)) return FALSE;
1011
return (mmguicore->device_connection_status_func)(mmguicore);
1014
guint64 mmguicore_devices_get_connection_timestamp(mmguicore_t mmguicore)
1018
timestamp = (guint64)time(NULL);
1020
if (mmguicore == NULL) return timestamp;
1021
if ((mmguicore->device == NULL) || (mmguicore->device_connection_timestamp_func == NULL)) return timestamp;
1023
timestamp = (mmguicore->device_connection_timestamp_func)(mmguicore);
1028
guint mmguicore_devices_get_current_operation(mmguicore_t mmguicore)
1030
if (mmguicore == NULL) return MMGUI_DEVICE_OPERATION_IDLE;
1031
if (mmguicore->device == NULL) return MMGUI_DEVICE_OPERATION_IDLE;
1033
return mmguicore->device->operation;
1036
guint mmguicore_location_get_capabilities(mmguicore_t mmguicore)
1038
if (mmguicore == NULL) return MMGUI_LOCATION_CAPS_NONE;
1039
if (mmguicore->device == NULL) return MMGUI_LOCATION_CAPS_NONE;
1041
return mmguicore->device->locationcaps;
1044
guint mmguicore_sms_get_capabilities(mmguicore_t mmguicore)
1046
if (mmguicore == NULL) return MMGUI_SMS_CAPS_NONE;
1047
if (mmguicore->device == NULL) return MMGUI_SMS_CAPS_NONE;
1049
return mmguicore->device->smscaps;
1052
static gint mmguicore_sms_sort_index_compare(gconstpointer a, gconstpointer b)
1054
mmgui_sms_message_t message1, message2;
1057
message1 = (mmgui_sms_message_t)a;
1058
message2 = (mmgui_sms_message_t)b;
1060
id1 = mmgui_smsdb_message_get_identifier(message1);
1061
id2 = mmgui_smsdb_message_get_identifier(message2);
1065
} else if (id1 > id2) {
1072
static gint mmguicore_sms_sort_timestamp_compare(gconstpointer a, gconstpointer b)
1074
mmgui_sms_message_t message1, message2;
1077
message1 = (mmgui_sms_message_t)a;
1078
message2 = (mmgui_sms_message_t)b;
1080
ts1 = mmgui_smsdb_message_get_timestamp(message1);
1081
ts2 = mmgui_smsdb_message_get_timestamp(message2);
1083
if (difftime(ts1, ts2) < 0.0) {
1085
} else if (difftime(ts1, ts2) > 0.0) {
1092
static void mmguicore_sms_merge_foreach(gpointer data, gpointer user_data)
1094
mmgui_sms_message_t curmessage, srcmessage;
1095
const gchar *srcnumber, *curnumber;
1096
time_t srcts, curts;
1097
gboolean srcbinary, curbinary;
1101
curmessage = (mmgui_sms_message_t)data;
1102
srcmessage = (mmgui_sms_message_t)user_data;
1104
if ((srcmessage == NULL) || (srcmessage == curmessage) || (mmgui_smsdb_message_get_read(curmessage))) return;
1107
srcnumber = mmgui_smsdb_message_get_number(srcmessage);
1108
curnumber = mmgui_smsdb_message_get_number(curmessage);
1110
srcts = mmgui_smsdb_message_get_timestamp(srcmessage);
1111
curts = mmgui_smsdb_message_get_timestamp(curmessage);
1113
srcbinary = mmgui_smsdb_message_get_binary(srcmessage);
1114
curbinary = mmgui_smsdb_message_get_binary(curmessage);
1116
if ((g_str_equal(srcnumber, curnumber)) && (srcbinary == curbinary)) {
1117
if (abs((gint)difftime(srcts, curts)) <= 5) {
1119
ident = mmgui_smsdb_message_get_identifier(curmessage);
1120
mmgui_smsdb_message_set_identifier(srcmessage, ident, TRUE);
1122
text = mmgui_smsdb_message_get_text(curmessage);
1124
mmgui_smsdb_message_set_text(srcmessage, text, TRUE);
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);
1130
//Mark message obsolete
1131
mmgui_smsdb_message_set_read(curmessage, TRUE);
1136
GSList *mmguicore_sms_enum(mmguicore_t mmguicore, gboolean concatenation)
1141
mmgui_sms_message_t message;
1143
if ((mmguicore == NULL) || (mmguicore->sms_enum_func == NULL)) return NULL;
1147
nummessages = (mmguicore->sms_enum_func)(mmguicore, &messages);
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);
1161
//After all, sort messages by timestamp
1162
messages = g_slist_sort(messages, mmguicore_sms_sort_timestamp_compare);
1168
mmgui_sms_message_t mmguicore_sms_get(mmguicore_t mmguicore, guint index)
1170
mmgui_sms_message_t message;
1172
if ((mmguicore == NULL) || (mmguicore->sms_get_func == NULL)) return NULL;
1174
message = (mmguicore->sms_get_func)(mmguicore, index);
1179
gboolean mmguicore_sms_delete(mmguicore_t mmguicore, guint index)
1181
if ((mmguicore == NULL) || (mmguicore->sms_delete_func == NULL)) return FALSE;
1183
return (mmguicore->sms_delete_func)(mmguicore, index);
1186
gboolean mmguicore_sms_validate_number(const gchar *number)
1189
gsize length, digitlength, i;
1193
if ((number != NULL) && (number[0] != '\0')) {
1194
length = strlen(number);
1195
if (number[0] == '+') {
1196
digitlength = length-1;
1198
digitlength = length;
1200
if ((digitlength < MMGUI_MIN_SMS_NUMBER_LENGTH) || (digitlength > MMGUI_MAX_SMS_NUMBER_LENGTH)) {
1203
for (i=0; i<length; i++) {
1204
if (((!isdigit(number[i])) && (number[i] != '+')) || ((i != 0) && (number[i] == '+'))) {
1217
gboolean mmguicore_sms_send(mmguicore_t mmguicore, gchar *number, gchar *text)
1219
if ((mmguicore == NULL) || (mmguicore->sms_send_func == NULL)) return FALSE;
1221
if ((number == NULL) || (text == NULL)) return FALSE;
1223
if ((!mmguicore_sms_validate_number(number)) || (text[0] == '\0')) return FALSE;
1225
return (mmguicore->sms_send_func)(mmguicore, number, text);
1228
guint mmguicore_ussd_get_capabilities(mmguicore_t mmguicore)
1230
if (mmguicore == NULL) return MMGUI_USSD_CAPS_NONE;
1231
if (mmguicore->device == NULL) return MMGUI_USSD_CAPS_NONE;
1233
return mmguicore->device->ussdcaps;
1236
static gchar *mmguicore_ussd_gsm7_to_ucs2(gchar *srcstr)
1238
gchar *decstr1, *decstr2;
1240
gboolean srcstrvalid;
1242
if (srcstr == NULL) return NULL;
1244
decstr1 = g_strdup(srcstr);
1245
strsize = strlen(srcstr);
1247
srcstrvalid = g_utf8_validate((const gchar *)srcstr, -1, (const gchar **)NULL);
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*/
1256
/*Return undecoded hash*/
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*/
1265
/*String not decoded*/
1267
/*Return valid source string*/
1269
return g_strdup(srcstr);
1271
/*Return undecoded hash*/
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*/
1283
/*Decoded string not validated*/
1286
/*Return valid source string*/
1288
return g_strdup(srcstr);
1290
/*Return undecoded hash*/
1295
/*String not decoded*/
1297
/*Return valid source string*/
1299
return g_strdup(srcstr);
1301
/*Return undecoded hash*/
1308
enum _mmgui_ussd_validation mmguicore_ussd_validate_request(gchar *request)
1310
enum _mmgui_ussd_validation statusid;
1314
statusid = MMGUI_USSD_VALIDATION_INVALID;
1316
if ((request == NULL) && (request[0] == '\0')) return statusid;
1318
length = strlen(request);
1320
if (length > MMGUI_MAX_USSD_REQUEST_LENGTH) return statusid;
1322
if ((request[0] == '*') && (request[length-1] == '#') && (length > 2)) {
1324
for (i=0; i<length; i++) {
1325
if ((!isdigit(request[i])) && (request[i] != '*') && (request[i] != '#')) {
1331
statusid = MMGUI_USSD_VALIDATION_REQUEST;
1333
statusid = MMGUI_USSD_VALIDATION_RESPONSE;
1336
statusid = MMGUI_USSD_VALIDATION_RESPONSE;
1342
gboolean mmguicore_ussd_cancel_session(mmguicore_t mmguicore)
1344
if ((mmguicore == NULL) || (mmguicore->ussd_cancel_session_func == NULL)) return FALSE;
1346
return (mmguicore->ussd_cancel_session_func)(mmguicore);
1349
enum _mmgui_ussd_state mmguicore_ussd_get_state(mmguicore_t mmguicore)
1351
enum _mmgui_ussd_state stateid;
1353
stateid = MMGUI_USSD_STATE_UNKNOWN;
1355
if ((mmguicore == NULL) || (mmguicore->ussd_get_state_func == NULL)) return stateid;
1357
stateid = (mmguicore->ussd_get_state_func)(mmguicore);
1362
gboolean mmguicore_ussd_send(mmguicore_t mmguicore, gchar *request)
1364
enum _mmgui_ussd_validation validationid;
1366
if ((mmguicore == NULL) || (mmguicore->ussd_send_func == NULL)) return FALSE;
1368
if (request == NULL) return FALSE;
1370
validationid = mmguicore_ussd_validate_request(request);
1372
return (mmguicore->ussd_send_func)(mmguicore, request, validationid);
1375
gboolean mmguicore_ussd_set_encoding(mmguicore_t mmguicore, enum _mmgui_ussd_encoding encoding)
1377
if ((mmguicore == NULL) || (mmguicore->device == NULL)) return FALSE;
1379
mmguicore->device->ussdencoding = encoding;
1384
enum _mmgui_ussd_encoding mmguicore_ussd_get_encoding(mmguicore_t mmguicore)
1386
if ((mmguicore == NULL) || (mmguicore->device == NULL)) return MMGUI_USSD_ENCODING_GSM7;
1388
return mmguicore->device->ussdencoding;
1391
guint mmguicore_newtworks_scan_get_capabilities(mmguicore_t mmguicore)
1393
if (mmguicore == NULL) return MMGUI_SCAN_CAPS_NONE;
1394
if (mmguicore->device == NULL) return MMGUI_SCAN_CAPS_NONE;
1396
return mmguicore->device->scancaps;
1399
static void mmguicore_networks_scan_free_foreach(gpointer data, gpointer user_data)
1401
mmgui_scanned_network_t network;
1403
if (data == NULL) return;
1405
network = (mmgui_scanned_network_t)data;
1407
if (network->operator_long != NULL) {
1408
g_free(network->operator_long);
1411
if (network->operator_short != NULL) {
1412
g_free(network->operator_short);
1416
void mmguicore_networks_scan_free(GSList *networks)
1418
if (networks == NULL) return;
1420
g_slist_foreach(networks, mmguicore_networks_scan_free_foreach, NULL);
1422
g_slist_free(networks);
1425
gboolean mmguicore_networks_scan(mmguicore_t mmguicore)
1427
if ((mmguicore == NULL) || (mmguicore->networks_scan_func == NULL)) return FALSE;
1429
return (mmguicore->networks_scan_func)(mmguicore);
1432
guint mmguicore_contacts_get_capabilities(mmguicore_t mmguicore)
1434
if (mmguicore == NULL) return MMGUI_CONTACTS_CAPS_NONE;
1435
if (mmguicore->device == NULL) return MMGUI_CONTACTS_CAPS_NONE;
1437
return mmguicore->device->contactscaps;
1440
void mmguicore_contacts_free_single(mmgui_contact_t contact, gboolean freestruct)
1442
if (contact == NULL) return;
1444
if (contact->name != NULL) {
1445
g_free(contact->name);
1447
if (contact->number != NULL) {
1448
g_free(contact->number);
1450
if (contact->email != NULL) {
1451
g_free(contact->email);
1453
if (contact->group != NULL) {
1454
g_free(contact->group);
1456
if (contact->name2 != NULL) {
1457
g_free(contact->name2);
1459
if (contact->number2 != NULL) {
1460
g_free(contact->number2);
1462
//Free contact structure
1468
static void mmguicore_contacts_free_foreach(gpointer data, gpointer user_data)
1470
mmgui_contact_t contact;
1472
if (data == NULL) return;
1474
contact = (mmgui_contact_t)data;
1476
mmguicore_contacts_free_single(contact, FALSE);
1479
static void mmguicore_contacts_free(GSList *contacts)
1481
if (contacts == NULL) return;
1483
g_slist_foreach(contacts, mmguicore_contacts_free_foreach, NULL);
1485
g_slist_free(contacts);
1488
static guint mmguicore_contacts_enum(mmguicore_t mmguicore)
1492
if ((mmguicore == NULL) || (mmguicore->contacts_enum_func == NULL)) return 0;
1493
if (mmguicore->device == NULL) return 0;
1495
if (mmguicore->device->contactslist != NULL) {
1496
mmguicore_contacts_free(mmguicore->device->contactslist);
1497
mmguicore->device->contactslist = NULL;
1500
numcontacts = (mmguicore->contacts_enum_func)(mmguicore, &(mmguicore->device->contactslist));
1505
GSList *mmguicore_contacts_list(mmguicore_t mmguicore)
1507
if (mmguicore == NULL) return NULL;
1508
if (mmguicore->device == NULL) return NULL;
1509
if (!(mmguicore->device->contactscaps & MMGUI_CONTACTS_CAPS_EXPORT)) return NULL;
1511
return mmguicore->device->contactslist;
1514
static gint mmguicore_contacts_get_compare(gconstpointer a, gconstpointer b)
1516
mmgui_contact_t contact;
1519
contact = (mmgui_contact_t)a;
1520
id = GPOINTER_TO_UINT(b);
1522
if (contact->id < id) {
1524
} else if (contact->id > id) {
1531
mmgui_contact_t mmguicore_contacts_get(mmguicore_t mmguicore, guint index)
1534
mmgui_contact_t contact;
1536
if (mmguicore == NULL) return NULL;
1537
if (mmguicore->device == NULL) return NULL;
1538
if (!(mmguicore->device->contactscaps & MMGUI_CONTACTS_CAPS_EXPORT)) return NULL;
1540
contactptr = g_slist_find_custom(mmguicore->device->contactslist, GUINT_TO_POINTER(index), mmguicore_contacts_get_compare);
1542
if (contactptr != NULL) {
1543
contact = (mmgui_contact_t)contactptr->data;
1550
static gint mmguicore_contacts_delete_compare(gconstpointer a, gconstpointer b)
1552
mmgui_contact_t contact;
1555
contact = (mmgui_contact_t)a;
1556
id = GPOINTER_TO_UINT(b);
1558
if (contact->id < id) {
1560
} else if (contact->id > id) {
1567
gboolean mmguicore_contacts_delete(mmguicore_t mmguicore, guint index)
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;
1576
result = (mmguicore->contacts_delete_func)(mmguicore, index);
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);
1591
gboolean mmguicore_contacts_add(mmguicore_t mmguicore, mmgui_contact_t contact)
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;
1600
index = (mmguicore->contacts_add_func)(mmguicore, contact);
1603
mmguicore->device->contactslist = g_slist_append(mmguicore->device->contactslist, contact);
1610
GHashTable *mmguicore_connections_sync(mmguicore_t mmguicore)
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;
1618
if (mmguicore == NULL) return NULL;
1619
if ((mmguicore->netlink == NULL) || (mmguicore->connections == NULL)) return NULL;
1621
#if GLIB_CHECK_VERSION(2,32,0)
1622
g_mutex_lock(&mmguicore->connsyncmutex);
1624
g_mutex_lock(mmguicore->connsyncmutex);
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;
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;
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);
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);
1670
g_slist_free(inslist);
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);
1679
extconnection->existsflag = FALSE;
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);
1688
g_slist_free(rmlist);
1691
#if GLIB_CHECK_VERSION(2,32,0)
1692
g_mutex_unlock(&mmguicore->connsyncmutex);
1694
g_mutex_unlock(mmguicore->connsyncmutex);
1697
return mmguicore->connections;
1700
static void mmguicore_connections_hash_destroy(gpointer data)
1702
mmgui_ext_connection_t connection;
1704
connection = (mmgui_ext_connection_t)data;
1706
if (connection->appname != NULL) {
1707
g_free(connection->appname);
1710
if (connection->dsthostname != NULL) {
1711
g_free(connection->dsthostname);
1714
if (connection != NULL) {
1719
gchar *mmguicore_get_last_error(mmguicore_t mmguicore)
1721
if ((mmguicore == NULL) || (mmguicore->last_error_func == NULL)) return NULL;
1723
return (mmguicore->last_error_func)(mmguicore);
1726
gchar *mmguicore_get_last_connection_error(mmguicore_t mmguicore)
1728
if ((mmguicore == NULL) || (mmguicore->connection_last_error_func == NULL)) return NULL;
1730
return (mmguicore->connection_last_error_func)(mmguicore);
1733
gboolean mmguicore_interrupt_operation(mmguicore_t mmguicore)
1735
if ((mmguicore == NULL) || (mmguicore->interrupt_operation_func == NULL)) return FALSE;
1737
return (mmguicore->interrupt_operation_func)(mmguicore);
1740
mmguicore_t mmguicore_new(mmgui_event_ext_callback callback, mmgui_traffic_limits_t limits, gpointer userdata)
1742
mmguicore_t mmguicore;
1744
mmguicore = g_new0(struct _mmguicore, 1);
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;
1789
mmguicore->devices = NULL;
1790
mmguicore->device = NULL;
1792
mmguicore->eventcb = mmguicore_event_callback;
1794
mmguicore->extcb = callback;
1796
mmguicore->limits = limits;
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)) {
1806
g_debug("No modules found\n");
1811
if (!mmguicore_modules_select(mmguicore)) {
1812
mmguicore_modules_close(mmguicore);
1813
mmguicore_modules_free(mmguicore);
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);
1823
mmguicore->workthreadmutex = g_mutex_new();
1824
mmguicore->connsyncmutex = g_mutex_new();
1827
#if GLIB_CHECK_VERSION(2,32,0)
1828
mmguicore->workthread = g_thread_new("Modem Manager GUI work thread", mmguicore_work_thread, mmguicore);
1830
mmguicore->workthread = g_thread_create(mmguicore_work_thread, mmguicore, TRUE, NULL);
1833
mmguicore->workthread = NULL;
1839
void mmguicore_close(mmguicore_t mmguicore)
1841
guint workthreadcmd;
1843
if (mmguicore == NULL) return;
1845
//Close opened device
1846
mmguicore_devices_close(mmguicore);
1849
workthreadcmd = MMGUI_THREAD_STOP_CMD;
1851
if (mmguicore->workthread != NULL) {
1853
#if GLIB_CHECK_VERSION(2,32,0)
1854
g_mutex_lock(&mmguicore->workthreadmutex);
1856
g_mutex_lock(mmguicore->workthreadmutex);
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]);
1865
#if GLIB_CHECK_VERSION(2,32,0)
1866
g_mutex_clear(&mmguicore->workthreadmutex);
1867
g_mutex_clear(&mmguicore->connsyncmutex);
1869
g_mutex_free(mmguicore->workthreadmutex);
1870
g_mutex_free(mmguicore->connsyncmutex);
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);
1882
mmguicore_modules_free(mmguicore);
1887
static gpointer mmguicore_work_thread(gpointer data)
1889
mmguicore_t mmguicore;
1891
gchar databuf[8192];
1893
guint activesockets;
1896
struct pollfd pollfds[3];
1897
//Work thread control
1898
gint ctlfd, ctlfdnum;
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;
1909
struct _mmgui_netlink_interface_event event;
1910
time_t ifstatetime, currenttime;
1912
gchar oldinterface[IFNAMSIZ];
1915
mmguicore = (mmguicore_t)data;
1917
if (mmguicore == NULL) return NULL;
1921
ctlfd = mmguicore->workthreadctl[1];
1924
ctlfdnum = activesockets;
1925
pollfds[ctlfdnum].fd = ctlfd;
1926
pollfds[ctlfdnum].events = POLLIN;
1930
intfd = mmgui_netlink_get_interfaces_monitoring_socket_fd(mmguicore->netlink);
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;
1946
connfd = mmgui_netlink_get_connections_monitoring_socket_fd(mmguicore->netlink);
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;
1962
//First we have to get device state
1963
ifstatetime = time(NULL);
1966
pollstatus = poll(pollfds, activesockets, 1000);
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) {
1978
g_debug("Work thread: Control command not received\n");
1983
//Lock mutex and work with device in safe mode
1984
#if GLIB_CHECK_VERSION(2,32,0)
1985
g_mutex_lock(&mmguicore->workthreadmutex);
1987
g_mutex_lock(mmguicore->workthreadmutex);
1990
currenttime = time(NULL);
1992
if (mmguicore->device != NULL) {
1993
if (abs((gint)difftime(ifstatetime, currenttime)) <= 5) {
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
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);
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);
2026
g_debug("Interface state changed\n");
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);
2040
} else if (pollstatus > 0) {
2041
//New data available
2042
//Interface monitoring
2043
if (pollfds[intfdnum].revents & POLLIN) {
2044
recvbytes = recvmsg(intfd, &intmsg, 0);
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))) {
2052
mmguicore_traffic_count(mmguicore, event.rxbytes, event.txbytes);
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);
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);
2078
g_debug("Work thread: interface event not received\n");
2081
//Connections monitoring
2082
if (pollfds[connfdnum].revents & POLLIN) {
2083
recvbytes = recvmsg(connfd, &connmsg, 0);
2085
#if GLIB_CHECK_VERSION(2,32,0)
2086
g_mutex_lock(&mmguicore->connsyncmutex);
2088
g_mutex_lock(mmguicore->connsyncmutex);
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);
2095
#if GLIB_CHECK_VERSION(2,32,0)
2096
g_mutex_unlock(&mmguicore->connsyncmutex);
2098
g_mutex_unlock(mmguicore->connsyncmutex);
2101
g_debug("Work thread: connections data not received\n");
2107
//Update internal device state
2108
mmguicore_devices_update_device_state(mmguicore);
2110
//Handle traffic limits
2111
mmguicore_traffic_limits(mmguicore);
2113
//Unlock mutex after work finished
2114
#if GLIB_CHECK_VERSION(2,32,0)
2115
g_mutex_unlock(&mmguicore->workthreadmutex);
2117
g_mutex_unlock(mmguicore->workthreadmutex);
2120
//Close thread control pipe descriptor
2121
close(mmguicore->workthreadctl[1]);
2126
static void mmguicore_traffic_count(mmguicore_t mmguicore, guint64 rxbytes, guint64 txbytes)
2128
mmguidevice_t device;
2131
struct _mmgui_traffic_update trafficupd;
2133
if (mmguicore == NULL) return;
2135
device = mmguicore->device;
2136
if (device == NULL) return;
2138
currenttime = time(NULL);
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++;
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);
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;
2166
mmgui_trafficdb_traffic_update(mmguicore->device->trafficdb, &trafficupd);
2168
//Update traffic count
2169
device->rxbytes = rxbytes;
2170
device->txbytes = txbytes;
2173
//Set last update time
2174
device->speedchecktime = currenttime;
2176
if (mmguicore->extcb != NULL) {
2177
(mmguicore->extcb)(MMGUI_EVENT_NET_STATUS, mmguicore, device, mmguicore->userdata);
2181
static void mmguicore_traffic_zero(mmguicore_t mmguicore)
2183
mmguidevice_t device;
2185
if (mmguicore == NULL) return;
2187
device = mmguicore->device;
2188
if (device == NULL) return;
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);
2199
if (mmguicore->extcb != NULL) {
2200
(mmguicore->extcb)(MMGUI_EVENT_NET_STATUS, mmguicore, NULL, mmguicore->userdata);
2204
static void mmguicore_traffic_limits(mmguicore_t mmguicore)
2206
if (mmguicore == NULL) return;
2208
if ((mmguicore->limits != NULL) && (mmguicore->device != NULL)) {
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);
2219
if (mmguicore->extcb != NULL) {
2220
(mmguicore->extcb)(MMGUI_EVENT_TRAFFIC_LIMIT, mmguicore, NULL, mmguicore->userdata);
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);
2235
if (mmguicore->extcb != NULL) {
2236
(mmguicore->extcb)(MMGUI_EVENT_TIME_LIMIT, mmguicore, NULL, mmguicore->userdata);