summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--network/manager.c97
-rw-r--r--network/server.c80
-rw-r--r--network/server.h4
3 files changed, 164 insertions, 17 deletions
diff --git a/network/manager.c b/network/manager.c
index 33cbd36f..ace1f602 100644
--- a/network/manager.c
+++ b/network/manager.c
@@ -77,7 +77,7 @@ static void pending_reply_free(struct pending_reply *pr)
}
static DBusHandlerResult create_path(DBusConnection *conn,
- DBusMessage *msg, char *path,
+ DBusMessage *msg, const char *path,
const char *sname)
{
DBusMessage *reply, *signal;
@@ -101,7 +101,6 @@ static DBusHandlerResult create_path(DBusConnection *conn,
dbus_message_append_args(reply, DBUS_TYPE_STRING, &path,
DBUS_TYPE_INVALID);
- g_free(path);
return send_message_and_unref(conn, reply);
}
@@ -221,7 +220,7 @@ static void pan_record_reply(DBusPendingCall *call, void *data)
pr->mgr->connections = g_slist_append(pr->mgr->connections,
g_strdup(pr->path));
- create_path(pr->conn, pr->msg, g_strdup (pr->path), "ConnectionCreated");
+ create_path(pr->conn, pr->msg, pr->path, "ConnectionCreated");
fail:
sdp_record_free(rec);
dbus_error_free(&derr);
@@ -333,6 +332,64 @@ static int get_handles(struct pending_reply *pr,
return 0;
}
+static void get_address_reply(DBusPendingCall *call, void *data)
+{
+ struct pending_reply *pr = data;
+ DBusMessage *reply = dbus_pending_call_steal_reply(call);
+ DBusError derr;
+ const char *address;
+
+ dbus_error_init(&derr);
+ if (dbus_set_error_from_message(&derr, reply)) {
+ error("GetAddress: %s(%s)", derr.name, derr.message);
+ goto fail;
+ }
+
+ if (!dbus_message_get_args(reply, &derr,
+ DBUS_TYPE_STRING, &address,
+ DBUS_TYPE_INVALID)) {
+ error("%s: %s", derr.name, derr.message);
+ goto fail;
+ }
+
+ if (server_register(pr->conn, address, pr->path, pr->id) < 0) {
+ err_failed(pr->conn, pr->msg, "D-Bus path registration failed");
+ goto fail;
+ }
+
+ pr->mgr->servers = g_slist_append(pr->mgr->servers,
+ g_strdup(pr->path));
+
+ create_path(pr->conn, pr->msg, pr->path, "ServerCreated");
+fail:
+ dbus_error_free(&derr);
+ dbus_message_unref(reply);
+ dbus_pending_call_unref(call);
+ return;
+}
+
+static int get_address(struct pending_reply *pr,
+ DBusPendingCallNotifyFunction cb)
+{
+ DBusMessage *msg;
+ DBusPendingCall *pending;
+
+ msg = dbus_message_new_method_call("org.bluez", pr->adapter_path,
+ "org.bluez.Adapter", "GetAddress");
+ if (!msg)
+ return -1;
+
+ if (dbus_connection_send_with_reply(pr->conn, msg, &pending, -1) == FALSE) {
+ error("Can't send D-Bus message.");
+ return -1;
+ }
+
+ dbus_pending_call_set_notify(pending, cb, pr, NULL);
+ dbus_message_unref(msg);
+
+ return 0;
+}
+
static void default_adapter_reply(DBusPendingCall *call, void *data)
{
struct pending_reply *pr = data;
@@ -357,7 +414,10 @@ static void default_adapter_reply(DBusPendingCall *call, void *data)
pr->adapter_path = g_strdup(adapter);
- if (get_handles(pr, pan_handle_reply) < 0) {
+ if (pr->id == BNEP_SVC_PANU && (get_handles(pr, pan_handle_reply) < 0)) {
+ err_failed(pr->conn, pr->msg, "D-Bus path registration failed");
+ goto fail;
+ } else if (get_address(pr, get_address_reply) < 0) {
err_failed(pr->conn, pr->msg, "D-Bus path registration failed");
goto fail;
}
@@ -404,9 +464,9 @@ static DBusHandlerResult create_server(DBusConnection *conn,
DBusMessage *msg, void *data)
{
struct manager *mgr = data;
+ struct pending_reply *pr;
DBusError derr;
const char *str;
- char *path;
int id;
dbus_error_init(&derr);
@@ -422,21 +482,28 @@ static DBusHandlerResult create_server(DBusConnection *conn,
if ((id != BNEP_SVC_GN) && (id != BNEP_SVC_NAP))
return err_invalid_args(conn, msg, "Not supported");
- path = g_new0(char, 32);
- snprintf(path, 32, NETWORK_PATH "/server/%X", id);
-
- if (g_slist_find_custom(mgr->servers, path, (GCompareFunc) strcmp))
- return err_already_exists(conn, msg, "Server Already exists");
+ pr = g_new(struct pending_reply, 1);
+ pr->conn = conn;
+ pr->msg = dbus_message_ref(msg);
+ pr->mgr = mgr;
+ pr->addr = NULL;
+ pr->id = id;
+ pr->path = g_new0(char, 32);
+ snprintf(pr->path, 32, NETWORK_PATH "/server/%s", bnep_name(id));
- if (server_register(conn, path, id) == -1) {
- err_failed(conn, msg, "D-Bus path registration failed");
- g_free(path);
+ if (g_slist_find_custom(mgr->servers, pr->path,
+ (GCompareFunc) strcmp)) {
+ err_already_exists(conn, msg, "Server Already exists");
+ pending_reply_free(pr);
return DBUS_HANDLER_RESULT_HANDLED;
}
- mgr->servers = g_slist_append(mgr->servers, g_strdup(path));
+ if (get_default_adapter(pr, default_adapter_reply) < 0) {
+ err_failed(conn, msg, "D-Bus path registration failed");
+ pending_reply_free(pr);
+ }
- return create_path(conn, msg, path, "ServerCreated");
+ return DBUS_HANDLER_RESULT_HANDLED;
}
static DBusHandlerResult remove_server(DBusConnection *conn,
diff --git a/network/server.c b/network/server.c
index 67319107..0c0932ae 100644
--- a/network/server.c
+++ b/network/server.c
@@ -30,6 +30,8 @@
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/stat.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/bnep.h>
@@ -50,6 +52,7 @@
#include "bridge.h"
#include "common.h"
#include "server.h"
+#include "textfile.h"
/* Pending Authorization */
struct pending_auth {
@@ -60,6 +63,7 @@ struct pending_auth {
/* Main server structure */
struct network_server {
+ bdaddr_t src; /* Bluetooth Local Address */
char *iface; /* Routing interface */
char *name; /* Server service name */
char *path; /* D-Bus path */
@@ -73,6 +77,48 @@ struct network_server {
static char netdev[16] = "bnep%d";
+static inline int create_filename(char *buf, size_t size,
+ bdaddr_t *bdaddr, const char *name)
+{
+ char addr[18];
+
+ ba2str(bdaddr, addr);
+
+ return create_name(buf, size, STORAGEDIR, addr, name);
+}
+
+static int del_stored_server_info(bdaddr_t *src, uint16_t uuid)
+{
+ char filename[PATH_MAX + 1];
+ const char *str;
+ int err;
+
+ create_filename(filename, PATH_MAX, src, "network");
+
+ str = bnep_uuid(uuid);
+
+ err = textfile_del(filename, str);
+
+ return err;
+}
+
+static int store_server_info(bdaddr_t *src, uint16_t uuid, gboolean enable)
+{
+ char filename[PATH_MAX + 1];
+ const char *str;
+ int err;
+
+ create_filename(filename, PATH_MAX, src, "network");
+
+ str = bnep_uuid(uuid);
+
+ create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
+
+ err = textfile_put(filename, str, enable ? "1" : "0");
+
+ return err;
+}
+
static void pending_auth_free(struct pending_auth *pauth)
{
if (!pauth)
@@ -684,6 +730,9 @@ static DBusHandlerResult enable(DBusConnection *conn,
DBusMessage *reply;
int err;
+ if (ns->io)
+ return err_already_exists(conn, msg, "Server already enabled");
+
reply = dbus_message_new_method_return(msg);
if (!reply)
return DBUS_HANDLER_RESULT_NEED_MEMORY;
@@ -699,6 +748,8 @@ static DBusHandlerResult enable(DBusConnection *conn,
if (err < 0)
return err_failed(conn, msg, strerror(-err));
+ store_server_info(&ns->src, ns->id, TRUE);
+
return send_message_and_unref(conn, reply);
}
@@ -724,6 +775,8 @@ static DBusHandlerResult disable(DBusConnection *conn,
g_io_channel_unref(ns->io);
ns->io = NULL;
+ store_server_info(&ns->src, ns->id, FALSE);
+
return send_message_and_unref(conn, reply);
}
@@ -943,6 +996,8 @@ static void server_free(struct network_server *ns)
g_io_channel_unref(ns->io);
}
+ del_stored_server_info(&ns->src, ns->id);
+
g_free(ns);
}
@@ -961,7 +1016,8 @@ static const DBusObjectPathVTable server_table = {
.unregister_function = server_unregister,
};
-int server_register(DBusConnection *conn, const char *path, uint16_t id)
+int server_register(DBusConnection *conn, const char *addr, const char *path,
+ uint16_t id)
{
struct network_server *ns;
@@ -989,11 +1045,33 @@ int server_register(DBusConnection *conn, const char *path, uint16_t id)
ns->path = g_strdup(path);
ns->id = id;
ns->conn = dbus_connection_ref(conn);
+ str2ba(addr, &ns->src);
info("Registered server path:%s", ns->path);
+ store_server_info(&ns->src, ns->id, FALSE);
+
return 0;
fail:
server_free(ns);
return -1;
}
+
+int read_server_uuid(bdaddr_t *src, uint16_t uuid, gboolean *enable)
+{
+ char filename[PATH_MAX + 1], *buff;
+ const char *str;
+
+ create_filename(filename, PATH_MAX, src, "network");
+
+ str = bnep_uuid(uuid);
+ buff = textfile_get(filename, str);
+ if (!buff)
+ return -ENOENT;
+
+ *enable = (strtol(buff, NULL, 10)) ? TRUE : FALSE;
+
+ g_free(buff);
+
+ return 0;
+}
diff --git a/network/server.h b/network/server.h
index 27b38ba6..7db4ad18 100644
--- a/network/server.h
+++ b/network/server.h
@@ -21,4 +21,6 @@
*
*/
-int server_register(DBusConnection *conn, const char *path, uint16_t id);
+int server_register(DBusConnection *conn, const char *addr, const char *path,
+ uint16_t id);
+int read_server_uuid(bdaddr_t *src, uint16_t uuid, gboolean *enable);