summaryrefslogtreecommitdiffstats
path: root/network
diff options
context:
space:
mode:
Diffstat (limited to 'network')
-rw-r--r--network/manager.c106
-rw-r--r--network/server.c499
-rw-r--r--network/server.h1
3 files changed, 266 insertions, 340 deletions
diff --git a/network/manager.c b/network/manager.c
index c0af5d34..371820cc 100644
--- a/network/manager.c
+++ b/network/manager.c
@@ -57,29 +57,11 @@
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;
diff --git a/network/server.c b/network/server.c
index 1f57a174..f4fabed9 100644
--- a/network/server.c
+++ b/network/server.c
@@ -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;
-}
diff --git a/network/server.h b/network/server.h
index 6fb06b58..74ec86df 100644
--- a/network/server.h
+++ b/network/server.h
@@ -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);