~ubuntu-branches/ubuntu/wily/bluez/wily

« back to all changes in this revision

Viewing changes to network/connection.c

ImportĀ upstreamĀ versionĀ 4.81

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 *
3
3
 *  BlueZ - Bluetooth protocol stack for Linux
4
4
 *
5
 
 *  Copyright (C) 2004-2009  Marcel Holtmann <marcel@holtmann.org>
 
5
 *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
6
6
 *
7
7
 *
8
8
 *  This program is free software; you can redistribute it and/or modify
31
31
#include <netinet/in.h>
32
32
 
33
33
#include <bluetooth/bluetooth.h>
34
 
#include <bluetooth/hci.h>
35
34
#include <bluetooth/bnep.h>
36
35
#include <bluetooth/sdp.h>
37
36
 
38
37
#include <glib.h>
39
38
#include <gdbus.h>
40
39
 
41
 
#include "logging.h"
 
40
#include "log.h"
42
41
#include "glib-helper.h"
43
42
#include "btio.h"
44
43
#include "dbus-common.h"
 
44
#include "adapter.h"
 
45
#include "device.h"
45
46
 
46
47
#include "error.h"
47
48
#include "common.h"
59
60
        bdaddr_t        src;
60
61
        bdaddr_t        dst;
61
62
        char            *path;          /* D-Bus path */
 
63
        struct btd_device *device;
62
64
        GSList          *connections;
63
65
};
64
66
 
69
71
        conn_state      state;
70
72
        GIOChannel      *io;
71
73
        guint           watch;          /* Disconnect watch */
 
74
        guint           dc_id;
72
75
        struct network_peer *peer;
73
76
};
74
77
 
78
81
} __attribute__ ((packed));
79
82
 
80
83
static DBusConnection *connection = NULL;
81
 
static const char *prefix = NULL;
82
84
static GSList *peers = NULL;
83
85
 
84
86
static struct network_peer *find_peer(GSList *list, const char *path)
138
140
{
139
141
        return g_dbus_create_error(msg,
140
142
                                ERROR_INTERFACE ".ConnectionAttemptFailed",
141
 
                                err ? err : "Connection attempt failed");
 
143
                                "%s", err ? err : "Connection attempt failed");
142
144
}
143
145
 
144
146
static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
153
155
                                        NETWORK_PEER_INTERFACE, "Connected",
154
156
                                        DBUS_TYPE_BOOLEAN, &connected);
155
157
                emit_property_changed(connection, nc->peer->path,
156
 
                                        NETWORK_PEER_INTERFACE, "Device",
 
158
                                        NETWORK_PEER_INTERFACE, "Interface",
157
159
                                        DBUS_TYPE_STRING, &property);
158
160
                emit_property_changed(connection, nc->peer->path,
159
161
                                        NETWORK_PEER_INTERFACE, "UUID",
160
162
                                        DBUS_TYPE_STRING, &property);
 
163
                device_remove_disconnect_watch(nc->peer->device, nc->dc_id);
 
164
                nc->dc_id = 0;
161
165
                if (nc->watch) {
162
166
                        g_dbus_remove_watch(connection, nc->watch);
163
167
                        nc->watch = 0;
168
172
 
169
173
        bnep_if_down(nc->dev);
170
174
        nc->state = DISCONNECTED;
171
 
        memset(nc->dev, 0, 16);
172
 
        strncpy(nc->dev, prefix, sizeof(nc->dev) - 1);
 
175
        memset(nc->dev, 0, sizeof(nc->dev));
 
176
        strcpy(nc->dev, "bnep%d");
173
177
 
174
178
        return FALSE;
175
179
}
206
210
                cancel_connection(nc, NULL);
207
211
}
208
212
 
 
213
static void disconnect_cb(struct btd_device *device, gboolean removal,
 
214
                                void *user_data)
 
215
{
 
216
        struct network_conn *nc = user_data;
 
217
 
 
218
        info("Network: disconnect %s", nc->peer->path);
 
219
 
 
220
        connection_destroy(NULL, user_data);
 
221
}
 
222
 
209
223
static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
210
224
                                                        gpointer data)
211
225
{
273
287
                goto failed;
274
288
        }
275
289
 
276
 
        bnep_if_up(nc->dev, nc->id);
 
290
        bnep_if_up(nc->dev);
277
291
        pdev = nc->dev;
278
292
        uuid = bnep_uuid(nc->id);
279
293
 
286
300
                                NETWORK_PEER_INTERFACE, "Connected",
287
301
                                DBUS_TYPE_BOOLEAN, &connected);
288
302
        emit_property_changed(connection, nc->peer->path,
289
 
                                NETWORK_PEER_INTERFACE, "Device",
 
303
                                NETWORK_PEER_INTERFACE, "Interface",
290
304
                                DBUS_TYPE_STRING, &pdev);
291
305
        emit_property_changed(connection, nc->peer->path,
292
306
                                NETWORK_PEER_INTERFACE, "UUID",
293
307
                                DBUS_TYPE_STRING, &uuid);
294
308
 
295
309
        nc->state = CONNECTED;
 
310
        nc->dc_id = device_add_disconnect_watch(nc->peer->device, disconnect_cb,
 
311
                                                nc, NULL);
296
312
 
297
313
        info("%s connected", nc->dev);
298
314
        /* Start watchdog */
484
500
        connected = nc ? TRUE : FALSE;
485
501
        dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN, &connected);
486
502
 
487
 
        /* Device */
 
503
        /* Interface */
488
504
        property = nc ? nc->dev : "";
489
 
        dict_append_entry(&dict, "Device", DBUS_TYPE_STRING, &property);
 
505
        dict_append_entry(&dict, "Interface", DBUS_TYPE_STRING, &property);
490
506
 
491
507
        /* UUID */
492
508
        property = nc ? bnep_uuid(nc->id) : "";
499
515
 
500
516
static void connection_free(struct network_conn *nc)
501
517
{
 
518
        if (nc->dc_id)
 
519
                device_remove_disconnect_watch(nc->peer->device, nc->dc_id);
 
520
 
502
521
        connection_destroy(connection, nc);
503
522
 
504
523
        g_free(nc);
509
528
{
510
529
        g_slist_foreach(peer->connections, (GFunc) connection_free, NULL);
511
530
        g_slist_free(peer->connections);
 
531
        btd_device_unref(peer->device);
512
532
        g_free(peer->path);
513
533
        g_free(peer);
514
534
}
517
537
{
518
538
        struct network_peer *peer = data;
519
539
 
520
 
        debug("Unregistered interface %s on path %s",
 
540
        DBG("Unregistered interface %s on path %s",
521
541
                NETWORK_PEER_INTERFACE, peer->path);
522
542
 
523
543
        peers = g_slist_remove(peers, peer);
558
578
        g_dbus_unregister_interface(connection, path, NETWORK_PEER_INTERFACE);
559
579
}
560
580
 
561
 
static struct network_peer *create_peer(const char *path, bdaddr_t *src,
562
 
                                bdaddr_t *dst)
 
581
static struct network_peer *create_peer(struct btd_device *device,
 
582
                                        const char *path, bdaddr_t *src,
 
583
                                        bdaddr_t *dst)
563
584
{
564
585
        struct network_peer *peer;
565
586
 
566
587
        peer = g_new0(struct network_peer, 1);
 
588
        peer->device = btd_device_ref(device);
567
589
        peer->path = g_strdup(path);
568
590
        bacpy(&peer->src, src);
569
591
        bacpy(&peer->dst, dst);
579
601
                return NULL;
580
602
        }
581
603
 
582
 
        debug("Registered interface %s on path %s",
 
604
        DBG("Registered interface %s on path %s",
583
605
                NETWORK_PEER_INTERFACE, path);
584
606
 
585
607
        return peer;
586
608
}
587
609
 
588
 
int connection_register(const char *path, bdaddr_t *src, bdaddr_t *dst,
589
 
                        uint16_t id)
 
610
int connection_register(struct btd_device *device, const char *path,
 
611
                        bdaddr_t *src, bdaddr_t *dst, uint16_t id)
590
612
{
591
613
        struct network_peer *peer;
592
614
        struct network_conn *nc;
596
618
 
597
619
        peer = find_peer(peers, path);
598
620
        if (!peer) {
599
 
                peer = create_peer(path, src, dst);
 
621
                peer = create_peer(device, path, src, dst);
600
622
                if (!peer)
601
623
                        return -1;
602
624
                peers = g_slist_append(peers, peer);
608
630
 
609
631
        nc = g_new0(struct network_conn, 1);
610
632
        nc->id = id;
611
 
        memset(nc->dev, 0, 16);
612
 
        strncpy(nc->dev, prefix, sizeof(nc->dev) - 1);
 
633
        memset(nc->dev, 0, sizeof(nc->dev));
 
634
        strcpy(nc->dev, "bnep%d");
613
635
        nc->state = DISCONNECTED;
614
636
        nc->peer = peer;
615
637
 
618
640
        return 0;
619
641
}
620
642
 
621
 
int connection_init(DBusConnection *conn, const char *iface_prefix)
 
643
int connection_init(DBusConnection *conn)
622
644
{
623
645
        connection = dbus_connection_ref(conn);
624
 
        prefix = iface_prefix;
625
646
 
626
647
        return 0;
627
648
}
628
649
 
629
 
void connection_exit()
 
650
void connection_exit(void)
630
651
{
631
652
        dbus_connection_unref(connection);
632
653
        connection = NULL;
633
 
        prefix = NULL;
634
654
}