~phablet-team/ofono/ofono-bug-updates

« back to all changes in this revision

Viewing changes to dundee/device.c

  • Committer: Denis Kenzior
  • Author(s): Lucas De Marchi
  • Date: 2011-03-18 23:31:14 UTC
  • Revision ID: git-v1:888e07863b24026413bac8f449de377c879e1044
message: add cancelled state

Based on patch from Yang Gu <gyagp0@gmail.com>

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 *  oFono - Open Source Telephony
3
 
 *
4
 
 *  Copyright (C) 2008-2012  Intel Corporation. All rights reserved.
5
 
 *  Copyright (C) 2012  BMW Car IT GmbH. All rights reserved.
6
 
 *
7
 
 *  This program is free software; you can redistribute it and/or modify
8
 
 *  it under the terms of the GNU General Public License version 2 as
9
 
 *  published by the Free Software Foundation.
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, write to the Free Software
18
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
 
 *
20
 
 */
21
 
 
22
 
#ifdef HAVE_CONFIG_H
23
 
#include <config.h>
24
 
#endif
25
 
 
26
 
#include <errno.h>
27
 
#include <string.h>
28
 
#include <stdio.h>
29
 
#include <netinet/ether.h>
30
 
 
31
 
#include <glib.h>
32
 
#include <gdbus.h>
33
 
#include <gatchat.h>
34
 
#include <gatppp.h>
35
 
 
36
 
#include "dundee.h"
37
 
 
38
 
#define PPP_TIMEOUT 15
39
 
 
40
 
static int next_device_id = 0;
41
 
static GHashTable *device_hash;
42
 
 
43
 
static const char *none_prefix[] = { NULL };
44
 
 
45
 
struct ipv4_settings {
46
 
        char *interface;
47
 
        char *ip;
48
 
        char **nameservers;
49
 
};
50
 
 
51
 
struct dundee_device {
52
 
        char *path;
53
 
        struct dundee_device_driver *driver;
54
 
        gboolean registered;
55
 
 
56
 
        GAtPPP *ppp;
57
 
        GAtChat *chat;
58
 
 
59
 
        char *name;
60
 
        gboolean active;
61
 
        struct ipv4_settings settings;
62
 
 
63
 
        DBusMessage *pending;
64
 
        guint connect_timeout;
65
 
        void *data;
66
 
};
67
 
 
68
 
const char *__dundee_device_get_path(struct dundee_device *device)
69
 
{
70
 
        return device->path;
71
 
}
72
 
 
73
 
static void settings_append(struct dundee_device *device,
74
 
                                        DBusMessageIter *iter)
75
 
{
76
 
        DBusMessageIter variant;
77
 
        DBusMessageIter array;
78
 
        char typesig[5];
79
 
        char arraysig[6];
80
 
 
81
 
        arraysig[0] = DBUS_TYPE_ARRAY;
82
 
        arraysig[1] = typesig[0] = DBUS_DICT_ENTRY_BEGIN_CHAR;
83
 
        arraysig[2] = typesig[1] = DBUS_TYPE_STRING;
84
 
        arraysig[3] = typesig[2] = DBUS_TYPE_VARIANT;
85
 
        arraysig[4] = typesig[3] = DBUS_DICT_ENTRY_END_CHAR;
86
 
        arraysig[5] = typesig[4] = '\0';
87
 
 
88
 
        dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT,
89
 
                                                arraysig, &variant);
90
 
 
91
 
        dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY,
92
 
                                                typesig, &array);
93
 
 
94
 
        if (device->active == FALSE)
95
 
                goto out;
96
 
 
97
 
        if (device->settings.interface)
98
 
                ofono_dbus_dict_append(&array, "Interface",
99
 
                                DBUS_TYPE_STRING, &device->settings.interface);
100
 
 
101
 
        if (device->settings.ip)
102
 
                ofono_dbus_dict_append(&array, "Address", DBUS_TYPE_STRING,
103
 
                                        &device->settings.ip);
104
 
 
105
 
        if (device->settings.nameservers)
106
 
                ofono_dbus_dict_append_array(&array, "DomainNameServers",
107
 
                                                DBUS_TYPE_STRING,
108
 
                                                &device->settings.nameservers);
109
 
 
110
 
out:
111
 
        dbus_message_iter_close_container(&variant, &array);
112
 
 
113
 
        dbus_message_iter_close_container(iter, &variant);
114
 
}
115
 
 
116
 
static void settings_append_dict(struct dundee_device *device,
117
 
                                DBusMessageIter *dict)
118
 
{
119
 
        DBusMessageIter entry;
120
 
        const char *key = "Settings";
121
 
 
122
 
        dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
123
 
                                                NULL, &entry);
124
 
 
125
 
        dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
126
 
 
127
 
        settings_append(device, &entry);
128
 
 
129
 
        dbus_message_iter_close_container(dict, &entry);
130
 
}
131
 
 
132
 
void __dundee_device_append_properties(struct dundee_device *device,
133
 
                                        DBusMessageIter *dict)
134
 
{
135
 
        settings_append_dict(device, dict);
136
 
 
137
 
        ofono_dbus_dict_append(dict, "Name", DBUS_TYPE_STRING,
138
 
                                &device->name);
139
 
 
140
 
        ofono_dbus_dict_append(dict, "Active", DBUS_TYPE_BOOLEAN,
141
 
                                &device->active);
142
 
}
143
 
 
144
 
void __dundee_device_foreach(dundee_device_foreach_func func, void *userdata)
145
 
{
146
 
        GHashTableIter iter;
147
 
        gpointer key, value;
148
 
 
149
 
        DBG("");
150
 
 
151
 
        g_hash_table_iter_init(&iter, device_hash);
152
 
 
153
 
        while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
154
 
                struct dundee_device *device = value;
155
 
 
156
 
                func(device, userdata);
157
 
        }
158
 
}
159
 
 
160
 
static void settings_changed(struct dundee_device *device)
161
 
{
162
 
        DBusConnection *conn = ofono_dbus_get_connection();
163
 
        DBusMessage *signal;
164
 
        DBusMessageIter iter;
165
 
        const char *key = "Settings";
166
 
 
167
 
        signal = dbus_message_new_signal(device->path,
168
 
                                        DUNDEE_DEVICE_INTERFACE,
169
 
                                        "PropertyChanged");
170
 
 
171
 
        if (signal == NULL)
172
 
                return;
173
 
        dbus_message_iter_init_append(signal, &iter);
174
 
        dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key);
175
 
 
176
 
        settings_append(device, &iter);
177
 
 
178
 
        g_dbus_send_message(conn, signal);
179
 
}
180
 
 
181
 
static DBusMessage *device_get_properties(DBusConnection *conn,
182
 
                                        DBusMessage *msg, void *data)
183
 
{
184
 
        struct dundee_device *device = data;
185
 
        DBusMessage *reply;
186
 
        DBusMessageIter iter;
187
 
        DBusMessageIter dict;
188
 
 
189
 
        reply = dbus_message_new_method_return(msg);
190
 
        if (reply == NULL)
191
 
                return NULL;
192
 
 
193
 
        dbus_message_iter_init_append(reply, &iter);
194
 
 
195
 
        dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
196
 
                                        OFONO_PROPERTIES_ARRAY_SIGNATURE,
197
 
                                        &dict);
198
 
 
199
 
        __dundee_device_append_properties(device, &dict);
200
 
 
201
 
        dbus_message_iter_close_container(&iter, &dict);
202
 
 
203
 
        return reply;
204
 
}
205
 
 
206
 
 
207
 
static void debug(const char *str, void *data)
208
 
{
209
 
        DBG("%s: %s\n", (const char *) data, str);
210
 
}
211
 
 
212
 
static void ppp_connect(const char *iface, const char *local, const char *peer,
213
 
                        const char *dns1, const char *dns2,
214
 
                        gpointer user_data)
215
 
{
216
 
        DBusConnection *conn = ofono_dbus_get_connection();
217
 
        struct dundee_device *device = user_data;
218
 
        const char *dns[3] = { dns1, dns2, 0 };
219
 
 
220
 
        DBG("%p", device);
221
 
        DBG("Network Device: %s\n", iface);
222
 
        DBG("IP Address: %s\n", local);
223
 
        DBG("Peer IP Address: %s\n", peer);
224
 
        DBG("Primary DNS Server: %s\n", dns1);
225
 
        DBG("Secondary DNS Server: %s\n", dns2);
226
 
 
227
 
        if (device->connect_timeout > 0) {
228
 
                g_source_remove(device->connect_timeout);
229
 
                device->connect_timeout = 0;
230
 
        }
231
 
 
232
 
        g_free(device->settings.interface);
233
 
        device->settings.interface = g_strdup(iface);
234
 
        if (device->settings.interface == NULL)
235
 
                goto err;
236
 
 
237
 
        g_free(device->settings.ip);
238
 
        device->settings.ip = g_strdup(local);
239
 
        if (device->settings.ip == NULL)
240
 
                goto err;
241
 
 
242
 
        g_strfreev(device->settings.nameservers);
243
 
        device->settings.nameservers = g_strdupv((gchar **)dns);
244
 
        if (device->settings.nameservers == NULL)
245
 
                goto err;
246
 
 
247
 
        __ofono_dbus_pending_reply(&device->pending,
248
 
                        dbus_message_new_method_return(device->pending));
249
 
        device->pending = NULL;
250
 
 
251
 
        device->active = TRUE;
252
 
 
253
 
        settings_changed(device);
254
 
        ofono_dbus_signal_property_changed(conn, device->path,
255
 
                                        DUNDEE_DEVICE_INTERFACE, "Active",
256
 
                                        DBUS_TYPE_BOOLEAN, &device->active);
257
 
 
258
 
        return;
259
 
 
260
 
err:
261
 
        g_free(device->settings.interface);
262
 
        g_free(device->settings.ip);
263
 
        g_strfreev(device->settings.nameservers);
264
 
        device->settings.interface = NULL;
265
 
        device->settings.ip = NULL;
266
 
        device->settings.nameservers = NULL;
267
 
 
268
 
        __ofono_dbus_pending_reply(&device->pending,
269
 
                                __dundee_error_failed(device->pending));
270
 
        device->pending = NULL;
271
 
}
272
 
 
273
 
static void disconnect_callback(const struct dundee_error *error, void *data)
274
 
{
275
 
        struct dundee_device *device = data;
276
 
 
277
 
        DBG("%p", device);
278
 
 
279
 
        g_at_chat_unref(device->chat);
280
 
        device->chat = NULL;
281
 
 
282
 
        if (device->pending == NULL)
283
 
                return;
284
 
 
285
 
        if (error->type != DUNDEE_ERROR_TYPE_NO_ERROR) {
286
 
                __ofono_dbus_pending_reply(&device->pending,
287
 
                                        __dundee_error_failed(device->pending));
288
 
                goto out;
289
 
        }
290
 
 
291
 
        __ofono_dbus_pending_reply(&device->pending,
292
 
                dbus_message_new_method_return(device->pending));
293
 
 
294
 
out:
295
 
        device->pending = NULL;
296
 
}
297
 
 
298
 
static gboolean ppp_connect_timeout(gpointer user_data)
299
 
{
300
 
        struct dundee_device *device = user_data;
301
 
 
302
 
        if (device->pending != NULL) {
303
 
                __ofono_dbus_pending_reply(&device->pending,
304
 
                                __dundee_error_timed_out(device->pending));
305
 
                device->pending = NULL;
306
 
        }
307
 
 
308
 
        device->driver->disconnect(device, disconnect_callback, device);
309
 
 
310
 
        device->connect_timeout = 0;
311
 
 
312
 
        return FALSE;
313
 
}
314
 
 
315
 
static void ppp_disconnect(GAtPPPDisconnectReason reason, gpointer user_data)
316
 
{
317
 
        DBusConnection *conn = ofono_dbus_get_connection();
318
 
        struct dundee_device *device = user_data;
319
 
 
320
 
        DBG("%p", device);
321
 
        DBG("PPP Link down: %d\n", reason);
322
 
 
323
 
        g_at_ppp_unref(device->ppp);
324
 
        device->ppp = NULL;
325
 
 
326
 
        g_at_chat_resume(device->chat);
327
 
 
328
 
        g_free(device->settings.interface);
329
 
        g_free(device->settings.ip);
330
 
        g_strfreev(device->settings.nameservers);
331
 
        device->settings.interface = NULL;
332
 
        device->settings.ip = NULL;
333
 
        device->settings.nameservers = NULL;
334
 
 
335
 
        device->active = FALSE;
336
 
 
337
 
        settings_changed(device);
338
 
        ofono_dbus_signal_property_changed(conn, device->path,
339
 
                                        DUNDEE_DEVICE_INTERFACE, "Active",
340
 
                                        DBUS_TYPE_BOOLEAN, &device->active);
341
 
 
342
 
        device->driver->disconnect(device, disconnect_callback, device);
343
 
}
344
 
 
345
 
static void dial_cb(gboolean ok, GAtResult *result, gpointer user_data)
346
 
{
347
 
        struct dundee_device *device = user_data;
348
 
        GAtIO *io;
349
 
 
350
 
        if (!ok) {
351
 
                DBG("Unable to define context\n");
352
 
                goto err;
353
 
        }
354
 
 
355
 
        /* get the data IO channel */
356
 
        io = g_at_chat_get_io(device->chat);
357
 
 
358
 
        /*
359
 
         * shutdown gatchat or else it tries to take all the input
360
 
         * from the modem and does not let PPP get it.
361
 
         */
362
 
        g_at_chat_suspend(device->chat);
363
 
 
364
 
        /* open ppp */
365
 
        device->ppp = g_at_ppp_new();
366
 
        if (device->ppp == NULL) {
367
 
                DBG("Unable to create PPP object\n");
368
 
                goto err;
369
 
        }
370
 
        g_at_ppp_set_debug(device->ppp, debug, "PPP");
371
 
 
372
 
        device->connect_timeout = g_timeout_add_seconds(PPP_TIMEOUT,
373
 
                                                ppp_connect_timeout, device);
374
 
 
375
 
        /* set connect and disconnect callbacks */
376
 
        g_at_ppp_set_connect_function(device->ppp, ppp_connect, device);
377
 
        g_at_ppp_set_disconnect_function(device->ppp, ppp_disconnect, device);
378
 
 
379
 
        /* open the ppp connection */
380
 
        g_at_ppp_open(device->ppp, io);
381
 
 
382
 
        return;
383
 
 
384
 
err:
385
 
        __ofono_dbus_pending_reply(&device->pending,
386
 
                                __dundee_error_failed(device->pending));
387
 
        device->pending = NULL;
388
 
 
389
 
        device->driver->disconnect(device, disconnect_callback, device);
390
 
}
391
 
 
392
 
static int device_dial_setup(struct dundee_device *device, int fd)
393
 
{
394
 
        GAtSyntax *syntax;
395
 
        GIOChannel *io;
396
 
 
397
 
        io = g_io_channel_unix_new(fd);
398
 
        if (io == NULL)
399
 
                return -EIO;
400
 
 
401
 
        syntax = g_at_syntax_new_gsm_permissive();
402
 
        device->chat = g_at_chat_new(io, syntax);
403
 
        g_io_channel_unref(io);
404
 
        g_at_syntax_unref(syntax);
405
 
 
406
 
        if (device->chat == NULL)
407
 
                return -EIO;
408
 
 
409
 
        g_at_chat_set_debug(device->chat, debug, "Control");
410
 
 
411
 
        g_at_chat_send(device->chat, "ATD*99#", none_prefix, dial_cb,
412
 
                        device, NULL);
413
 
 
414
 
        return 0;
415
 
}
416
 
 
417
 
static void connect_callback(const struct dundee_error *error,
418
 
                                int fd, void *data)
419
 
{
420
 
        struct dundee_device *device = data;
421
 
        int err;
422
 
 
423
 
        DBG("%p", device);
424
 
 
425
 
        if (error->type != DUNDEE_ERROR_TYPE_NO_ERROR)
426
 
                goto err;
427
 
 
428
 
        err = device_dial_setup(device, fd);
429
 
        if (err < 0)
430
 
                goto err;
431
 
 
432
 
        return;
433
 
 
434
 
err:
435
 
        __ofono_dbus_pending_reply(&device->pending,
436
 
                                __dundee_error_failed(device->pending));
437
 
        device->pending = NULL;
438
 
}
439
 
 
440
 
static DBusMessage *set_property_active(struct dundee_device *device,
441
 
                                        DBusMessage *msg,
442
 
                                        DBusMessageIter *var)
443
 
{
444
 
        ofono_bool_t active;
445
 
 
446
 
        DBG("%p path %s", device, device->path);
447
 
 
448
 
        if (dbus_message_iter_get_arg_type(var) != DBUS_TYPE_BOOLEAN)
449
 
                return __dundee_error_invalid_args(msg);
450
 
 
451
 
        dbus_message_iter_get_basic(var, &active);
452
 
 
453
 
        device->pending = dbus_message_ref(msg);
454
 
 
455
 
        if (active)
456
 
                device->driver->connect(device, connect_callback, device);
457
 
        else if (device->ppp)
458
 
                g_at_ppp_shutdown(device->ppp);
459
 
 
460
 
        return NULL;
461
 
}
462
 
 
463
 
static DBusMessage *device_set_property(DBusConnection *conn,
464
 
                                        DBusMessage *msg, void *data)
465
 
{
466
 
        struct dundee_device *device = data;
467
 
        DBusMessageIter iter, var;
468
 
        const char *name;
469
 
 
470
 
        if (dbus_message_iter_init(msg, &iter) == FALSE)
471
 
                return __dundee_error_invalid_args(msg);
472
 
 
473
 
        if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
474
 
                return __dundee_error_invalid_args(msg);
475
 
 
476
 
        dbus_message_iter_get_basic(&iter, &name);
477
 
        dbus_message_iter_next(&iter);
478
 
 
479
 
        if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
480
 
                return __dundee_error_invalid_args(msg);
481
 
 
482
 
        dbus_message_iter_recurse(&iter, &var);
483
 
 
484
 
        if (g_str_equal(name, "Active"))
485
 
                return set_property_active(device, msg, &var);
486
 
 
487
 
        return __dundee_error_invalid_args(msg);
488
 
}
489
 
 
490
 
static const GDBusMethodTable device_methods[] = {
491
 
        { GDBUS_METHOD("GetProperties",
492
 
                        NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
493
 
                        device_get_properties) },
494
 
        { GDBUS_ASYNC_METHOD("SetProperty",
495
 
                        GDBUS_ARGS({ "property", "s" }, { "value", "v" }),
496
 
                        NULL, device_set_property) },
497
 
        { }
498
 
};
499
 
 
500
 
static const GDBusSignalTable device_signals[] = {
501
 
        { GDBUS_SIGNAL("PropertyChanged",
502
 
                        GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
503
 
        { }
504
 
};
505
 
 
506
 
static int register_device(struct dundee_device *device)
507
 
{
508
 
        DBusConnection *conn = ofono_dbus_get_connection();
509
 
        DBusMessage *signal;
510
 
        DBusMessageIter iter;
511
 
        DBusMessageIter dict;
512
 
 
513
 
        DBG("%p path %s", device, device->path);
514
 
 
515
 
        if (!g_dbus_register_interface(conn, device->path,
516
 
                                        DUNDEE_DEVICE_INTERFACE,
517
 
                                        device_methods, device_signals,
518
 
                                        NULL, device, NULL)) {
519
 
                ofono_error("Could not register Device %s", device->path);
520
 
                return -EIO;
521
 
        }
522
 
 
523
 
        signal = dbus_message_new_signal(DUNDEE_MANAGER_PATH,
524
 
                                                DUNDEE_MANAGER_INTERFACE,
525
 
                                                "DeviceAdded");
526
 
 
527
 
        if (signal == NULL)
528
 
                return -ENOMEM;
529
 
 
530
 
        dbus_message_iter_init_append(signal, &iter);
531
 
 
532
 
        dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH,
533
 
                                        &device->path);
534
 
        dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
535
 
                                        OFONO_PROPERTIES_ARRAY_SIGNATURE,
536
 
                                        &dict);
537
 
        __dundee_device_append_properties(device, &dict);
538
 
        dbus_message_iter_close_container(&iter, &dict);
539
 
 
540
 
        g_dbus_send_message(conn, signal);
541
 
 
542
 
        return 0;
543
 
}
544
 
 
545
 
static int unregister_device(struct dundee_device *device)
546
 
{
547
 
        DBusConnection *conn = ofono_dbus_get_connection();
548
 
 
549
 
        DBG("%p path %s", device, device->path);
550
 
 
551
 
        g_dbus_unregister_interface(conn, device->path,
552
 
                                        DUNDEE_DEVICE_INTERFACE);
553
 
 
554
 
        g_dbus_emit_signal(conn, DUNDEE_MANAGER_PATH,
555
 
                                DUNDEE_MANAGER_INTERFACE, "DeviceRemoved",
556
 
                                DBUS_TYPE_OBJECT_PATH, &device->path,
557
 
                                DBUS_TYPE_INVALID);
558
 
 
559
 
        return 0;
560
 
}
561
 
 
562
 
static void destroy_device(gpointer user)
563
 
{
564
 
        struct dundee_device *device = user;
565
 
 
566
 
        if (device->chat != NULL)
567
 
                g_at_chat_unref(device->chat);
568
 
 
569
 
        if (device->ppp != NULL)
570
 
                g_at_ppp_unref(device->ppp);
571
 
 
572
 
        if (device->pending)
573
 
                dbus_message_unref(device->pending);
574
 
 
575
 
        g_free(device->settings.interface);
576
 
        g_free(device->settings.ip);
577
 
        g_strfreev(device->settings.nameservers);
578
 
 
579
 
        g_free(device->path);
580
 
        g_free(device->name);
581
 
 
582
 
        g_free(device);
583
 
}
584
 
 
585
 
struct dundee_device *dundee_device_create(struct dundee_device_driver *d)
586
 
{
587
 
        struct dundee_device *device;
588
 
 
589
 
        device = g_try_new0(struct dundee_device, 1);
590
 
        if (device == NULL)
591
 
                return NULL;
592
 
 
593
 
        device->driver = d;
594
 
 
595
 
        device->path = g_strdup_printf("/device%d", next_device_id);
596
 
        if (device->path == NULL) {
597
 
                g_free(device);
598
 
                return NULL;
599
 
        }
600
 
 
601
 
        next_device_id += 1;
602
 
 
603
 
        return device;
604
 
}
605
 
 
606
 
int dundee_device_register(struct dundee_device *device)
607
 
{
608
 
        int err;
609
 
 
610
 
        err = register_device(device);
611
 
        if (err < 0)
612
 
                return err;
613
 
 
614
 
        device->registered = TRUE;
615
 
 
616
 
        g_hash_table_insert(device_hash, g_strdup(device->path), device);
617
 
 
618
 
        return 0;
619
 
}
620
 
 
621
 
void dundee_device_unregister(struct dundee_device *device)
622
 
{
623
 
        DBG("%p", device);
624
 
 
625
 
        unregister_device(device);
626
 
 
627
 
        device->registered = FALSE;
628
 
 
629
 
        g_hash_table_remove(device_hash, device->path);
630
 
}
631
 
 
632
 
void dundee_device_set_data(struct dundee_device *device, void *data)
633
 
{
634
 
        device->data = data;
635
 
}
636
 
 
637
 
void *dundee_device_get_data(struct dundee_device *device)
638
 
{
639
 
        return device->data;
640
 
}
641
 
 
642
 
int dundee_device_set_name(struct dundee_device *device, const char *name)
643
 
{
644
 
        DBusConnection *conn = ofono_dbus_get_connection();
645
 
 
646
 
        DBG("%p name %s", device, name);
647
 
 
648
 
        g_free(device->name);
649
 
        device->name = g_strdup(name);
650
 
 
651
 
        if (device->registered == FALSE)
652
 
                return 0;
653
 
 
654
 
        ofono_dbus_signal_property_changed(conn, device->path,
655
 
                                        DUNDEE_DEVICE_INTERFACE, "Name",
656
 
                                        DBUS_TYPE_STRING, &device->name);
657
 
 
658
 
        return 0;
659
 
}
660
 
 
661
 
static void device_shutdown(gpointer key, gpointer value, gpointer user_data)
662
 
{
663
 
        struct dundee_device *device = value;
664
 
 
665
 
        unregister_device(device);
666
 
}
667
 
 
668
 
void __dundee_device_shutdown(void)
669
 
{
670
 
        g_hash_table_foreach(device_hash, device_shutdown, NULL);
671
 
 
672
 
        __dundee_exit();
673
 
}
674
 
 
675
 
int __dundee_device_init(void)
676
 
{
677
 
        DBG("");
678
 
 
679
 
        device_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
680
 
                                                g_free, destroy_device);
681
 
 
682
 
        return 0;
683
 
}
684
 
 
685
 
void __dundee_device_cleanup(void)
686
 
{
687
 
        DBG("");
688
 
 
689
 
        g_hash_table_destroy(device_hash);
690
 
}