OSDN Git Service

Make network plugin to register adapter drivers.
authorLuiz Augusto von Dentz <luiz.dentz@indt.org.br>
Tue, 12 Aug 2008 21:53:29 +0000 (18:53 -0300)
committerLuiz Augusto von Dentz <luiz.dentz@indt.org.br>
Tue, 12 Aug 2008 21:53:29 +0000 (18:53 -0300)
network/manager.c
network/server.c
network/server.h

index c0af5d3..371820c 100644 (file)
 
 static struct network_conf *conf = NULL;/* Network service configuration */
 
-static DBusConnection *connection = NULL;
-
-static void register_server(uint16_t id)
-{
-       char path[MAX_PATH_LENGTH];
-       bdaddr_t src;
-       int dev_id;
-
-       if (!conf->server_enabled)
-               return;
-
-       snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH "/%s", bnep_name(id));
+static struct btd_adapter_driver network_panu_server_driver;
+static struct btd_adapter_driver network_gn_server_driver;
+static struct btd_adapter_driver network_nap_server_driver;
 
-       bacpy(&src, BDADDR_ANY);
-       dev_id = hci_get_route(&src);
-       if (dev_id < 0 || hci_devba(dev_id, &src))
-               return;
-
-       if (server_register(path, &src, id) < 0)
-               return;
-
-       server_store(path);
-}
+static DBusConnection *connection = NULL;
 
 static int network_probe(struct btd_device_driver *driver,
                        struct btd_device *device, GSList *records)
@@ -113,6 +95,62 @@ static void network_remove(struct btd_device_driver *driver,
        connection_unregister(path, id);
 }
 
+static int network_server_probe(struct adapter *adapter, uint16_t id)
+{
+       const gchar *path = adapter_get_path(adapter);
+       const char *source;
+       bdaddr_t src;
+
+       DBG("path %s", path);
+
+       if (!conf->server_enabled)
+               return 0;
+
+       source = adapter_get_address(adapter);
+       str2ba(source, &src);
+
+       return server_register(path, &src, id);
+}
+
+static void network_server_remove(struct adapter *adapter, uint16_t id)
+{
+       const gchar *path = adapter_get_path(adapter);
+
+       DBG("path %s", path);
+
+       server_unregister(path, id);
+}
+
+static int network_panu_server_probe(struct adapter *adapter)
+{
+       return network_server_probe(adapter, BNEP_SVC_PANU);
+}
+
+static int network_gn_server_probe(struct adapter *adapter)
+{
+       return network_server_probe(adapter, BNEP_SVC_GN);
+}
+
+static int network_nap_server_probe(struct adapter *adapter)
+{
+       return network_server_probe(adapter, BNEP_SVC_NAP);
+}
+
+static void network_panu_server_remove(struct adapter *adapter)
+{
+       network_server_remove(adapter, BNEP_SVC_PANU);
+}
+
+static void network_gn_server_remove(struct adapter *adapter)
+{
+       network_server_remove(adapter, BNEP_SVC_GN);
+}
+
+static void network_nap_server_remove(struct adapter *adapter)
+{
+       network_server_remove(adapter, BNEP_SVC_NAP);
+}
+
 static struct btd_device_driver network_panu_driver = {
        .name   = "network-panu",
        .uuids  = BTD_UUIDS(PANU_UUID),
@@ -134,6 +172,24 @@ static struct btd_device_driver network_nap_driver = {
        .remove = network_remove,
 };
 
+static struct btd_adapter_driver network_panu_server_driver = {
+       .name   = "network-panu-server",
+       .probe  = network_panu_server_probe,
+       .remove = network_panu_server_remove,
+};
+
+static struct btd_adapter_driver network_gn_server_driver = {
+       .name   = "network-gn-server",
+       .probe  = network_gn_server_probe,
+       .remove = network_gn_server_remove,
+};
+
+static struct btd_adapter_driver network_nap_server_driver = {
+       .name   = "network-nap-server",
+       .probe  = network_nap_server_probe,
+       .remove = network_nap_server_remove,
+};
+
 int network_manager_init(DBusConnection *conn, struct network_conf *service_conf)
 {
        conf = service_conf;
@@ -159,9 +215,9 @@ int network_manager_init(DBusConnection *conn, struct network_conf *service_conf
 
        /* Register PANU, GN and NAP servers if they don't exist */
        /* FIXME: server should be registered as adapter driver */
-       register_server(BNEP_SVC_PANU);
-       register_server(BNEP_SVC_GN);
-       register_server(BNEP_SVC_NAP);
+       btd_register_adapter_driver(&network_panu_server_driver);
+       btd_register_adapter_driver(&network_gn_server_driver);
+       btd_register_adapter_driver(&network_nap_server_driver);
 
        if (connection_init(conn, conf->iface_prefix) < 0)
                return -1;
index 1f57a17..f4fabed 100644 (file)
@@ -55,7 +55,9 @@
 #include "sdpd.h"
 #include "glib-helper.h"
 
-#define NETWORK_SERVER_INTERFACE "org.bluez.network.Server"
+#define NETWORK_PEER_INTERFACE "org.bluez.network.Peer"
+#define NETWORK_HUB_INTERFACE "org.bluez.network.Hub"
+#define NETWORK_ROUTER_INTERFACE "org.bluez.network.Router"
 #define SETUP_TIMEOUT          1000
 #define MAX_SETUP_ATTEMPTS     3
 
@@ -77,32 +79,58 @@ struct timeout {
        guint   watch;          /* BNEP socket watch */
 };
 
+struct network_adapter {
+       bdaddr_t        src;            /* Bluetooth Local Address */
+       char            *path;          /* D-Bus path */
+       GIOChannel      *io;            /* Bnep socket */
+       struct timeout  *to;            /* Socket timeout */
+       GSList          *servers;       /* Server register to adapter */
+};
+
 /* Main server structure */
 struct network_server {
-       bdaddr_t        src;            /* Bluetooth Local Address */
-       char            *iface;         /* Routing interface */
+       char            *iface;         /* DBus interface */
        char            *name;          /* Server service name */
        char            *range;         /* IP Address range */
-       char            *path;          /* D-Bus path */
        gboolean        enable;         /* Enable flag */
        uint32_t        record_id;      /* Service record id */
        uint16_t        id;             /* Service class identifier */
        GSList          *clients;       /* Active connections */
+       struct network_adapter *na;     /* Adapter reference */
 };
 
-static GIOChannel *bnep_io = NULL;
 static DBusConnection *connection = NULL;
 static struct setup_session *setup = NULL;
-static GSList *servers = NULL;
+static GSList *adapters = NULL;
 static const char *prefix = NULL;
 static gboolean security = TRUE;
 
-gint find_server(gconstpointer a, gconstpointer b)
+static struct network_adapter *find_adapter(GSList *list, const char *path)
 {
-       const struct network_server *ns = a;
-       const char *path = b;
+       GSList *l;
 
-       return strcmp(ns->path, path);
+       for (l = list; l; l = l->next) {
+               struct network_adapter *na = l->data;
+
+               if (g_str_equal(na->path, path))
+                       return na;
+       }
+
+       return NULL;
+}
+
+static struct network_server *find_server(GSList *list, uint16_t id)
+{
+       GSList *l;
+
+       for (l = list; l; l = l->next) {
+               struct network_server *ns = l->data;
+
+               if (ns->id == id)
+                       return ns;
+       }
+
+       return NULL;
 }
 
 static struct setup_session *setup_session_new(gchar *address,
@@ -127,39 +155,6 @@ static void setup_session_free(struct setup_session *setup)
        g_free(setup);
 }
 
-static struct network_server *server_find(bdaddr_t *src, uint16_t role)
-{
-       struct network_server *ns;
-       GSList *l;
-
-       for (l = servers; l; l = l->next) {
-               ns = l->data;
-               if (bacmp(&ns->src, src) != 0)
-                       continue;
-               if (ns->id == role)
-                       return ns;
-       }
-
-       return NULL;
-}
-
-static int store_property(bdaddr_t *src, uint16_t id,
-                       const char *key, const char *value)
-{
-       char filename[PATH_MAX + 1];
-       char addr[18];
-
-       ba2str(src, addr);
-       if (id == BNEP_SVC_NAP)
-               create_name(filename, PATH_MAX, STORAGEDIR, addr, "nap");
-       else if (id == BNEP_SVC_GN)
-               create_name(filename, PATH_MAX, STORAGEDIR, addr, "gn");
-       else if (id == BNEP_SVC_PANU)
-               create_name(filename, PATH_MAX, STORAGEDIR, addr, "panu");
-
-       return textfile_put(filename, key, value);
-}
-
 static void add_lang_attr(sdp_record_t *r)
 {
        sdp_lang_attr_t base_lang;
@@ -351,6 +346,7 @@ static int server_connadd(struct network_server *ns, int nsk,
 static void req_auth_cb(DBusError *derr, void *user_data)
 {
        struct network_server *ns = user_data;
+       struct network_adapter *na = ns->na;
        uint16_t val;
 
        if (!setup) {
@@ -363,7 +359,7 @@ static void req_auth_cb(DBusError *derr, void *user_data)
                if (dbus_error_has_name(derr, DBUS_ERROR_NO_REPLY)) {
                        bdaddr_t dst;
                        str2ba(setup->address, &dst);
-                       service_cancel_auth(&ns->src, &dst);
+                       service_cancel_auth(&na->src, &dst);
                }
                val = BNEP_CONN_NOT_ALLOWED;
                goto done;
@@ -383,14 +379,15 @@ done:
 
 static int authorize_connection(struct network_server *ns, const char *address)
 {
+       struct network_adapter *na;
        const char *uuid;
        bdaddr_t dst;
        int ret_val;
 
-       uuid =  bnep_uuid(ns->id);
+       uuid = bnep_uuid(ns->id);
        str2ba(address, &dst);
 
-       ret_val = service_req_auth(&ns->src, &dst, uuid, req_auth_cb, ns);
+       ret_val = service_req_auth(&na->src, &dst, uuid, req_auth_cb, ns);
 
        return ret_val;
 }
@@ -444,7 +441,8 @@ static uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req,
 static gboolean bnep_setup(GIOChannel *chan,
                        GIOCondition cond, gpointer user_data)
 {
-       struct timeout *to = user_data;
+       struct network_adapter *na = user_data;
+       struct timeout *to = na->to;
        struct network_server *ns;
        uint8_t packet[BNEP_MTU];
        struct bnep_setup_conn_req *req = (void *) packet;
@@ -489,7 +487,7 @@ static gboolean bnep_setup(GIOChannel *chan,
        }
 
        ba2str(&sa.l2_bdaddr, address);
-       ns = server_find(&sa.l2_bdaddr, dst_role);
+       ns = find_server(na->servers, dst_role);
        if (!ns || ns->enable == FALSE) {
                error("Server unavailable: %s (0x%x)", address, dst_role);
                rsp = BNEP_CONN_NOT_ALLOWED;
@@ -553,7 +551,8 @@ static gboolean timeout_cb(void *user_data)
 static void connect_event(GIOChannel *chan, int err, const bdaddr_t *src,
                                const bdaddr_t *dst, gpointer user_data)
 {
-       struct timeout *to;
+       struct network_adapter *na;
+       struct timeout *to = na->to;
 
        if (err < 0) {
                error("accept(): %s(%d)", strerror(errno), errno);
@@ -571,7 +570,7 @@ static void connect_event(GIOChannel *chan, int err, const bdaddr_t *src,
        to->id = g_timeout_add(SETUP_TIMEOUT, timeout_cb, to);
        to->watch = g_io_add_watch_full(chan, G_PRIORITY_DEFAULT,
                                G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
-                               bnep_setup, to, setup_destroy);
+                               bnep_setup, na, setup_destroy);
        g_io_channel_unref(chan);
 
        return;
@@ -580,20 +579,10 @@ static void connect_event(GIOChannel *chan, int err, const bdaddr_t *src,
 int server_init(DBusConnection *conn, const char *iface_prefix,
                gboolean secure)
 {
-       int lm;
-
-       lm = secure ? L2CAP_LM_SECURE : 0;
-
        security = secure;
        connection = dbus_connection_ref(conn);
        prefix = iface_prefix;
 
-       bnep_io = bt_l2cap_listen(BDADDR_ANY, BNEP_PSM, BNEP_MTU, lm,
-                       connect_event, NULL);
-       if (!bnep_io)
-               return -1;
-       g_io_channel_set_close_on_unref(bnep_io, FALSE);
-
        if (bridge_create(BNEP_SVC_GN) < 0)
                error("Can't create GN bridge");
 
@@ -602,12 +591,6 @@ int server_init(DBusConnection *conn, const char *iface_prefix,
 
 void server_exit()
 {
-       if (bnep_io != NULL) {
-               g_io_channel_close(bnep_io);
-               g_io_channel_unref(bnep_io);
-               bnep_io = NULL;
-       }
-
        if (bridge_remove(BNEP_SVC_GN) < 0)
                error("Can't remove GN bridge");
 
@@ -617,6 +600,7 @@ void server_exit()
 
 static uint32_t register_server_record(struct network_server *ns)
 {
+       struct network_adapter *na = ns->na;
        sdp_record_t *record;
 
        record = server_record_new(ns->name, ns->id);
@@ -625,7 +609,7 @@ static uint32_t register_server_record(struct network_server *ns)
                return 0;
        }
 
-       if (add_record_to_server(&ns->src, record) < 0) {
+       if (add_record_to_server(&na->src, record) < 0) {
                error("Failed to register service record");
                sdp_record_free(record);
                return 0;
@@ -636,24 +620,6 @@ static uint32_t register_server_record(struct network_server *ns)
        return record->handle;
 }
 
-static DBusMessage *get_uuid(DBusConnection *conn,
-                               DBusMessage *msg, void *data)
-{
-       struct network_server *ns = data;
-       DBusMessage *reply;
-       const char *uuid;
-
-       reply = dbus_message_new_method_return(msg);
-       if (!reply)
-               return NULL;
-
-       uuid = bnep_uuid(ns->id);
-       dbus_message_append_args(reply,
-                       DBUS_TYPE_STRING, &uuid,
-                       DBUS_TYPE_INVALID);
-
-       return reply;
-}
 
 static inline DBusMessage *failed(DBusMessage *msg, const char *description)
 {
@@ -679,17 +645,6 @@ static DBusMessage *enable(DBusConnection *conn,
                                                ".AlreadyExist",
                                                "Server already enabled");
 
-       if (bacmp(&ns->src, BDADDR_ANY) == 0) {
-               int dev_id;
-
-               dev_id = hci_get_route(&ns->src);
-               if ((dev_id < 0) || (hci_devba(dev_id, &ns->src) < 0))
-                       return failed(msg, "Adapter not available");
-
-               /* Store the server info */
-               server_store(ns->path);
-       }
-
        reply = dbus_message_new_method_return(msg);
        if (!reply)
                return NULL;
@@ -703,11 +658,6 @@ static DBusMessage *enable(DBusConnection *conn,
 
        ns->enable = TRUE;
 
-       store_property(&ns->src, ns->id, "enabled", "1");
-
-       g_dbus_emit_signal(conn, ns->path, NETWORK_SERVER_INTERFACE,
-                                       "Enabled", DBUS_TYPE_INVALID);
-
        return reply;
 }
 
@@ -743,16 +693,11 @@ static DBusMessage *disable(DBusConnection *conn,
 
        g_slist_foreach(ns->clients, (GFunc) kill_connection, NULL);
 
-       store_property(&ns->src, ns->id, "enabled", "0");
-
-       g_dbus_emit_signal(conn, ns->path, NETWORK_SERVER_INTERFACE,
-                                       "Disabled", DBUS_TYPE_INVALID);
-
        return reply;
 }
 
-static DBusMessage *is_enabled(DBusConnection *conn, DBusMessage *msg,
-                               void *data)
+static DBusMessage *set_name(DBusConnection *conn, DBusMessage *msg,
+                               const char *name, void *data)
 {
        struct network_server *ns = data;
        DBusMessage *reply;
@@ -761,28 +706,6 @@ static DBusMessage *is_enabled(DBusConnection *conn, DBusMessage *msg,
        if (!reply)
                return NULL;
 
-       dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &ns->enable,
-                                       DBUS_TYPE_INVALID);
-
-       return reply;
-}
-
-static DBusMessage *set_name(DBusConnection *conn,
-                               DBusMessage *msg, void *data)
-{
-       struct network_server *ns = data;
-       DBusMessage *reply;
-       const char *name;
-
-       reply = dbus_message_new_method_return(msg);
-       if (!reply)
-               return NULL;
-
-       if (!dbus_message_get_args(msg, NULL,
-                               DBUS_TYPE_STRING, &name,
-                               DBUS_TYPE_INVALID))
-               return NULL;
-
        if (!name || (strlen(name) == 0))
                return invalid_arguments(msg, "Invalid name");
 
@@ -802,59 +725,10 @@ static DBusMessage *set_name(DBusConnection *conn,
                ns->record_id = handle;
        }
 
-       store_property(&ns->src, ns->id, "name", ns->name);
-
        return reply;
 }
 
-static DBusMessage *get_name(DBusConnection *conn,
-                               DBusMessage *msg, void *data)
-{
-       struct network_server *ns = data;
-       char name[] = "";
-       const char *pname = (ns->name ? ns->name : name);
-       DBusMessage *reply;
-
-       reply = dbus_message_new_method_return(msg);
-       if (!reply)
-               return NULL;
-
-       dbus_message_append_args(reply,
-                       DBUS_TYPE_STRING, &pname,
-                       DBUS_TYPE_INVALID);
-
-       return reply;
-}
-
-static DBusMessage *set_address_range(DBusConnection *conn,
-                                       DBusMessage *msg, void *data)
-{
-       return NULL;
-}
-
-static DBusMessage *set_routing(DBusConnection *conn, DBusMessage *msg,
-                                       void *data)
-{
-       struct network_server *ns = data;
-       const char *iface;
-
-       if (!dbus_message_get_args(msg, NULL,
-                               DBUS_TYPE_STRING, &iface,
-                               DBUS_TYPE_INVALID))
-               return NULL;
-
-       /* FIXME: Check if the interface is valid/UP */
-       if (!iface || (strlen(iface) == 0))
-               return invalid_arguments(msg, "Invalid interface");
-
-       if (ns->iface)
-               g_free(ns->iface);
-       ns->iface = g_strdup(iface);
-
-       return dbus_message_new_method_return(msg);
-}
-
-static DBusMessage *get_info(DBusConnection *conn,
+static DBusMessage *get_properties(DBusConnection *conn,
                                DBusMessage *msg, void *data)
 {
        struct network_server *ns = data;
@@ -874,18 +748,74 @@ static DBusMessage *get_info(DBusConnection *conn,
                        DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
                        DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
 
-       dbus_message_iter_append_dict_entry(&dict, "name",
+       dbus_message_iter_append_dict_entry(&dict, "Name",
                        DBUS_TYPE_STRING, &ns->name);
 
        uuid = bnep_uuid(ns->id);
-       dbus_message_iter_append_dict_entry(&dict, "uuid",
+       dbus_message_iter_append_dict_entry(&dict, "Uuid",
                        DBUS_TYPE_STRING, &uuid);
 
+       dbus_message_iter_append_dict_entry(&dict, "Enabled",
+                       DBUS_TYPE_BOOLEAN, &ns->enable);
+
        dbus_message_iter_close_container(&iter, &dict);
 
        return reply;
 }
 
+static DBusMessage *set_property(DBusConnection *conn,
+                                       DBusMessage *msg, void *data)
+{
+       DBusMessageIter iter;
+       DBusMessageIter sub;
+       const char *property;
+
+       if (!dbus_message_iter_init(msg, &iter))
+               return invalid_arguments(msg, "Not a dict");
+
+       if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+               return invalid_arguments(msg, "Key not a string");
+
+       dbus_message_iter_get_basic(&iter, &property);
+       dbus_message_iter_next(&iter);
+
+       if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
+               return invalid_arguments(msg, "Value not a variant");
+       dbus_message_iter_recurse(&iter, &sub);
+
+       if (g_str_equal("Name", property)) {
+               const char *name;
+
+               if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)
+                       return invalid_arguments(msg, "Value not string");
+               dbus_message_iter_get_basic(&sub, &name);
+
+               return set_name(conn, msg, name, data);
+       } else if (g_str_equal("Enabled", property)) {
+               gboolean enabled;
+
+               if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
+                       return invalid_arguments(msg, "Value not boolean");
+               dbus_message_iter_get_basic(&sub, &enabled);
+
+               return enabled ? enable(conn, msg, data) :
+                               disable(conn, msg, data);
+       }
+
+       return invalid_arguments(msg, "Property does not exist");
+}
+
+static void adapter_free(struct network_adapter *na)
+{
+       if (na->io != NULL) {
+               g_io_channel_close(na->io);
+               g_io_channel_unref(na->io);
+       }
+
+       g_free(na->path);
+       g_free(na);
+}
+
 static void server_free(struct network_server *ns)
 {
        if (!ns)
@@ -904,9 +834,6 @@ static void server_free(struct network_server *ns)
        if (ns->range)
                g_free(ns->range);
 
-       if (ns->path)
-               g_free(ns->path);
-
        if (ns->clients) {
                g_slist_foreach(ns->clients, (GFunc) g_free, NULL);
                g_slist_free(ns->clients);
@@ -915,183 +842,125 @@ static void server_free(struct network_server *ns)
        g_free(ns);
 }
 
-static void server_unregister(void *data)
+static void path_unregister(void *data)
 {
        struct network_server *ns = data;
+       struct network_adapter *na = ns->na;
 
-       info("Unregistered server path:%s", ns->path);
-
-       servers = g_slist_remove(servers, ns);
+       na->servers = g_slist_remove(na->servers, ns);
        server_free(ns);
+
+       info("Unregistered interface %s on path %s",
+               ns->iface, na->path);
+
+       if (na->servers)
+               return;
+
+       adapter_free(na);
 }
 
 static GDBusMethodTable server_methods[] = {
-       { "GetUUID",            "",     "s",    get_uuid },
-       { "Enable",             "",     "",     enable },
-       { "Disable",            "",     "",     disable },
-       { "IsEnabled",          "",     "b",    is_enabled },
-       { "SetName",            "s",    "",     set_name },
-       { "GetName",            "",     "s",    get_name },
-       { "SetAddressRange",    "ss",   "",     set_address_range },
-       { "SetRouting",         "s",    "",     set_routing },
-       { "GetInfo",            "",     "a{sv}",get_info },
+       { "SetProperty",        "sv",   "",     set_property },
+       { "GetProperties",      "",     "a{sv}",get_properties },
        { }
 };
 
 static GDBusSignalTable server_signals[] = {
-       { "Enabled",    ""      },
-       { "Disabled",   ""      },
+       { "PropertyChanged",            "sv"            },
        { }
 };
 
-int server_register(const char *path, bdaddr_t *src, uint16_t id)
+static struct network_adapter *create_adapter(const char *path, bdaddr_t *src)
 {
-       struct network_server *ns;
+       struct network_adapter *na;
+       int lm;
 
-       if (!path)
-               return -EINVAL;
+       lm = security ? L2CAP_LM_SECURE : 0;
 
-       ns = g_new0(struct network_server, 1);
+       na = g_new0(struct network_adapter, 1);
+       na->path = g_strdup(path);
+       bacpy(&na->src, src);
 
-       if (!g_dbus_register_interface(connection, path,
-                                       NETWORK_SERVER_INTERFACE,
-                                       server_methods, server_signals, NULL,
-                                       ns, server_unregister)) {
-               error("D-Bus failed to register %s interface",
-                               NETWORK_SERVER_INTERFACE);
-               server_free(ns);
-               return -1;
+       na->io = bt_l2cap_listen(src, BNEP_PSM, BNEP_MTU, lm,
+                       connect_event, na);
+       if (!na->io) {
+               adapter_free(na);
+               return NULL;
        }
 
-       /* Setting a default name */
-       if (id == BNEP_SVC_NAP)
-               ns->name = g_strdup("BlueZ NAP service");
-       else if (id == BNEP_SVC_GN)
-               ns->name = g_strdup("BlueZ GN service");
-       else
-               ns->name = g_strdup("BlueZ PANU service");
+       g_io_channel_set_close_on_unref(na->io, FALSE);
 
-       ns->path = g_strdup(path);
-       ns->id = id;
-       bacpy(&ns->src, src);
-
-       servers = g_slist_append(servers, ns);
-
-       info("Registered server path:%s", path);
-
-       return 0;
+       return na;
 }
 
-int server_register_from_file(const char *path, const bdaddr_t *src,
-               uint16_t id, const char *filename)
+int server_register(const char *path, bdaddr_t *src, uint16_t id)
 {
+       struct network_adapter *na;
        struct network_server *ns;
-       char *str;
 
-       if (!path)
-               return -EINVAL;
-
-       ns = g_new0(struct network_server, 1);
-
-       bacpy(&ns->src, src);
-       ns->path = g_strdup(path);
-       ns->id = id;
-       ns->name = textfile_get(filename, "name");
-       if (!ns->name) {
-               /* Name is mandatory */
-               server_free(ns);
-               return -1;
+       na = find_adapter(adapters, path);
+       if (!na) {
+               na = create_adapter(path, src);
+               if (!na)
+                       return -EINVAL;
+               adapters = g_slist_append(adapters, na);
        }
 
-       ns->range = textfile_get(filename, "address_range");
-       ns->iface = textfile_get(filename, "routing");
+       ns = find_server(na->servers, id);
+       if (ns)
+               return 0;
 
-       str = textfile_get(filename, "enabled");
-       if (str) {
-               if (strcmp("1", str) == 0) {
-                       ns->record_id = register_server_record(ns);
-                       ns->enable = TRUE;
-               }
-               g_free(str);
+       ns = g_new0(struct network_server, 1);
+
+       switch (id) {
+       case BNEP_SVC_PANU:
+               ns->iface = g_strdup(NETWORK_PEER_INTERFACE);
+               ns->name = g_strdup("BlueZ PANU service");
+               break;
+       case BNEP_SVC_GN:
+               ns->iface = g_strdup(NETWORK_HUB_INTERFACE);
+               ns->name = g_strdup("BlueZ GN service");
+               break;
+       case BNEP_SVC_NAP:
+               ns->iface = g_strdup(NETWORK_ROUTER_INTERFACE);
+               ns->name = g_strdup("BlueZ NAP service");
+               break;
        }
 
-       if (!g_dbus_register_interface(connection, path,
-                                       NETWORK_SERVER_INTERFACE,
+       if (!g_dbus_register_interface(connection, path, ns->iface,
                                        server_methods, server_signals, NULL,
-                                       ns, server_unregister)) {
+                                       ns, path_unregister)) {
                error("D-Bus failed to register %s interface",
-                               NETWORK_SERVER_INTERFACE);
+                               ns->iface);
                server_free(ns);
                return -1;
        }
 
-       servers = g_slist_append(servers, ns);
+       ns->id = id;
+       ns->na = na;
+       ns->record_id = register_server_record(ns);
+       ns->enable = TRUE;
+       na->servers = g_slist_append(na->servers, ns);
 
-       info("Registered server path:%s", path);
+       info("Registered interface %s on path %s", ns->iface, path);
 
        return 0;
 }
 
-int server_store(const char *path)
+int server_unregister(const char *path, uint16_t id)
 {
+       struct network_adapter *na;
        struct network_server *ns;
-       char filename[PATH_MAX + 1];
-       char addr[18];
-       GSList *l;
-
-       l = g_slist_find_custom(servers, path, find_server);
-       if (!l) {
-               error("Unable to salve %s on storage", path);
-               return -ENOENT;
-       }
 
-       ns = l->data;
-       ba2str(&ns->src, addr);
-       if (ns->id == BNEP_SVC_NAP)
-               create_name(filename, PATH_MAX, STORAGEDIR, addr, "nap");
-       else if (ns->id == BNEP_SVC_GN)
-               create_name(filename, PATH_MAX, STORAGEDIR, addr, "gn");
-       else
-               create_name(filename, PATH_MAX, STORAGEDIR, addr, "panu");
-
-       create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-       textfile_put(filename, "name", ns->name);
-
-       if (ns->iface)
-               textfile_put(filename, "routing", ns->iface);
+       na = find_adapter(adapters, path);
+       if (!na)
+               return -EINVAL;
 
-       if (ns->range)
-               textfile_put(filename, "range", ns->range);
+       ns = find_server(na->servers, id);
+       if (!ns)
+               return -EINVAL;
 
-       textfile_put(filename, "enabled", ns->enable ? "1": "0");
+       g_dbus_unregister_interface(connection, path, ns->iface);
 
        return 0;
 }
-
-int server_find_data(const char *path, const char *pattern)
-{
-       struct network_server *ns;
-       const char *uuid;
-       GSList *l;
-
-       l = g_slist_find_custom(servers, path, find_server);
-       if (!l)
-               return -1;
-
-       ns = l->data;
-       if (ns->name && strcasecmp(pattern, ns->name) == 0)
-               return 0;
-
-       if (ns->iface && strcasecmp(pattern, ns->iface) == 0)
-               return 0;
-
-       uuid = bnep_name(ns->id);
-       if (uuid && strcasecmp(pattern, uuid) == 0)
-               return 0;
-
-       if (bnep_service_id(pattern) == ns->id)
-               return 0;
-
-       return -1;
-}
index 6fb06b5..74ec86d 100644 (file)
@@ -25,6 +25,7 @@ int server_init(DBusConnection *conn, const char *iface_prefix,
                gboolean secure);
 void server_exit();
 int server_register(const char *path, bdaddr_t *src, uint16_t id);
+int server_unregister(const char *path, uint16_t id);
 int server_register_from_file(const char *path, const bdaddr_t *src,
                uint16_t id, const char *filename);