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

« back to all changes in this revision

Viewing changes to network/server.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 <errno.h>
32
32
 
33
33
#include <bluetooth/bluetooth.h>
34
 
#include <bluetooth/hci.h>
35
34
#include <bluetooth/bnep.h>
36
 
#include <bluetooth/l2cap.h>
37
35
#include <bluetooth/sdp.h>
38
36
#include <bluetooth/sdp_lib.h>
39
37
#include <netinet/in.h>
44
42
#include "../src/dbus-common.h"
45
43
#include "../src/adapter.h"
46
44
 
47
 
#include "logging.h"
 
45
#include "log.h"
48
46
#include "error.h"
49
47
#include "sdpd.h"
50
48
#include "btio.h"
51
49
#include "glib-helper.h"
52
50
 
53
 
#include "bridge.h"
54
51
#include "common.h"
55
52
#include "server.h"
56
53
 
57
 
#define NETWORK_PEER_INTERFACE "org.bluez.NetworkPeer"
58
 
#define NETWORK_HUB_INTERFACE "org.bluez.NetworkHub"
59
 
#define NETWORK_ROUTER_INTERFACE "org.bluez.NetworkRouter"
 
54
#define NETWORK_SERVER_INTERFACE "org.bluez.NetworkServer"
60
55
#define SETUP_TIMEOUT           1
61
56
 
62
57
/* Pending Authorization */
67
62
};
68
63
 
69
64
struct network_adapter {
70
 
        bdaddr_t        src;            /* Bluetooth Local Address */
71
 
        char            *path;          /* D-Bus path */
 
65
        struct btd_adapter *adapter;    /* Adapter pointer */
72
66
        GIOChannel      *io;            /* Bnep socket */
73
67
        struct network_session *setup;  /* Setup in progress */
74
68
        GSList          *servers;       /* Server register to adapter */
76
70
 
77
71
/* Main server structure */
78
72
struct network_server {
 
73
        bdaddr_t        src;            /* Bluetooth Local Address */
79
74
        char            *iface;         /* DBus interface */
80
75
        char            *name;          /* Server service name */
81
 
        char            *range;         /* IP Address range */
82
 
        gboolean        enable;         /* Enable flag */
 
76
        char            *bridge;        /* Bridge name */
83
77
        uint32_t        record_id;      /* Service record id */
84
78
        uint16_t        id;             /* Service class identifier */
85
79
        GSList          *sessions;      /* Active connections */
86
80
        struct network_adapter *na;     /* Adapter reference */
 
81
        guint           watch_id;       /* Client service watch */
87
82
};
88
83
 
89
84
static DBusConnection *connection = NULL;
90
85
static GSList *adapters = NULL;
91
 
static const char *prefix = NULL;
92
86
static gboolean security = TRUE;
93
87
 
94
 
static struct network_adapter *find_adapter(GSList *list, const char *path)
 
88
static struct network_adapter *find_adapter(GSList *list,
 
89
                                        struct btd_adapter *adapter)
95
90
{
96
91
        GSList *l;
97
92
 
98
93
        for (l = list; l; l = l->next) {
99
94
                struct network_adapter *na = l->data;
100
95
 
101
 
                if (g_str_equal(na->path, path))
 
96
                if (na->adapter == adapter)
102
97
                        return na;
103
98
        }
104
99
 
144
139
        uint16_t security_desc = (security ? 0x0001 : 0x0000);
145
140
        uint16_t net_access_type = 0xfffe;
146
141
        uint32_t max_net_access_rate = 0;
147
 
        const char *desc = "BlueZ PAN service";
 
142
        const char *desc = "Network service";
148
143
        sdp_record_t *record;
149
144
 
150
145
        record = sdp_record_alloc();
275
270
                                uint16_t dst_role)
276
271
{
277
272
        char devname[16];
278
 
        const char *bridge;
279
273
        int err, nsk;
280
274
 
281
 
        /* Server can be disabled in the meantime */
282
 
        if (ns->enable == FALSE)
283
 
                return -EPERM;
284
 
 
285
 
        memset(devname, 0, 16);
286
 
        strncpy(devname, prefix, sizeof(devname) - 1);
 
275
        memset(devname, 0, sizeof(devname));
 
276
        strcpy(devname, "bnep%d");
287
277
 
288
278
        nsk = g_io_channel_unix_get_fd(session->io);
289
279
        err = bnep_connadd(nsk, dst_role, devname);
292
282
 
293
283
        info("Added new connection: %s", devname);
294
284
 
295
 
        bridge = bridge_get_name(ns->id);
296
 
        if (bridge) {
297
 
                if (bridge_add_interface(ns->id, devname) < 0) {
298
 
                        error("Can't add %s to the bridge %s: %s(%d)",
299
 
                                        devname, bridge, strerror(errno),
300
 
                                        errno);
301
 
                        return -EPERM;
302
 
                }
 
285
        if (bnep_add_to_bridge(devname, ns->bridge) < 0) {
 
286
                error("Can't add %s to the bridge %s: %s(%d)",
 
287
                                devname, ns->bridge, strerror(errno), errno);
 
288
                return -EPERM;
 
289
        }
303
290
 
304
 
                bnep_if_up(devname, 0);
305
 
        } else
306
 
                bnep_if_up(devname, ns->id);
 
291
        bnep_if_up(devname);
307
292
 
308
293
        ns->sessions = g_slist_append(ns->sessions, session);
309
294
 
321
306
                return BNEP_CONN_INVALID_SRC;
322
307
        case BNEP_SVC_PANU:
323
308
                if (src_role == BNEP_SVC_PANU ||
324
 
                        src_role == BNEP_SVC_GN ||
325
 
                        src_role == BNEP_SVC_NAP)
 
309
                                src_role == BNEP_SVC_GN ||
 
310
                                src_role == BNEP_SVC_NAP)
326
311
                        return 0;
327
312
 
328
313
                return BNEP_CONN_INVALID_SRC;
421
406
                goto reply;
422
407
 
423
408
        ns = find_server(na->servers, dst_role);
424
 
        if (!ns || ns->enable == FALSE) {
 
409
        if (!ns) {
425
410
                error("Server unavailable: (0x%x)", dst_role);
426
411
                goto reply;
427
412
        }
428
413
 
 
414
        if (!ns->record_id) {
 
415
                error("Service record not available");
 
416
                goto reply;
 
417
        }
 
418
 
 
419
        if (!ns->bridge) {
 
420
                error("Bridge interface not configured");
 
421
                goto reply;
 
422
        }
 
423
 
429
424
        if (server_connadd(ns, na->setup, dst_role) < 0)
430
425
                goto reply;
431
426
 
483
478
static void confirm_event(GIOChannel *chan, gpointer user_data)
484
479
{
485
480
        struct network_adapter *na = user_data;
 
481
        struct network_server *ns;
486
482
        int perr;
487
483
        bdaddr_t src, dst;
488
 
        char *address[18];
 
484
        char address[18];
489
485
        GError *err = NULL;
490
486
 
491
487
        bt_io_get(chan, BT_IO_L2CAP, &err,
499
495
                goto drop;
500
496
        }
501
497
 
502
 
        debug("BNEP: incoming connect from %s", address);
 
498
        DBG("BNEP: incoming connect from %s", address);
503
499
 
504
500
        if (na->setup) {
505
501
                error("Refusing connect from %s: setup in progress", address);
506
502
                goto drop;
507
503
        }
508
504
 
 
505
        ns = find_server(na->servers, BNEP_SVC_NAP);
 
506
        if (!ns)
 
507
                goto drop;
 
508
 
 
509
        if (!ns->record_id)
 
510
                goto drop;
 
511
 
 
512
        if (!ns->bridge)
 
513
                goto drop;
 
514
 
509
515
        na->setup = g_new0(struct network_session, 1);
510
516
        bacpy(&na->setup->dst, &dst);
511
517
        na->setup->io = g_io_channel_ref(chan);
525
531
        g_io_channel_shutdown(chan, TRUE, NULL);
526
532
}
527
533
 
528
 
int server_init(DBusConnection *conn, const char *iface_prefix,
529
 
                gboolean secure)
 
534
int server_init(DBusConnection *conn, gboolean secure)
530
535
{
531
536
        security = secure;
532
537
        connection = dbus_connection_ref(conn);
533
 
        prefix = iface_prefix;
534
 
 
535
 
        if (bridge_create(BNEP_SVC_GN) < 0)
536
 
                error("Can't create GN bridge");
537
538
 
538
539
        return 0;
539
540
}
540
541
 
541
 
void server_exit()
 
542
void server_exit(void)
542
543
{
543
 
        if (bridge_remove(BNEP_SVC_GN) < 0)
544
 
                error("Can't remove GN bridge");
545
 
 
546
544
        dbus_connection_unref(connection);
547
545
        connection = NULL;
548
546
}
549
547
 
550
548
static uint32_t register_server_record(struct network_server *ns)
551
549
{
552
 
        struct network_adapter *na = ns->na;
553
550
        sdp_record_t *record;
554
551
 
555
552
        record = server_record_new(ns->name, ns->id);
558
555
                return 0;
559
556
        }
560
557
 
561
 
        if (add_record_to_server(&na->src, record) < 0) {
 
558
        if (add_record_to_server(&ns->src, record) < 0) {
562
559
                error("Failed to register service record");
563
560
                sdp_record_free(record);
564
561
                return 0;
565
562
        }
566
563
 
567
 
        debug("register_server_record: got record id 0x%x", record->handle);
 
564
        DBG("got record id 0x%x", record->handle);
568
565
 
569
566
        return record->handle;
570
567
}
573
570
static inline DBusMessage *failed(DBusMessage *msg, const char *description)
574
571
{
575
572
        return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
576
 
                                description);
 
573
                                                        "%s", description);
577
574
}
578
575
 
579
576
static inline DBusMessage *invalid_arguments(DBusMessage *msg,
580
577
                                        const char *description)
581
578
{
582
579
        return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments",
583
 
                                description);
584
 
}
585
 
 
586
 
static DBusMessage *enable(DBusConnection *conn,
587
 
                        DBusMessage *msg, void *data)
588
 
{
589
 
        struct network_server *ns = data;
590
 
        DBusMessage *reply;
591
 
 
592
 
        if (ns->enable)
593
 
                return g_dbus_create_error(msg, ERROR_INTERFACE
594
 
                                                ".AlreadyExist",
595
 
                                                "Server already enabled");
596
 
 
597
 
        reply = dbus_message_new_method_return(msg);
598
 
        if (!reply)
599
 
                return NULL;
600
 
 
601
 
        /* Add the service record */
602
 
        ns->record_id = register_server_record(ns);
603
 
        if (!ns->record_id) {
604
 
                dbus_message_unref(reply);
605
 
                return failed(msg, "Service record registration failed");
606
 
        }
607
 
 
608
 
        ns->enable = TRUE;
609
 
 
610
 
        return reply;
611
 
}
612
 
 
613
 
static DBusMessage *disable(DBusConnection *conn,
614
 
                                DBusMessage *msg, void *data)
615
 
{
616
 
        struct network_server *ns = data;
617
 
        DBusMessage *reply;
618
 
 
619
 
        reply = dbus_message_new_method_return(msg);
620
 
        if (!reply)
621
 
                return NULL;
622
 
 
623
 
        if (!ns->enable)
624
 
                return failed(msg, "Not enabled");
625
 
 
626
 
        /* Remove the service record */
 
580
                                                        "%s", description);
 
581
}
 
582
 
 
583
static void server_disconnect(DBusConnection *conn, void *user_data)
 
584
{
 
585
        struct network_server *ns = user_data;
 
586
 
 
587
        ns->watch_id = 0;
 
588
 
627
589
        if (ns->record_id) {
628
590
                remove_record_from_server(ns->record_id);
629
591
                ns->record_id = 0;
630
592
        }
631
593
 
632
 
        ns->enable = FALSE;
633
 
 
634
 
        g_slist_foreach(ns->sessions, (GFunc) session_free, NULL);
635
 
        g_slist_free(ns->sessions);
636
 
 
637
 
        return reply;
 
594
        g_free(ns->bridge);
 
595
        ns->bridge = NULL;
638
596
}
639
597
 
640
 
static DBusMessage *set_name(DBusConnection *conn, DBusMessage *msg,
641
 
                                const char *name, void *data)
 
598
static DBusMessage *register_server(DBusConnection *conn,
 
599
                                DBusMessage *msg, void *data)
642
600
{
643
601
        struct network_server *ns = data;
644
602
        DBusMessage *reply;
 
603
        const char *uuid, *bridge;
 
604
 
 
605
        if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &uuid,
 
606
                                DBUS_TYPE_STRING, &bridge, DBUS_TYPE_INVALID))
 
607
                return NULL;
 
608
 
 
609
        if (g_strcmp0(uuid, "nap"))
 
610
                return failed(msg, "Invalid UUID");
 
611
 
 
612
        if (ns->record_id)
 
613
                return failed(msg, "Already registered");
645
614
 
646
615
        reply = dbus_message_new_method_return(msg);
647
616
        if (!reply)
648
617
                return NULL;
649
618
 
650
 
        if (!name || (strlen(name) == 0))
651
 
                return invalid_arguments(msg, "Invalid name");
652
 
 
653
 
        if (ns->name)
654
 
                g_free(ns->name);
655
 
        ns->name = g_strdup(name);
656
 
 
657
 
        if (ns->enable && ns->record_id) {
658
 
                uint32_t handle = register_server_record(ns);
659
 
                if (!handle) {
660
 
                        dbus_message_unref(reply);
661
 
                        return failed(msg,
662
 
                                "Service record attribute update failed");
663
 
                }
664
 
 
665
 
                remove_record_from_server(ns->record_id);
666
 
                ns->record_id = handle;
667
 
        }
 
619
        ns->record_id = register_server_record(ns);
 
620
        if (!ns->record_id)
 
621
                return failed(msg, "SDP record registration failed");
 
622
 
 
623
        g_free(ns->bridge);
 
624
        ns->bridge = g_strdup(bridge);
 
625
 
 
626
        ns->watch_id = g_dbus_add_disconnect_watch(conn,
 
627
                                        dbus_message_get_sender(msg),
 
628
                                        server_disconnect, ns, NULL);
668
629
 
669
630
        return reply;
670
631
}
671
632
 
672
 
static DBusMessage *get_properties(DBusConnection *conn,
673
 
                                DBusMessage *msg, void *data)
 
633
static DBusMessage *unregister_server(DBusConnection *conn,
 
634
                                        DBusMessage *msg, void *data)
674
635
{
675
636
        struct network_server *ns = data;
676
637
        DBusMessage *reply;
677
 
        DBusMessageIter iter;
678
 
        DBusMessageIter dict;
679
638
        const char *uuid;
680
639
 
 
640
        if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &uuid,
 
641
                                                        DBUS_TYPE_INVALID))
 
642
                return NULL;
 
643
 
 
644
        if (g_strcmp0(uuid, "nap"))
 
645
                return failed(msg, "Invalid UUID");
 
646
 
681
647
        reply = dbus_message_new_method_return(msg);
682
648
        if (!reply)
683
649
                return NULL;
684
650
 
685
 
        dbus_message_iter_init_append(reply, &iter);
686
 
 
687
 
        dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
688
 
                        DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
689
 
                        DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
690
 
                        DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
691
 
 
692
 
        dict_append_entry(&dict, "Name", DBUS_TYPE_STRING, &ns->name);
693
 
 
694
 
        uuid = bnep_uuid(ns->id);
695
 
        dict_append_entry(&dict, "Uuid", DBUS_TYPE_STRING, &uuid);
696
 
 
697
 
        dict_append_entry(&dict, "Enabled", DBUS_TYPE_BOOLEAN, &ns->enable);
698
 
 
699
 
        dbus_message_iter_close_container(&iter, &dict);
 
651
        g_dbus_remove_watch(conn, ns->watch_id);
 
652
 
 
653
        server_disconnect(conn, ns);
700
654
 
701
655
        return reply;
702
656
}
703
657
 
704
 
static DBusMessage *set_property(DBusConnection *conn,
705
 
                                        DBusMessage *msg, void *data)
706
 
{
707
 
        DBusMessageIter iter;
708
 
        DBusMessageIter sub;
709
 
        const char *property;
710
 
 
711
 
        if (!dbus_message_iter_init(msg, &iter))
712
 
                return invalid_arguments(msg, "Not a dict");
713
 
 
714
 
        if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
715
 
                return invalid_arguments(msg, "Key not a string");
716
 
 
717
 
        dbus_message_iter_get_basic(&iter, &property);
718
 
        dbus_message_iter_next(&iter);
719
 
 
720
 
        if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
721
 
                return invalid_arguments(msg, "Value not a variant");
722
 
        dbus_message_iter_recurse(&iter, &sub);
723
 
 
724
 
        if (g_str_equal("Name", property)) {
725
 
                const char *name;
726
 
 
727
 
                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)
728
 
                        return invalid_arguments(msg, "Value not string");
729
 
                dbus_message_iter_get_basic(&sub, &name);
730
 
 
731
 
                return set_name(conn, msg, name, data);
732
 
        } else if (g_str_equal("Enabled", property)) {
733
 
                gboolean enabled;
734
 
 
735
 
                if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
736
 
                        return invalid_arguments(msg, "Value not boolean");
737
 
                dbus_message_iter_get_basic(&sub, &enabled);
738
 
 
739
 
                return enabled ? enable(conn, msg, data) :
740
 
                                disable(conn, msg, data);
741
 
        }
742
 
 
743
 
        return invalid_arguments(msg, "Property does not exist");
744
 
}
745
 
 
746
658
static void adapter_free(struct network_adapter *na)
747
659
{
748
660
        if (na->io != NULL) {
751
663
        }
752
664
 
753
665
        setup_destroy(na);
754
 
        g_free(na->path);
 
666
        btd_adapter_unref(na->adapter);
755
667
        g_free(na);
756
668
}
757
669
 
764
676
        if (ns->record_id)
765
677
                remove_record_from_server(ns->record_id);
766
678
 
767
 
        if (ns->iface)
768
 
                g_free(ns->iface);
769
 
 
770
 
        if (ns->name)
771
 
                g_free(ns->name);
772
 
 
773
 
        if (ns->range)
774
 
                g_free(ns->range);
 
679
        g_free(ns->iface);
 
680
        g_free(ns->name);
 
681
        g_free(ns->bridge);
775
682
 
776
683
        if (ns->sessions) {
777
684
                g_slist_foreach(ns->sessions, (GFunc) session_free, NULL);
786
693
        struct network_server *ns = data;
787
694
        struct network_adapter *na = ns->na;
788
695
 
789
 
        debug("Unregistered interface %s on path %s",
790
 
                ns->iface, na->path);
 
696
        DBG("Unregistered interface %s on path %s",
 
697
                ns->iface, adapter_get_path(na->adapter));
791
698
 
792
699
        na->servers = g_slist_remove(na->servers, ns);
793
700
        server_free(ns);
800
707
}
801
708
 
802
709
static GDBusMethodTable server_methods[] = {
803
 
        { "SetProperty",        "sv",   "",     set_property },
804
 
        { "GetProperties",      "",     "a{sv}",get_properties },
805
 
        { }
806
 
};
807
 
 
808
 
static GDBusSignalTable server_signals[] = {
809
 
        { "PropertyChanged",            "sv"            },
810
 
        { }
811
 
};
812
 
 
813
 
static struct network_adapter *create_adapter(const char *path, bdaddr_t *src)
 
710
        { "Register",   "ss",   "",     register_server         },
 
711
        { "Unregister", "s",    "",     unregister_server       },
 
712
        { }
 
713
};
 
714
 
 
715
static struct network_adapter *create_adapter(struct btd_adapter *adapter)
814
716
{
815
717
        struct network_adapter *na;
816
718
        GError *err = NULL;
 
719
        bdaddr_t src;
817
720
 
818
721
        na = g_new0(struct network_adapter, 1);
819
 
        na->path = g_strdup(path);
820
 
        bacpy(&na->src, src);
 
722
        na->adapter = btd_adapter_ref(adapter);
 
723
 
 
724
        adapter_get_address(adapter, &src);
821
725
 
822
726
        na->io = bt_io_listen(BT_IO_L2CAP, NULL, confirm_event, na,
823
727
                                NULL, &err,
824
 
                                BT_IO_OPT_SOURCE_BDADDR, src,
 
728
                                BT_IO_OPT_SOURCE_BDADDR, &src,
825
729
                                BT_IO_OPT_PSM, BNEP_PSM,
826
730
                                BT_IO_OPT_OMTU, BNEP_MTU,
827
731
                                BT_IO_OPT_IMTU, BNEP_MTU,
838
742
        return na;
839
743
}
840
744
 
841
 
int server_register(const char *path, bdaddr_t *src, uint16_t id)
 
745
int server_register(struct btd_adapter *adapter)
842
746
{
843
747
        struct network_adapter *na;
844
748
        struct network_server *ns;
 
749
        const char *path;
845
750
 
846
 
        na = find_adapter(adapters, path);
 
751
        na = find_adapter(adapters, adapter);
847
752
        if (!na) {
848
 
                na = create_adapter(path, src);
 
753
                na = create_adapter(adapter);
849
754
                if (!na)
850
755
                        return -EINVAL;
851
756
                adapters = g_slist_append(adapters, na);
852
757
        }
853
758
 
854
 
        ns = find_server(na->servers, id);
 
759
        ns = find_server(na->servers, BNEP_SVC_NAP);
855
760
        if (ns)
856
761
                return 0;
857
762
 
858
763
        ns = g_new0(struct network_server, 1);
859
764
 
860
 
        switch (id) {
861
 
        case BNEP_SVC_PANU:
862
 
                ns->iface = g_strdup(NETWORK_PEER_INTERFACE);
863
 
                ns->name = g_strdup("BlueZ PANU service");
864
 
                break;
865
 
        case BNEP_SVC_GN:
866
 
                ns->iface = g_strdup(NETWORK_HUB_INTERFACE);
867
 
                ns->name = g_strdup("BlueZ GN service");
868
 
                break;
869
 
        case BNEP_SVC_NAP:
870
 
                ns->iface = g_strdup(NETWORK_ROUTER_INTERFACE);
871
 
                ns->name = g_strdup("BlueZ NAP service");
872
 
                break;
873
 
        }
 
765
        ns->iface = g_strdup(NETWORK_SERVER_INTERFACE);
 
766
        ns->name = g_strdup("Network service");
 
767
 
 
768
        path = adapter_get_path(adapter);
874
769
 
875
770
        if (!g_dbus_register_interface(connection, path, ns->iface,
876
 
                                        server_methods, server_signals, NULL,
 
771
                                        server_methods, NULL, NULL,
877
772
                                        ns, path_unregister)) {
878
773
                error("D-Bus failed to register %s interface",
879
774
                                ns->iface);
881
776
                return -1;
882
777
        }
883
778
 
884
 
        ns->id = id;
 
779
        adapter_get_address(adapter, &ns->src);
 
780
        ns->id = BNEP_SVC_NAP;
885
781
        ns->na = na;
886
 
        ns->record_id = register_server_record(ns);
887
 
        ns->enable = TRUE;
 
782
        ns->record_id = 0;
888
783
        na->servers = g_slist_append(na->servers, ns);
889
784
 
890
 
        debug("Registered interface %s on path %s", ns->iface, path);
 
785
        DBG("Registered interface %s on path %s", ns->iface, path);
891
786
 
892
787
        return 0;
893
788
}
894
789
 
895
 
int server_unregister(const char *path, uint16_t id)
 
790
int server_unregister(struct btd_adapter *adapter)
896
791
{
897
792
        struct network_adapter *na;
898
793
        struct network_server *ns;
 
794
        uint16_t id = BNEP_SVC_NAP;
899
795
 
900
 
        na = find_adapter(adapters, path);
 
796
        na = find_adapter(adapters, adapter);
901
797
        if (!na)
902
798
                return -EINVAL;
903
799
 
905
801
        if (!ns)
906
802
                return -EINVAL;
907
803
 
908
 
        g_dbus_unregister_interface(connection, path, ns->iface);
 
804
        g_dbus_unregister_interface(connection, adapter_get_path(adapter),
 
805
                                        ns->iface);
909
806
 
910
807
        return 0;
911
808
}