diff options
author | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2007-04-02 18:23:50 +0000 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2007-04-02 18:23:50 +0000 |
commit | 0f09acbace55a146315d240d45132faf62ad45cf (patch) | |
tree | 19f5133e1e3e26c8a1a5c5d08895c1975310d6d7 | |
parent | e8eda4d4fddd56a8ed38358ef3e0a9cf1bb2dcb5 (diff) |
Add storage code.
-rw-r--r-- | network/manager.c | 97 | ||||
-rw-r--r-- | network/server.c | 80 | ||||
-rw-r--r-- | network/server.h | 4 |
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); |