Add NAP network signal
[platform/upstream/bluez.git] / profiles / network / server.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
6  *
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21  *
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28 #include <stdio.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include <errno.h>
32
33 #include <bluetooth/bluetooth.h>
34 #include <bluetooth/bnep.h>
35 #include <bluetooth/sdp.h>
36 #include <bluetooth/sdp_lib.h>
37 #include <netinet/in.h>
38
39 #include <glib.h>
40 #include <gdbus/gdbus.h>
41
42 #include "btio/btio.h"
43 #include "lib/uuid.h"
44 #include "src/dbus-common.h"
45 #include "src/adapter.h"
46 #include "src/log.h"
47 #include "src/error.h"
48 #include "src/sdpd.h"
49
50 #include "bnep.h"
51 #include "server.h"
52
53 #define NETWORK_SERVER_INTERFACE "org.bluez.NetworkServer1"
54 #define BNEP_INTERFACE "bnep%d"
55 #define SETUP_TIMEOUT           1
56
57 /* Pending Authorization */
58 struct network_session {
59         bdaddr_t        dst;            /* Remote Bluetooth Address */
60         char            dev[16];        /* Interface name */
61         GIOChannel      *io;            /* Pending connect channel */
62         guint           watch;          /* BNEP socket watch */
63 };
64
65 struct network_adapter {
66         struct btd_adapter *adapter;    /* Adapter pointer */
67         GIOChannel      *io;            /* Bnep socket */
68         struct network_session *setup;  /* Setup in progress */
69         GSList          *servers;       /* Server register to adapter */
70 };
71
72 /* Main server structure */
73 struct network_server {
74         bdaddr_t        src;            /* Bluetooth Local Address */
75         char            *name;          /* Server service name */
76         char            *bridge;        /* Bridge name */
77         uint32_t        record_id;      /* Service record id */
78         uint16_t        id;             /* Service class identifier */
79         GSList          *sessions;      /* Active connections */
80         struct network_adapter *na;     /* Adapter reference */
81         guint           watch_id;       /* Client service watch */
82 };
83
84 static GSList *adapters = NULL;
85 static gboolean security = TRUE;
86
87 static struct network_adapter *find_adapter(GSList *list,
88                                         struct btd_adapter *adapter)
89 {
90         for (; list; list = list->next) {
91                 struct network_adapter *na = list->data;
92
93                 if (na->adapter == adapter)
94                         return na;
95         }
96
97         return NULL;
98 }
99
100 static struct network_server *find_server(GSList *list, uint16_t id)
101 {
102         for (; list; list = list->next) {
103                 struct network_server *ns = list->data;
104
105                 if (ns->id == id)
106                         return ns;
107         }
108
109         return NULL;
110 }
111
112 static struct network_server *find_server_by_uuid(GSList *list,
113                                                         const char *uuid)
114 {
115         for (; list; list = list->next) {
116                 struct network_server *ns = list->data;
117
118                 if (strcasecmp(uuid, bnep_uuid(ns->id)) == 0)
119                         return ns;
120
121                 if (strcasecmp(uuid, bnep_name(ns->id)) == 0)
122                         return ns;
123         }
124
125         return NULL;
126 }
127
128 static sdp_record_t *server_record_new(const char *name, uint16_t id)
129 {
130         sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto;
131         uuid_t root_uuid, pan, l2cap, bnep;
132         sdp_profile_desc_t profile[1];
133         sdp_list_t *proto[2];
134         sdp_data_t *v, *p;
135         uint16_t psm = BNEP_PSM, version = 0x0100;
136         uint16_t security_desc = (security ? 0x0001 : 0x0000);
137         uint16_t net_access_type = 0xfffe;
138         uint32_t max_net_access_rate = 0;
139         const char *desc = "Network service";
140         sdp_record_t *record;
141
142         record = sdp_record_alloc();
143         if (!record)
144                 return NULL;
145
146         record->attrlist = NULL;
147         record->pattern = NULL;
148
149         switch (id) {
150         case BNEP_SVC_NAP:
151                 sdp_uuid16_create(&pan, NAP_SVCLASS_ID);
152                 svclass = sdp_list_append(NULL, &pan);
153                 sdp_set_service_classes(record, svclass);
154
155                 sdp_uuid16_create(&profile[0].uuid, NAP_PROFILE_ID);
156                 profile[0].version = 0x0100;
157                 pfseq = sdp_list_append(NULL, &profile[0]);
158                 sdp_set_profile_descs(record, pfseq);
159
160                 sdp_set_info_attr(record, name, NULL, desc);
161
162                 sdp_attr_add_new(record, SDP_ATTR_NET_ACCESS_TYPE,
163                                         SDP_UINT16, &net_access_type);
164                 sdp_attr_add_new(record, SDP_ATTR_MAX_NET_ACCESSRATE,
165                                         SDP_UINT32, &max_net_access_rate);
166                 break;
167         case BNEP_SVC_GN:
168                 sdp_uuid16_create(&pan, GN_SVCLASS_ID);
169                 svclass = sdp_list_append(NULL, &pan);
170                 sdp_set_service_classes(record, svclass);
171
172                 sdp_uuid16_create(&profile[0].uuid, GN_PROFILE_ID);
173                 profile[0].version = 0x0100;
174                 pfseq = sdp_list_append(NULL, &profile[0]);
175                 sdp_set_profile_descs(record, pfseq);
176
177                 sdp_set_info_attr(record, name, NULL, desc);
178                 break;
179         case BNEP_SVC_PANU:
180                 sdp_uuid16_create(&pan, PANU_SVCLASS_ID);
181                 svclass = sdp_list_append(NULL, &pan);
182                 sdp_set_service_classes(record, svclass);
183
184                 sdp_uuid16_create(&profile[0].uuid, PANU_PROFILE_ID);
185                 profile[0].version = 0x0100;
186                 pfseq = sdp_list_append(NULL, &profile[0]);
187                 sdp_set_profile_descs(record, pfseq);
188
189                 sdp_set_info_attr(record, name, NULL, desc);
190                 break;
191         default:
192                 sdp_record_free(record);
193                 return NULL;
194         }
195
196         sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
197         root = sdp_list_append(NULL, &root_uuid);
198         sdp_set_browse_groups(record, root);
199
200         sdp_uuid16_create(&l2cap, L2CAP_UUID);
201         proto[0] = sdp_list_append(NULL, &l2cap);
202         p = sdp_data_alloc(SDP_UINT16, &psm);
203         proto[0] = sdp_list_append(proto[0], p);
204         apseq    = sdp_list_append(NULL, proto[0]);
205
206         sdp_uuid16_create(&bnep, BNEP_UUID);
207         proto[1] = sdp_list_append(NULL, &bnep);
208         v = sdp_data_alloc(SDP_UINT16, &version);
209         proto[1] = sdp_list_append(proto[1], v);
210
211         /* Supported protocols */
212         {
213                 uint16_t ptype[] = {
214                         0x0800,  /* IPv4 */
215                         0x0806,  /* ARP */
216                 };
217                 sdp_data_t *head, *pseq;
218                 int p;
219
220                 for (p = 0, head = NULL; p < 2; p++) {
221                         sdp_data_t *data = sdp_data_alloc(SDP_UINT16, &ptype[p]);
222                         if (head)
223                                 sdp_seq_append(head, data);
224                         else
225                                 head = data;
226                 }
227                 pseq = sdp_data_alloc(SDP_SEQ16, head);
228                 proto[1] = sdp_list_append(proto[1], pseq);
229         }
230
231         apseq = sdp_list_append(apseq, proto[1]);
232
233         aproto = sdp_list_append(NULL, apseq);
234         sdp_set_access_protos(record, aproto);
235
236         sdp_add_lang_attr(record);
237
238         sdp_attr_add_new(record, SDP_ATTR_SECURITY_DESC,
239                                 SDP_UINT16, &security_desc);
240
241         sdp_data_free(p);
242         sdp_data_free(v);
243         sdp_list_free(apseq, NULL);
244         sdp_list_free(root, NULL);
245         sdp_list_free(aproto, NULL);
246         sdp_list_free(proto[0], NULL);
247         sdp_list_free(proto[1], NULL);
248         sdp_list_free(svclass, NULL);
249         sdp_list_free(pfseq, NULL);
250
251         return record;
252 }
253
254 static void session_free(void *data)
255 {
256         struct network_session *session = data;
257
258         if (session->watch)
259                 g_source_remove(session->watch);
260
261         if (session->io)
262                 g_io_channel_unref(session->io);
263
264         g_free(session);
265 }
266
267 static void setup_destroy(void *user_data)
268 {
269         struct network_adapter *na = user_data;
270         struct network_session *setup = na->setup;
271
272         if (!setup)
273                 return;
274
275         na->setup = NULL;
276
277         session_free(setup);
278 }
279
280 static gboolean bnep_setup(GIOChannel *chan,
281                         GIOCondition cond, gpointer user_data)
282 {
283         struct network_adapter *na = user_data;
284         struct network_server *ns;
285         uint8_t packet[BNEP_MTU];
286         struct bnep_setup_conn_req *req = (void *) packet;
287         uint16_t src_role, dst_role, rsp = BNEP_CONN_NOT_ALLOWED;
288         int n, sk;
289
290         if (cond & G_IO_NVAL)
291                 return FALSE;
292
293         if (cond & (G_IO_ERR | G_IO_HUP)) {
294                 error("Hangup or error on BNEP socket");
295                 return FALSE;
296         }
297
298         sk = g_io_channel_unix_get_fd(chan);
299
300         /* Reading BNEP_SETUP_CONNECTION_REQUEST_MSG */
301         n = read(sk, packet, sizeof(packet));
302         if (n < 0) {
303                 error("read(): %s(%d)", strerror(errno), errno);
304                 return FALSE;
305         }
306
307         /* Highest known Control command ID
308          * is BNEP_FILTER_MULT_ADDR_RSP = 0x06 */
309         if (req->type == BNEP_CONTROL &&
310                                 req->ctrl > BNEP_FILTER_MULT_ADDR_RSP) {
311                 uint8_t pkt[3];
312
313                 pkt[0] = BNEP_CONTROL;
314                 pkt[1] = BNEP_CMD_NOT_UNDERSTOOD;
315                 pkt[2] = req->ctrl;
316
317                 send(sk, pkt, sizeof(pkt), 0);
318
319                 return FALSE;
320         }
321
322         if (req->type != BNEP_CONTROL || req->ctrl != BNEP_SETUP_CONN_REQ)
323                 return FALSE;
324
325         rsp = bnep_setup_decode(req, &dst_role, &src_role);
326         if (rsp)
327                 goto reply;
328
329         rsp = bnep_setup_chk(dst_role, src_role);
330         if (rsp)
331                 goto reply;
332
333         rsp = BNEP_CONN_NOT_ALLOWED;
334
335         ns = find_server(na->servers, dst_role);
336         if (!ns) {
337                 error("Server unavailable: (0x%x)", dst_role);
338                 goto reply;
339         }
340
341         if (!ns->record_id) {
342                 error("Service record not available");
343                 goto reply;
344         }
345
346         if (!ns->bridge) {
347                 error("Bridge interface not configured");
348                 goto reply;
349         }
350
351         strncpy(na->setup->dev, BNEP_INTERFACE, 16);
352         na->setup->dev[15] = '\0';
353
354         if (bnep_server_add(sk, dst_role, ns->bridge, na->setup->dev,
355                                                         &na->setup->dst) < 0)
356                 goto reply;
357
358         rsp = BNEP_SUCCESS;
359
360 {
361         const gchar *adapter_path = adapter_get_path(na->adapter);
362         const char *pdev = na->setup->dev;
363         char address[24] = {0};
364         char *paddr = address;
365
366         ba2str(&na->setup->dst, paddr);
367
368         na->setup = NULL;
369
370         DBG("send peerconnected signal");
371
372         g_dbus_emit_signal(btd_get_dbus_connection(), adapter_path,
373                         NETWORK_SERVER_INTERFACE, "PeerConnected",
374                         DBUS_TYPE_STRING, &pdev,
375                         DBUS_TYPE_STRING, &paddr,
376                         DBUS_TYPE_INVALID);
377 }
378
379 reply:
380         bnep_send_ctrl_rsp(sk, BNEP_CONTROL, BNEP_SETUP_CONN_RSP, rsp);
381
382         return FALSE;
383 }
384
385 static void connect_event(GIOChannel *chan, GError *err, gpointer user_data)
386 {
387         struct network_adapter *na = user_data;
388
389         if (err) {
390                 error("%s", err->message);
391                 setup_destroy(na);
392                 return;
393         }
394
395         g_io_channel_set_close_on_unref(chan, TRUE);
396
397         na->setup->watch = g_io_add_watch_full(chan, G_PRIORITY_DEFAULT,
398                                 G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
399                                 bnep_setup, na, setup_destroy);
400 }
401
402 static void auth_cb(DBusError *derr, void *user_data)
403 {
404         struct network_adapter *na = user_data;
405         GError *err = NULL;
406
407         if (derr) {
408                 error("Access denied: %s", derr->message);
409                 goto reject;
410         }
411
412         if (!bt_io_accept(na->setup->io, connect_event, na, NULL,
413                                                         &err)) {
414                 error("bt_io_accept: %s", err->message);
415                 g_error_free(err);
416                 goto reject;
417         }
418
419         return;
420
421 reject:
422         g_io_channel_shutdown(na->setup->io, TRUE, NULL);
423         setup_destroy(na);
424 }
425
426 static void confirm_event(GIOChannel *chan, gpointer user_data)
427 {
428         struct network_adapter *na = user_data;
429         struct network_server *ns;
430         bdaddr_t src, dst;
431         char address[18];
432         GError *err = NULL;
433         guint ret;
434
435         bt_io_get(chan, &err,
436                         BT_IO_OPT_SOURCE_BDADDR, &src,
437                         BT_IO_OPT_DEST_BDADDR, &dst,
438                         BT_IO_OPT_DEST, address,
439                         BT_IO_OPT_INVALID);
440         if (err) {
441                 error("%s", err->message);
442                 g_error_free(err);
443                 goto drop;
444         }
445
446         DBG("BNEP: incoming connect from %s", address);
447
448         if (na->setup) {
449                 error("Refusing connect from %s: setup in progress", address);
450                 goto drop;
451         }
452
453         ns = find_server(na->servers, BNEP_SVC_NAP);
454         if (!ns)
455                 goto drop;
456
457         if (!ns->record_id)
458                 goto drop;
459
460         if (!ns->bridge)
461                 goto drop;
462
463         na->setup = g_new0(struct network_session, 1);
464         bacpy(&na->setup->dst, &dst);
465         na->setup->io = g_io_channel_ref(chan);
466
467         ret = btd_request_authorization(&src, &dst, BNEP_SVC_UUID,
468                                         auth_cb, na);
469         if (ret == 0) {
470                 error("Refusing connect from %s", address);
471                 setup_destroy(na);
472                 goto drop;
473         }
474
475         return;
476
477 drop:
478         g_io_channel_shutdown(chan, TRUE, NULL);
479 }
480
481 int server_init(gboolean secure)
482 {
483         security = secure;
484
485         return 0;
486 }
487
488 static uint32_t register_server_record(struct network_server *ns)
489 {
490         sdp_record_t *record;
491
492         record = server_record_new(ns->name, ns->id);
493         if (!record) {
494                 error("Unable to allocate new service record");
495                 return 0;
496         }
497
498         if (adapter_service_add(ns->na->adapter, record) < 0) {
499                 error("Failed to register service record");
500                 sdp_record_free(record);
501                 return 0;
502         }
503
504         DBG("got record id 0x%x", record->handle);
505
506         return record->handle;
507 }
508
509 static void server_remove_sessions(struct network_server *ns)
510 {
511         GSList *list;
512
513         for (list = ns->sessions; list; list = list->next) {
514                 struct network_session *session = list->data;
515
516                 if (*session->dev == '\0')
517                         continue;
518
519                 bnep_server_delete(ns->bridge, session->dev, &session->dst);
520
521                 DBG("send peerdisconnected signal");
522
523                 g_dbus_emit_signal(btd_get_dbus_connection(),
524                         adapter_get_path(ns->na->adapter),
525                         NETWORK_SERVER_INTERFACE, "PeerDisconnected",
526                         DBUS_TYPE_STRING, &session->dev,
527                         DBUS_TYPE_STRING, &session->dst,
528                         DBUS_TYPE_INVALID);
529         }
530
531         g_slist_free_full(ns->sessions, session_free);
532
533         ns->sessions = NULL;
534 }
535
536 static void server_disconnect(DBusConnection *conn, void *user_data)
537 {
538         struct network_server *ns = user_data;
539
540         server_remove_sessions(ns);
541
542         ns->watch_id = 0;
543
544         if (ns->record_id) {
545                 adapter_service_remove(ns->na->adapter, ns->record_id);
546                 ns->record_id = 0;
547         }
548
549         g_free(ns->bridge);
550         ns->bridge = NULL;
551 }
552
553 static DBusMessage *register_server(DBusConnection *conn,
554                                 DBusMessage *msg, void *data)
555 {
556         struct network_adapter *na = data;
557         struct network_server *ns;
558         DBusMessage *reply;
559         const char *uuid, *bridge;
560
561         if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &uuid,
562                                 DBUS_TYPE_STRING, &bridge, DBUS_TYPE_INVALID))
563                 return btd_error_invalid_args(msg);
564
565         ns = find_server_by_uuid(na->servers, uuid);
566         if (ns == NULL)
567                 return btd_error_failed(msg, "Invalid UUID");
568
569         if (ns->record_id)
570                 return btd_error_already_exists(msg);
571
572         reply = dbus_message_new_method_return(msg);
573         if (!reply)
574                 return NULL;
575
576         ns->record_id = register_server_record(ns);
577         if (!ns->record_id)
578                 return btd_error_failed(msg, "SDP record registration failed");
579
580         g_free(ns->bridge);
581         ns->bridge = g_strdup(bridge);
582
583         ns->watch_id = g_dbus_add_disconnect_watch(conn,
584                                         dbus_message_get_sender(msg),
585                                         server_disconnect, ns, NULL);
586
587         return reply;
588 }
589
590 static DBusMessage *unregister_server(DBusConnection *conn,
591                                         DBusMessage *msg, void *data)
592 {
593         struct network_adapter *na = data;
594         struct network_server *ns;
595         DBusMessage *reply;
596         const char *uuid;
597
598         if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &uuid,
599                                                         DBUS_TYPE_INVALID))
600                 return btd_error_invalid_args(msg);
601
602         ns = find_server_by_uuid(na->servers, uuid);
603         if (!ns)
604                 return btd_error_failed(msg, "Invalid UUID");
605
606         reply = dbus_message_new_method_return(msg);
607         if (!reply)
608                 return NULL;
609
610         g_dbus_remove_watch(conn, ns->watch_id);
611
612         server_disconnect(conn, ns);
613
614         return reply;
615 }
616
617 static void adapter_free(struct network_adapter *na)
618 {
619         if (na->io != NULL) {
620                 g_io_channel_shutdown(na->io, TRUE, NULL);
621                 g_io_channel_unref(na->io);
622         }
623
624         setup_destroy(na);
625         btd_adapter_unref(na->adapter);
626         g_free(na);
627 }
628
629 static void server_free(void *data)
630 {
631         struct network_server *ns = data;
632
633         if (!ns)
634                 return;
635
636         server_remove_sessions(ns);
637
638         if (ns->record_id)
639                 adapter_service_remove(ns->na->adapter, ns->record_id);
640
641         g_dbus_remove_watch(btd_get_dbus_connection(), ns->watch_id);
642         g_free(ns->name);
643         g_free(ns->bridge);
644
645         g_free(ns);
646 }
647
648 static void path_unregister(void *data)
649 {
650         struct network_adapter *na = data;
651
652         DBG("Unregistered interface %s on path %s",
653                 NETWORK_SERVER_INTERFACE, adapter_get_path(na->adapter));
654
655         g_slist_free_full(na->servers, server_free);
656
657         adapters = g_slist_remove(adapters, na);
658         adapter_free(na);
659 }
660
661 static GDBusSignalTable server_signals[] = {
662         { GDBUS_SIGNAL("PeerConnected",
663                         GDBUS_ARGS({ "device", "s" }, { "address", "s" })) },
664         { GDBUS_SIGNAL("PeerDisconnected",
665                         GDBUS_ARGS({ "device", "s" }, { "address", "s" })) },
666         { }
667 };
668
669 static const GDBusMethodTable server_methods[] = {
670         { GDBUS_METHOD("Register",
671                         GDBUS_ARGS({ "uuid", "s" }, { "bridge", "s" }), NULL,
672                         register_server) },
673         { GDBUS_METHOD("Unregister",
674                         GDBUS_ARGS({ "uuid", "s" }), NULL,
675                         unregister_server) },
676         { }
677 };
678
679 static struct network_adapter *create_adapter(struct btd_adapter *adapter)
680 {
681         struct network_adapter *na;
682         GError *err = NULL;
683
684         na = g_new0(struct network_adapter, 1);
685         na->adapter = btd_adapter_ref(adapter);
686
687         na->io = bt_io_listen(NULL, confirm_event, na,
688                                 NULL, &err,
689                                 BT_IO_OPT_SOURCE_BDADDR,
690                                 btd_adapter_get_address(adapter),
691                                 BT_IO_OPT_PSM, BNEP_PSM,
692                                 BT_IO_OPT_OMTU, BNEP_MTU,
693                                 BT_IO_OPT_IMTU, BNEP_MTU,
694                                 BT_IO_OPT_SEC_LEVEL,
695                                 security ? BT_IO_SEC_MEDIUM : BT_IO_SEC_LOW,
696                                 BT_IO_OPT_INVALID);
697         if (!na->io) {
698                 error("%s", err->message);
699                 g_error_free(err);
700                 adapter_free(na);
701                 return NULL;
702         }
703
704         return na;
705 }
706
707 int server_register(struct btd_adapter *adapter, uint16_t id)
708 {
709         struct network_adapter *na;
710         struct network_server *ns;
711         const char *path;
712
713         na = find_adapter(adapters, adapter);
714         if (!na) {
715                 na = create_adapter(adapter);
716                 if (!na)
717                         return -EINVAL;
718                 adapters = g_slist_append(adapters, na);
719         }
720
721         ns = find_server(na->servers, id);
722         if (ns)
723                 return 0;
724
725         ns = g_new0(struct network_server, 1);
726
727         ns->name = g_strdup("Network service");
728
729         path = adapter_get_path(adapter);
730
731         if (g_slist_length(na->servers) > 0)
732                 goto done;
733
734         if (!g_dbus_register_interface(btd_get_dbus_connection(),
735                                         path, NETWORK_SERVER_INTERFACE,
736                                         server_methods, server_signals,
737                                         NULL,
738                                         na, path_unregister)) {
739                 error("D-Bus failed to register %s interface",
740                                         NETWORK_SERVER_INTERFACE);
741                 server_free(ns);
742                 return -1;
743         }
744
745         DBG("Registered interface %s on path %s", NETWORK_SERVER_INTERFACE,
746                                                                         path);
747
748 done:
749         bacpy(&ns->src, btd_adapter_get_address(adapter));
750         ns->id = id;
751         ns->na = na;
752         ns->record_id = 0;
753         na->servers = g_slist_append(na->servers, ns);
754
755         return 0;
756 }
757
758 int server_unregister(struct btd_adapter *adapter, uint16_t id)
759 {
760         struct network_adapter *na;
761         struct network_server *ns;
762
763         na = find_adapter(adapters, adapter);
764         if (!na)
765                 return -EINVAL;
766
767         ns = find_server(na->servers, id);
768         if (!ns)
769                 return -EINVAL;
770
771         na->servers = g_slist_remove(na->servers, ns);
772         server_free(ns);
773
774         if (g_slist_length(na->servers) > 0)
775                 return 0;
776
777         g_dbus_unregister_interface(btd_get_dbus_connection(),
778                                                 adapter_get_path(adapter),
779                                                 NETWORK_SERVER_INTERFACE);
780
781         return 0;
782 }