From 3406c27e758f3dfa182f6fdfcc878bc3a53e3c98 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 9 Mar 2007 15:33:38 +0000 Subject: Add skeleton for network service --- network/server.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 network/server.c (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c new file mode 100644 index 00000000..b8fe0382 --- /dev/null +++ b/network/server.c @@ -0,0 +1,28 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2004-2007 Marcel Holtmann + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "server.h" -- cgit From 1055292b83db7b5eb211a07d1d05c3450faaef20 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 16 Mar 2007 20:44:42 +0000 Subject: Initial implementation of network server interface. --- network/server.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index b8fe0382..8695aeaa 100644 --- a/network/server.c +++ b/network/server.c @@ -25,4 +25,139 @@ #include #endif +#include + +#include + +#include "logging.h" +#include "dbus.h" +#include "error.h" + +#define NETWORK_SERVER_INTERFACE "org.bluez.network.Server" + #include "server.h" + +struct network_server { + char *path; +}; + +static DBusHandlerResult get_uuid(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult enable(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult disable(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult set_name(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult get_name(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult set_address_range(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult set_routing(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult set_security(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult get_security(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult server_message(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + const char *iface, *member; + + iface = dbus_message_get_interface(msg); + member = dbus_message_get_member(msg); + + if (strcmp(NETWORK_SERVER_INTERFACE, iface)) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + if (strcmp(member, "GetUUID") == 0) + return get_uuid(conn, msg, data); + + if (strcmp(member, "Enable") == 0) + return enable(conn, msg, data); + + if (strcmp(member, "Disable") == 0) + return disable(conn, msg, data); + + if (strcmp(member, "SetName") == 0) + return set_name(conn, msg, data); + + if (strcmp(member, "GetName") == 0) + return get_name(conn, msg, data); + + if (strcmp(member, "SetAddressRange") == 0) + return set_address_range(conn, msg, data); + + if (strcmp(member, "SetRouting") == 0) + return set_routing(conn, msg, data); + + if (strcmp(member, "SetSecurity") == 0) + return set_security(conn, msg, data); + + if (strcmp(member, "GetSecurity") == 0) + return get_security(conn, msg, data); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static void server_free(struct network_server *ns) +{ + if (!ns) + return; + + if (ns->path) + g_free(ns->path); + + g_free(ns); +} + +static void server_unregister(DBusConnection *conn, void *data) +{ + struct network_server *ns = data; + + info("Unregistered server path %s", ns->path); + + server_free(ns); +} + +/* Virtual table to handle server object path hierarchy */ +static const DBusObjectPathVTable server_table = { + .message_function = server_message, + .unregister_function = server_unregister, +}; -- cgit From 0ac929228aa1eb823f37776e2bbb84855417c66e Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 19 Mar 2007 13:57:52 +0000 Subject: Fix build, move errors to error file and add server registration. --- network/server.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 8695aeaa..e88b8090 100644 --- a/network/server.c +++ b/network/server.c @@ -161,3 +161,28 @@ static const DBusObjectPathVTable server_table = { .message_function = server_message, .unregister_function = server_unregister, }; + +int server_register(DBusConnection *conn, const char *path) +{ + struct network_server *ns; + + if (!conn) + return -1; + + ns = g_new0(struct network_server, 1); + + /* register path */ + if (!dbus_connection_register_object_path(conn, path, + &server_table, ns)) { + error("D-Bus failed to register %s path", path); + goto fail; + } + + ns->path = g_strdup(path); + info("Registered server path:%s", path); + + return 0; +fail: + server_free(ns); + return -1; +} -- cgit From c41c67efc320d5f8b15963246cc0c2aa006446d5 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 20 Mar 2007 15:10:58 +0000 Subject: Initial code of CreateServer and RemoveServer methods. --- network/server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index e88b8090..adc6517d 100644 --- a/network/server.c +++ b/network/server.c @@ -179,7 +179,7 @@ int server_register(DBusConnection *conn, const char *path) } ns->path = g_strdup(path); - info("Registered server path:%s", path); + info("Registered server path:%s", ns->path); return 0; fail: -- cgit From 11676370a14d77b9fc04af03143fe56ab58753cd Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 21 Mar 2007 18:04:04 +0000 Subject: Remove duplicate code and some minor fixes. --- network/server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index adc6517d..bce8e3b6 100644 --- a/network/server.c +++ b/network/server.c @@ -151,7 +151,7 @@ static void server_unregister(DBusConnection *conn, void *data) { struct network_server *ns = data; - info("Unregistered server path %s", ns->path); + info("Unregistered server path:%s", ns->path); server_free(ns); } -- cgit From d1e15b83b04cf2cfe3f154678b1d72ebaf783512 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 22 Mar 2007 14:21:01 +0000 Subject: network: Added Server.GetUUID() --- network/server.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index bce8e3b6..3318eecf 100644 --- a/network/server.c +++ b/network/server.c @@ -25,6 +25,8 @@ #include #endif +#include + #include #include @@ -38,13 +40,25 @@ #include "server.h" struct network_server { + char *uuid; char *path; }; -static DBusHandlerResult get_uuid(DBusConnection *conn, DBusMessage *msg, - void *data) +static DBusHandlerResult get_uuid(DBusConnection *conn, + DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct network_server *ns = data; + DBusMessage *reply; + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_message_append_args(reply, + DBUS_TYPE_STRING, &ns->uuid, + DBUS_TYPE_INVALID); + + return send_message_and_unref(conn, reply); } static DBusHandlerResult enable(DBusConnection *conn, DBusMessage *msg, @@ -144,6 +158,9 @@ static void server_free(struct network_server *ns) if (ns->path) g_free(ns->path); + if (ns->uuid) + g_free(ns->uuid); + g_free(ns); } @@ -162,12 +179,15 @@ static const DBusObjectPathVTable server_table = { .unregister_function = server_unregister, }; -int server_register(DBusConnection *conn, const char *path) +int server_register(DBusConnection *conn, const char *path, const char *uuid) { struct network_server *ns; if (!conn) - return -1; + return -EINVAL; + + if (!path || !uuid) + return -EINVAL; ns = g_new0(struct network_server, 1); @@ -179,6 +199,7 @@ int server_register(DBusConnection *conn, const char *path) } ns->path = g_strdup(path); + ns->uuid = g_strdup(uuid); info("Registered server path:%s", ns->path); return 0; -- cgit From 04b559087e7a2a593822ca933e3f7aca3700fa43 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 22 Mar 2007 15:03:34 +0000 Subject: network: Added Server.GetName() --- network/server.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 3318eecf..bf1e45fc 100644 --- a/network/server.c +++ b/network/server.c @@ -40,8 +40,10 @@ #include "server.h" struct network_server { - char *uuid; + + char *name; char *path; + char *uuid; }; static DBusHandlerResult get_uuid(DBusConnection *conn, @@ -79,10 +81,23 @@ static DBusHandlerResult set_name(DBusConnection *conn, DBusMessage *msg, return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -static DBusHandlerResult get_name(DBusConnection *conn, DBusMessage *msg, - void *data) +static DBusHandlerResult get_name(DBusConnection *conn, + DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + 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 DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_message_append_args(reply, + DBUS_TYPE_STRING, &pname, + DBUS_TYPE_INVALID); + + return send_message_and_unref(conn, reply); } static DBusHandlerResult set_address_range(DBusConnection *conn, -- cgit From 9cefcf43f42f48d59804c1832e8e5fc9a5abe26e Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 22 Mar 2007 15:24:51 +0000 Subject: network: Added Server.SetName --- network/server.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index bf1e45fc..98eb83b3 100644 --- a/network/server.c +++ b/network/server.c @@ -75,10 +75,32 @@ static DBusHandlerResult disable(DBusConnection *conn, DBusMessage *msg, return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -static DBusHandlerResult set_name(DBusConnection *conn, DBusMessage *msg, - void *data) +static DBusHandlerResult set_name(DBusConnection *conn, + DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct network_server *ns = data; + DBusMessage *reply; + const char *name; + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_INVALID)) + return err_invalid_args(conn, msg, "Invalid name"); + + if (!name || (strlen(name) == 0)) + return err_invalid_args(conn, msg, "Invalid name"); + + if (ns->name) + g_free(ns->name); + ns->name = g_strdup(name); + + /* FIXME: Update the service record attribute */ + + return send_message_and_unref(conn, reply); } static DBusHandlerResult get_name(DBusConnection *conn, -- cgit From b8773553381ed1d070c7bc2a60c7a8b3f5f96552 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 22 Mar 2007 17:12:40 +0000 Subject: network: Added Server.GetSecurity() --- network/server.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 98eb83b3..6a91de7c 100644 --- a/network/server.c +++ b/network/server.c @@ -41,9 +41,10 @@ struct network_server { - char *name; - char *path; - char *uuid; + char *name; + char *path; + char *uuid; + dbus_bool_t secure; }; static DBusHandlerResult get_uuid(DBusConnection *conn, @@ -143,7 +144,18 @@ static DBusHandlerResult set_security(DBusConnection *conn, DBusMessage *msg, static DBusHandlerResult get_security(DBusConnection *conn, DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct network_server *ns = data; + DBusMessage *reply; + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_message_append_args(reply, + DBUS_TYPE_BOOLEAN, &ns->secure, + DBUS_TYPE_INVALID); + + return send_message_and_unref(conn, reply); } static DBusHandlerResult server_message(DBusConnection *conn, -- cgit From ed83ee24ed636f5f2d213bc825d702cc45c20b8f Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 22 Mar 2007 17:20:19 +0000 Subject: network: Added Server.SetSecurity --- network/server.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 6a91de7c..982c0830 100644 --- a/network/server.c +++ b/network/server.c @@ -135,10 +135,30 @@ static DBusHandlerResult set_routing(DBusConnection *conn, DBusMessage *msg, return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -static DBusHandlerResult set_security(DBusConnection *conn, DBusMessage *msg, - void *data) +static DBusHandlerResult set_security(DBusConnection *conn, + DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct network_server *ns = data; + DBusMessage *reply; + DBusError derr; + dbus_bool_t secure; + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_error_init(&derr); + if (!dbus_message_get_args(msg, &derr, + DBUS_TYPE_BOOLEAN, &secure, + DBUS_TYPE_INVALID)) { + err_invalid_args(conn, msg, derr.message); + dbus_error_free(&derr); + return DBUS_HANDLER_RESULT_HANDLED; + } + + ns->secure = secure; + + return send_message_and_unref(conn, reply); } static DBusHandlerResult get_security(DBusConnection *conn, -- cgit From d1ffb661fd4fb9f81ba406345e4c17dadd766265 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 22 Mar 2007 17:43:32 +0000 Subject: network: added Server.SetRouting --- network/server.c | 40 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 36 insertions(+), 4 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 982c0830..02ad8edf 100644 --- a/network/server.c +++ b/network/server.c @@ -40,10 +40,10 @@ #include "server.h" struct network_server { - + char *iface; /* Routing interface */ char *name; - char *path; - char *uuid; + char *path; + char *uuid; /* UUID 128 */ dbus_bool_t secure; }; @@ -132,7 +132,33 @@ static DBusHandlerResult set_address_range(DBusConnection *conn, static DBusHandlerResult set_routing(DBusConnection *conn, DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct network_server *ns = data; + DBusMessage *reply; + DBusError derr; + const char *iface; + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_error_init(&derr); + if (!dbus_message_get_args(msg, &derr, + DBUS_TYPE_STRING, &iface, + DBUS_TYPE_INVALID)) { + err_invalid_args(conn, msg, derr.message); + dbus_error_free(&derr); + return DBUS_HANDLER_RESULT_HANDLED; + } + + /* FIXME: Check if the interface is valid/UP */ + if (!iface || (strlen(iface) == 0)) + return err_invalid_args(conn, msg, "Invalid interface"); + + if (ns->iface) + g_free(ns->iface); + ns->iface = g_strdup(iface); + + return send_message_and_unref(conn, reply); } static DBusHandlerResult set_security(DBusConnection *conn, @@ -224,6 +250,12 @@ static void server_free(struct network_server *ns) if (!ns) return; + if (ns->iface) + g_free(ns->iface); + + if (ns->name) + g_free(ns->name); + if (ns->path) g_free(ns->path); -- cgit From 0f7f9e9d9fc5493258d2b64b6ae8085c07d177d9 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 22 Mar 2007 17:56:08 +0000 Subject: network: returning a better message content in the D-Bus error for invalid arguments --- network/server.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 02ad8edf..5cfb332e 100644 --- a/network/server.c +++ b/network/server.c @@ -81,16 +81,21 @@ static DBusHandlerResult set_name(DBusConnection *conn, { struct network_server *ns = data; DBusMessage *reply; + DBusError derr; const char *name; reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; - if (!dbus_message_get_args(msg, NULL, + dbus_error_init(&derr); + if (!dbus_message_get_args(msg, &derr, DBUS_TYPE_STRING, &name, - DBUS_TYPE_INVALID)) - return err_invalid_args(conn, msg, "Invalid name"); + DBUS_TYPE_INVALID)) { + err_invalid_args(conn, msg, derr.message); + dbus_error_free(&derr); + return DBUS_HANDLER_RESULT_HANDLED; + } if (!name || (strlen(name) == 0)) return err_invalid_args(conn, msg, "Invalid name"); -- cgit From ef3649fd9e62bd989ff67a125a05c962d5640fd3 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 23 Mar 2007 21:04:08 +0000 Subject: network: using service class identifier instead of the uuid 128 string for server registration --- network/server.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 5cfb332e..80c8df9e 100644 --- a/network/server.c +++ b/network/server.c @@ -37,14 +37,15 @@ #define NETWORK_SERVER_INTERFACE "org.bluez.network.Server" +#include "common.h" #include "server.h" struct network_server { char *iface; /* Routing interface */ char *name; char *path; - char *uuid; /* UUID 128 */ dbus_bool_t secure; + uint16_t id; /* Service class identifier */ }; static DBusHandlerResult get_uuid(DBusConnection *conn, @@ -52,13 +53,15 @@ static DBusHandlerResult get_uuid(DBusConnection *conn, { struct network_server *ns = data; DBusMessage *reply; + const char *uuid; reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; + uuid = bnep_uuid(ns->id); dbus_message_append_args(reply, - DBUS_TYPE_STRING, &ns->uuid, + DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID); return send_message_and_unref(conn, reply); @@ -264,9 +267,6 @@ static void server_free(struct network_server *ns) if (ns->path) g_free(ns->path); - if (ns->uuid) - g_free(ns->uuid); - g_free(ns); } @@ -285,14 +285,14 @@ static const DBusObjectPathVTable server_table = { .unregister_function = server_unregister, }; -int server_register(DBusConnection *conn, const char *path, const char *uuid) +int server_register(DBusConnection *conn, const char *path, uint16_t id) { struct network_server *ns; if (!conn) return -EINVAL; - if (!path || !uuid) + if (!path) return -EINVAL; ns = g_new0(struct network_server, 1); @@ -305,7 +305,7 @@ int server_register(DBusConnection *conn, const char *path, const char *uuid) } ns->path = g_strdup(path); - ns->uuid = g_strdup(uuid); + ns->id = id; info("Registered server path:%s", ns->path); return 0; -- cgit From 0ebeaaa03e9bd402876d7bb8cc7784cbff08a614 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 26 Mar 2007 14:43:52 +0000 Subject: metwork: Added function to call the service record registration --- network/server.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 89 insertions(+), 6 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 80c8df9e..3b5444ff 100644 --- a/network/server.c +++ b/network/server.c @@ -25,9 +25,12 @@ #include #endif +#include #include #include +#include +#include #include @@ -42,12 +45,74 @@ struct network_server { char *iface; /* Routing interface */ - char *name; - char *path; + char *name; /* Server service name */ + char *path; /* D-Bus path */ dbus_bool_t secure; + uint32_t record_id; /* Service record id */ uint16_t id; /* Service class identifier */ }; +static int create_server_record(sdp_buf_t *buf, uint16_t id) +{ + /* FIXME: service name must be configurable */ + + /* FIXME: Create the service record */ + + return -1; +} + +static uint32_t add_server_record(DBusConnection *conn, uint16_t id) +{ + DBusMessage *msg, *reply; + DBusError derr; + dbus_uint32_t rec_id; + sdp_buf_t buf; + + msg = dbus_message_new_method_call("org.bluez", "/org/bluez", + "org.bluez.Database", "AddServiceRecord"); + if (!msg) { + error("Can't allocate new method call"); + return 0; + } + + if (create_server_record(&buf, id) < 0) { + error("Unable to allocate new service record"); + dbus_message_unref(msg); + return 0; + } + + dbus_message_append_args(msg, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, + &buf.data, buf.data_size, DBUS_TYPE_INVALID); + + dbus_error_init(&derr); + reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &derr); + + free(buf.data); + dbus_message_unref(msg); + + if (dbus_error_is_set(&derr) || dbus_set_error_from_message(&derr, reply)) { + error("Adding service record failed: %s", derr.message); + dbus_error_free(&derr); + return 0; + } + + dbus_message_get_args(reply, &derr, DBUS_TYPE_UINT32, &rec_id, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&derr)) { + error("Invalid arguments to AddServiceRecord reply: %s", derr.message); + dbus_message_unref(reply); + dbus_error_free(&derr); + return 0; + } + + dbus_message_unref(reply); + + debug("add_server_record: got record id 0x%x", rec_id); + + return rec_id; +} + static DBusHandlerResult get_uuid(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -67,10 +132,28 @@ static DBusHandlerResult get_uuid(DBusConnection *conn, return send_message_and_unref(conn, reply); } -static DBusHandlerResult enable(DBusConnection *conn, DBusMessage *msg, - void *data) +static DBusHandlerResult enable(DBusConnection *conn, + DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct network_server *ns = data; + DBusMessage *reply; + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + /* Add the service record */ + ns->record_id = add_server_record(conn, ns->id); + if (!ns->record_id) { + error("Unable to register the server(0x%x) service record", ns->id); + return err_failed(conn, msg, "Unable to register the service record"); + } + + /* FIXME: Check security */ + + /* FIXME: Start listen */ + + return send_message_and_unref(conn, reply); } static DBusHandlerResult disable(DBusConnection *conn, DBusMessage *msg, @@ -297,7 +380,7 @@ int server_register(DBusConnection *conn, const char *path, uint16_t id) ns = g_new0(struct network_server, 1); - /* register path */ + /* Register path */ if (!dbus_connection_register_object_path(conn, path, &server_table, ns)) { error("D-Bus failed to register %s path", path); -- cgit From daf9e4f8a6fd95b682d26e3bdd965248de30c148 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 26 Mar 2007 18:59:34 +0000 Subject: network: added function to create the server(NAP/GN) service record --- network/server.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 124 insertions(+), 2 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 3b5444ff..427bff8b 100644 --- a/network/server.c +++ b/network/server.c @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -52,13 +53,134 @@ struct network_server { uint16_t id; /* Service class identifier */ }; +void add_lang_attr(sdp_record_t *r) +{ + sdp_lang_attr_t base_lang; + sdp_list_t *langs = 0; + + /* UTF-8 MIBenum (http://www.iana.org/assignments/character-sets) */ + base_lang.code_ISO639 = (0x65 << 8) | 0x6e; + base_lang.encoding = 106; + base_lang.base_offset = SDP_PRIMARY_LANG_BASE; + langs = sdp_list_append(0, &base_lang); + sdp_set_lang_attr(r, langs); + sdp_list_free(langs, 0); +} + static int create_server_record(sdp_buf_t *buf, uint16_t id) { + sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto; + uuid_t root_uuid, pan, l2cap, bnep; + sdp_profile_desc_t profile[1]; + sdp_list_t *proto[2]; + sdp_data_t *v, *p; + uint16_t psm = BNEP_PSM, version = 0x0100; + uint16_t security_desc = 0; + uint16_t net_access_type = 0xfffe; + uint32_t max_net_access_rate = 0; + const char *name = "BlueZ PAN"; + const char *desc = "BlueZ PAN Service"; + sdp_record_t record; + int ret; + /* FIXME: service name must be configurable */ - /* FIXME: Create the service record */ + memset(&record, 0, sizeof(sdp_record_t)); + + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); + root = sdp_list_append(NULL, &root_uuid); + sdp_set_browse_groups(&record, root); + + sdp_uuid16_create(&l2cap, L2CAP_UUID); + proto[0] = sdp_list_append(NULL, &l2cap); + p = sdp_data_alloc(SDP_UINT16, &psm); + proto[0] = sdp_list_append(proto[0], p); + apseq = sdp_list_append(NULL, proto[0]); + + sdp_uuid16_create(&bnep, BNEP_UUID); + proto[1] = sdp_list_append(NULL, &bnep); + v = sdp_data_alloc(SDP_UINT16, &version); + proto[1] = sdp_list_append(proto[1], v); + + /* Supported protocols */ + { + uint16_t ptype[] = { + 0x0800, /* IPv4 */ + 0x0806, /* ARP */ + }; + sdp_data_t *head, *pseq; + int p; + + for (p = 0, head = NULL; p < 2; p++) { + sdp_data_t *data = sdp_data_alloc(SDP_UINT16, &ptype[p]); + if (head) + sdp_seq_append(head, data); + else + head = data; + } + pseq = sdp_data_alloc(SDP_SEQ16, head); + proto[1] = sdp_list_append(proto[1], pseq); + } - return -1; + apseq = sdp_list_append(apseq, proto[1]); + + aproto = sdp_list_append(NULL, apseq); + sdp_set_access_protos(&record, aproto); + + add_lang_attr(&record); + + /* FIXME: Missing check the security attribute */ + sdp_attr_add_new(&record, SDP_ATTR_SECURITY_DESC, + SDP_UINT16, &security_desc); + + if (id == BNEP_SVC_NAP) { + sdp_uuid16_create(&pan, NAP_SVCLASS_ID); + svclass = sdp_list_append(NULL, &pan); + sdp_set_service_classes(&record, svclass); + + sdp_uuid16_create(&profile[0].uuid, NAP_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(NULL, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_set_info_attr(&record, "Network Access Point", name, desc); + + sdp_attr_add_new(&record, SDP_ATTR_NET_ACCESS_TYPE, + SDP_UINT16, &net_access_type); + sdp_attr_add_new(&record, SDP_ATTR_MAX_NET_ACCESSRATE, + SDP_UINT32, &max_net_access_rate); + } else { + /* BNEP_SVC_GN */ + sdp_uuid16_create(&pan, GN_SVCLASS_ID); + svclass = sdp_list_append(NULL, &pan); + sdp_set_service_classes(&record, svclass); + + sdp_uuid16_create(&profile[0].uuid, GN_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(NULL, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_set_info_attr(&record, "Group Network Service", name, desc); + } + + if (sdp_gen_record_pdu(&record, buf) < 0) + ret = -1; + else + ret = 0; + + sdp_data_free(p); + sdp_data_free(v); + sdp_list_free(apseq, NULL); + sdp_list_free(root, NULL); + sdp_list_free(aproto, NULL); + sdp_list_free(proto[0], NULL); + sdp_list_free(proto[1], NULL); + sdp_list_free(svclass, NULL); + sdp_list_free(pfseq, NULL); + sdp_list_free(record.attrlist, (sdp_free_func_t) sdp_data_free); + sdp_list_free(record.pattern, free); + + return ret; } static uint32_t add_server_record(DBusConnection *conn, uint16_t id) -- cgit From 2b349e5e40d1e96a7968104e51fd10d95a6f390b Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 26 Mar 2007 20:08:34 +0000 Subject: network: added initial code for server L2CAP listening --- network/server.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 427bff8b..1a02bb50 100644 --- a/network/server.c +++ b/network/server.c @@ -25,11 +25,14 @@ #include #endif +#include #include #include +#include #include #include +#include #include #include @@ -51,6 +54,7 @@ struct network_server { dbus_bool_t secure; uint32_t record_id; /* Service record id */ uint16_t id; /* Service class identifier */ + GIOChannel *io; /* GIOChannel when listening */ }; void add_lang_attr(sdp_record_t *r) @@ -183,6 +187,86 @@ static int create_server_record(sdp_buf_t *buf, uint16_t id) return ret; } +static gboolean connect_event(GIOChannel *chan, + GIOCondition cond, gpointer data) +{ + info("FIXME: Connect event"); + return FALSE; +} + +static int l2cap_listen(struct network_server *ns) +{ + struct l2cap_options l2o; + struct sockaddr_l2 l2a; + socklen_t olen; + int sk, lm, err; + + /* Create L2CAP socket and bind it to PSM BNEP */ + sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); + if (sk < 0) { + err = errno; + error("Cannot create L2CAP socket. %s(%d)", + strerror(err), err); + return -err; + } + + memset(&l2a, 0, sizeof(l2a)); + l2a.l2_family = AF_BLUETOOTH; + bacpy(&l2a.l2_bdaddr, BDADDR_ANY); + l2a.l2_psm = htobs(BNEP_PSM); + + if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a))) { + err = errno; + error("Bind failed. %s(%d)", strerror(err), err); + goto fail; + } + + /* Setup L2CAP options according to BNEP spec */ + memset(&l2o, 0, sizeof(l2o)); + olen = sizeof(l2o); + if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen) < 0) { + err = errno; + error("Failed to get L2CAP options. %s(%d)", + strerror(err), err); + goto fail; + } + + l2o.imtu = l2o.omtu = BNEP_MTU; + if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)) < 0) { + err = errno; + error("Failed to set L2CAP options. %s(%d)", + strerror(err), err); + goto fail; + } + + /* Set link mode */ + lm = (ns->secure ? L2CAP_LM_SECURE : 0); + if (lm && setsockopt(sk, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0) { + err = errno; + error("Failed to set link mode. %s(%d)", + strerror(err), err); + goto fail; + } + + if (listen(sk, 10) < 0) { + err = errno; + error("Listen failed. %s(%d)", strerror(err), err); + goto fail; + } + + ns->io = g_io_channel_unix_new(sk); + g_io_channel_set_close_on_unref(ns->io, TRUE); + + g_io_add_watch(ns->io, G_IO_IN, connect_event, NULL); + + return 0; +fail: + + close(sk); + errno = err; + return -err; +} + static uint32_t add_server_record(DBusConnection *conn, uint16_t id) { DBusMessage *msg, *reply; @@ -259,6 +343,7 @@ static DBusHandlerResult enable(DBusConnection *conn, { struct network_server *ns = data; DBusMessage *reply; + int err; reply = dbus_message_new_method_return(msg); if (!reply) @@ -273,7 +358,9 @@ static DBusHandlerResult enable(DBusConnection *conn, /* FIXME: Check security */ - /* FIXME: Start listen */ + err = l2cap_listen(ns); + if (err < 0) + return err_failed(conn, msg, strerror(-err)); return send_message_and_unref(conn, reply); } -- cgit From 556bafad380353f745f8c0a54b9753967e75a1c2 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Tue, 27 Mar 2007 21:34:13 +0000 Subject: network: Added authorization for incomming connections --- network/server.c | 277 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 265 insertions(+), 12 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 1a02bb50..e33e7133 100644 --- a/network/server.c +++ b/network/server.c @@ -25,6 +25,7 @@ #include #endif +#include #include #include #include @@ -36,6 +37,8 @@ #include #include +#include + #include #include "logging.h" @@ -47,17 +50,40 @@ #include "common.h" #include "server.h" +/* Pending Authorization */ +struct pending_auth { + char *addr; /* Bluetooth Address */ + GIOChannel *io; /* BNEP connection setup io channel */ +}; + +/* Main server structure */ struct network_server { - char *iface; /* Routing interface */ - char *name; /* Server service name */ - char *path; /* D-Bus path */ - dbus_bool_t secure; - uint32_t record_id; /* Service record id */ - uint16_t id; /* Service class identifier */ - GIOChannel *io; /* GIOChannel when listening */ + char *iface; /* Routing interface */ + char *name; /* Server service name */ + char *path; /* D-Bus path */ + dbus_bool_t secure; + uint32_t record_id; /* Service record id */ + uint16_t id; /* Service class identifier */ + GIOChannel *io; /* GIOChannel when listening */ + DBusConnection *conn; /* D-Bus connection */ + struct pending_auth *pauth; /* Pending incomming connection/authorization */ }; -void add_lang_attr(sdp_record_t *r) +static char netdev[16] = "bnep%d"; + +static void pending_auth_free(struct pending_auth *pauth) +{ + if (!pauth) + return; + if (pauth->addr) + g_free(pauth->addr); + /* FIXME: Is it necessary close the BNEP socket? */ + if (pauth->io) + g_io_channel_unref(pauth->io); + g_free(pauth); +} + +static void add_lang_attr(sdp_record_t *r) { sdp_lang_attr_t base_lang; sdp_list_t *langs = 0; @@ -187,11 +213,228 @@ static int create_server_record(sdp_buf_t *buf, uint16_t id) return ret; } +static int send_bnep_ctrl_rsp(GIOChannel *chan, uint16_t response) +{ + struct bnep_control_rsp rsp; + GIOError gerr; + gsize n; + + rsp.type = BNEP_CONTROL; + rsp.ctrl = BNEP_SETUP_CONN_RSP; + rsp.resp = htons(response); + + gerr = g_io_channel_write(chan, (gchar *)&rsp, sizeof(rsp), &n); + + return -gerr; +} + +static void authorization_callback(DBusPendingCall *pcall, void *data) +{ + struct network_server *ns = data; + DBusMessage *reply = dbus_pending_call_steal_reply(pcall); + DBusError derr; + uint16_t response; + + if (!ns->pauth) + goto failed; + + dbus_error_init(&derr); + if (dbus_set_error_from_message(&derr, reply)) { + error("Access denied: %s", derr.message); + response = BNEP_CONN_NOT_ALLOWED; + } else { + char devname[16]; + int sk; + + response = BNEP_SUCCESS; + + memset(devname, 0, 16); + strncpy(devname, netdev, 16); + + /* FIXME: Is it the correct order? */ + sk = g_io_channel_unix_get_fd(ns->pauth->io); + bnep_connadd(sk, BNEP_SVC_PANU, devname); + + info("Authorization succedded. New connection: %s", devname); + + /* FIXME: send the D-Bus message to notify the new bnep iface */ + } + + send_bnep_ctrl_rsp(ns->pauth->io, response); + + pending_auth_free(ns->pauth); + ns->pauth = NULL; + +failed: + dbus_message_unref(reply); + dbus_pending_call_unref(pcall); +} + +static int authorize_connection(struct network_server *ns) +{ + DBusMessage *msg; + DBusPendingCall *pending; + const char *uuid = ""; /* FIXME: */ + + msg = dbus_message_new_method_call("org.bluez", "/org/bluez", + "org.bluez.Database", "RequestAuthorization"); + if (!msg) { + error("Unable to allocat new RequestAuthorization method call"); + return -ENOMEM; + } + + debug("Requesting authorization for %s UUID:%s", ns->pauth->addr, uuid); + + dbus_message_append_args(msg, + DBUS_TYPE_STRING, &ns->pauth->addr, + DBUS_TYPE_STRING, &uuid, + DBUS_TYPE_INVALID); + + if (dbus_connection_send_with_reply(ns->conn, msg, &pending, -1) == FALSE) { + error("Sending of authorization request failed"); + return -EACCES; + } + + dbus_pending_call_set_notify(pending, authorization_callback, ns, NULL); + dbus_message_unref(msg); + + return 0; +} + +static gboolean connect_setup_event(GIOChannel *chan, + GIOCondition cond, gpointer data) +{ + struct network_server *ns = data; + struct bnep_setup_conn_req *req; + unsigned char pkt[BNEP_MTU]; + gsize n; + GIOError gerr; + uint8_t *pservice; + uint16_t role, response; + + if (cond & G_IO_NVAL) + return FALSE; + + if (cond & (G_IO_ERR | G_IO_HUP)) { + error("Hangup or error on L2CAP socket"); + /* FIXME: Cancel the pending authorization if applied */ + return FALSE; + } + + /* FIXME: Missing address setup connection request retries */ + + gerr = g_io_channel_read(chan, (gchar *)pkt, sizeof(pkt) - 1, &n); + if (gerr != G_IO_ERROR_NONE) + return FALSE; + + if (n < sizeof(*req)) { + error("Invalid BNEP packet size"); + return FALSE; + } + + req = (void *)pkt; + if (req->type != BNEP_CONTROL || req->ctrl != BNEP_SETUP_CONN_REQ) { + error("Invalid BNEP control packet content"); + return FALSE; + } + + /* + * FIXME: According to BNEP SPEC the UUID size can be + * 2-16 bytes. Currently only 2 bytes size is supported + */ + if (req->uuid_size != 2) { + response = BNEP_CONN_INVALID_SVC; + goto reply; + } + + pservice = req->service; + /* Getting destination service: considering 2 bytes size */ + role = ntohs(bt_get_unaligned((uint16_t *) pservice)); + + pservice += req->uuid_size; + /* Getting source service: considering 2 bytes size */ + role = ntohs(bt_get_unaligned((uint16_t *) pservice)); + + if (role != BNEP_SVC_PANU) { + response = BNEP_CONN_INVALID_SRC; + goto reply; + } + + /* Wait authorization before reply success */ + if (authorize_connection(ns) < 0) { + response = BNEP_CONN_NOT_ALLOWED; + goto reply; + + } + + return TRUE; +reply: + send_bnep_ctrl_rsp(chan, response); + return FALSE; +} + +static void connect_setup_destroy(gpointer data) +{ + struct network_server *ns = data; + + if (ns->pauth) { + pending_auth_free(ns->pauth); + ns->pauth = NULL; + } +} + static gboolean connect_event(GIOChannel *chan, GIOCondition cond, gpointer data) { - info("FIXME: Connect event"); - return FALSE; + struct network_server *ns = data; + struct sockaddr_l2 addr; + socklen_t addrlen; + char peer[18]; + bdaddr_t dst; + unsigned short psm; + int sk, nsk; + + if (cond & G_IO_NVAL) + return FALSE; + + if (cond & (G_IO_ERR | G_IO_HUP)) { + error("Hangup or error on L2CAP socket PSM 15"); + /* FIXME: Notify the userspace? */ + return FALSE; + } + + sk = g_io_channel_unix_get_fd(chan); + + memset(&addr, 0, sizeof(addr)); + addrlen = sizeof(addr); + + nsk = accept(sk, (struct sockaddr *) &addr, &addrlen); + if (nsk < 0) + return TRUE; + + bacpy(&dst, &addr.l2_bdaddr); + psm = btohs(addr.l2_psm); + + /* FIXME: Maybe keep a list of connected devices */ + + ba2str(&dst, peer); + info("Incoming connection from:%s on PSM %d", peer, psm); + + /* FIXME: HOW handle multiple incomming connections? */ + + /* Setting the pending incomming connection setup */ + ns->pauth = g_new0(struct pending_auth, 1); + ns->pauth->addr = g_strdup(peer); + ns->pauth->io = g_io_channel_unix_new(nsk); + + g_io_channel_set_close_on_unref(ns->pauth->io, FALSE); + + /* New watch for BNEP setup */ + g_io_add_watch_full(ns->pauth->io, G_PRIORITY_DEFAULT, + G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + connect_setup_event, ns, &connect_setup_destroy); + + return TRUE; } static int l2cap_listen(struct network_server *ns) @@ -248,7 +491,7 @@ static int l2cap_listen(struct network_server *ns) goto fail; } - if (listen(sk, 10) < 0) { + if (listen(sk, 1) < 0) { err = errno; error("Listen failed. %s(%d)", strerror(err), err); goto fail; @@ -257,7 +500,8 @@ static int l2cap_listen(struct network_server *ns) ns->io = g_io_channel_unix_new(sk); g_io_channel_set_close_on_unref(ns->io, TRUE); - g_io_add_watch(ns->io, G_IO_IN, connect_event, NULL); + g_io_add_watch(ns->io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + connect_event, ns); return 0; fail: @@ -559,6 +803,14 @@ static void server_free(struct network_server *ns) if (ns->path) g_free(ns->path); + if (ns->conn) + dbus_connection_unref(ns->conn); + + if (ns->io) + g_io_channel_unref(ns->io); + + /* FIXME: Missing release/free all bnepX interfaces */ + g_free(ns); } @@ -598,6 +850,7 @@ 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); info("Registered server path:%s", ns->path); return 0; -- cgit From 45bddf6307e9a6f017a313d2b3e16ef6ce8db376 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 28 Mar 2007 13:44:27 +0000 Subject: network: Remove the service record when the server path is unregistered --- network/server.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index e33e7133..0dd29d0d 100644 --- a/network/server.c +++ b/network/server.c @@ -563,6 +563,39 @@ static uint32_t add_server_record(DBusConnection *conn, uint16_t id) return rec_id; } +static int remove_server_record(DBusConnection *conn, uint32_t rec_id) +{ + DBusMessage *msg, *reply; + DBusError derr; + + msg = dbus_message_new_method_call("org.bluez", "/org/bluez", + "org.bluez.Database", "RemoveServiceRecord"); + if (!msg) { + error("Can't allocate new method call"); + return -ENOMEM; + } + + dbus_message_append_args(msg, + DBUS_TYPE_UINT32, &rec_id, + DBUS_TYPE_INVALID); + + dbus_error_init(&derr); + reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &derr); + + dbus_message_unref(msg); + + if (dbus_error_is_set(&derr)) { + error("Removing service record 0x%x failed: %s", + rec_id, derr.message); + dbus_error_free(&derr); + return -1; + } + + dbus_message_unref(reply); + + return 0; +} + static DBusHandlerResult get_uuid(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -794,6 +827,10 @@ static void server_free(struct network_server *ns) if (!ns) return; + /* FIXME: Missing release/free all bnepX interfaces */ + if (ns->record_id) + remove_server_record(ns->conn, ns->record_id); + if (ns->iface) g_free(ns->iface); @@ -809,8 +846,6 @@ static void server_free(struct network_server *ns) if (ns->io) g_io_channel_unref(ns->io); - /* FIXME: Missing release/free all bnepX interfaces */ - g_free(ns); } -- cgit From 44f1d3a1a09a29afd84496a1d6b49d08caf3dbe2 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 28 Mar 2007 14:35:28 +0000 Subject: network: added Server.Disable --- network/server.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 0dd29d0d..e70e13ab 100644 --- a/network/server.c +++ b/network/server.c @@ -642,10 +642,30 @@ static DBusHandlerResult enable(DBusConnection *conn, return send_message_and_unref(conn, reply); } -static DBusHandlerResult disable(DBusConnection *conn, DBusMessage *msg, - void *data) +static DBusHandlerResult disable(DBusConnection *conn, + DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct network_server *ns = data; + DBusMessage *reply; + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + if (!ns->io) + return err_failed(conn, msg, "Not enabled"); + + /* Remove the service record */ + if (ns->record_id) { + remove_server_record(conn, ns->record_id); + ns->record_id = 0; + } + + g_io_channel_unref(ns->io); + g_io_channel_close(ns->io); + ns->io = NULL; + + return send_message_and_unref(conn, reply); } static DBusHandlerResult set_name(DBusConnection *conn, @@ -843,8 +863,10 @@ static void server_free(struct network_server *ns) if (ns->conn) dbus_connection_unref(ns->conn); - if (ns->io) + if (ns->io) { g_io_channel_unref(ns->io); + g_io_channel_close(ns->io); + } g_free(ns); } -- cgit From 50bec7777e06c2321b7b21c8b69ff48acad54190 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 28 Mar 2007 15:22:39 +0000 Subject: network: fixed server role when calling bnep_connadd --- network/server.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index e70e13ab..e8dedf7b 100644 --- a/network/server.c +++ b/network/server.c @@ -253,10 +253,14 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) /* FIXME: Is it the correct order? */ sk = g_io_channel_unix_get_fd(ns->pauth->io); - bnep_connadd(sk, BNEP_SVC_PANU, devname); + bnep_connadd(sk, ns->id, devname); + + /* FIXME: Reply not allowed if bnep connection add fails? */ info("Authorization succedded. New connection: %s", devname); + /* Enable routing if applied */ + /* FIXME: send the D-Bus message to notify the new bnep iface */ } @@ -360,6 +364,11 @@ static gboolean connect_setup_event(GIOChannel *chan, goto reply; } + /* + * FIXME: Check if the connection already exists. Check if the + * BNEP SPEC allows return "connection not allowed" for this case + */ + /* Wait authorization before reply success */ if (authorize_connection(ns) < 0) { response = BNEP_CONN_NOT_ALLOWED; -- cgit From ea1a79ba431bd7aec17fe24084577443fb2a72d5 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 28 Mar 2007 15:33:31 +0000 Subject: network: reply bnep "not allowed" if the bnep_connadd fails --- network/server.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index e8dedf7b..e04d6de4 100644 --- a/network/server.c +++ b/network/server.c @@ -232,8 +232,10 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) { struct network_server *ns = data; DBusMessage *reply = dbus_pending_call_steal_reply(pcall); + char devname[16]; DBusError derr; uint16_t response; + int sk; if (!ns->pauth) goto failed; @@ -242,28 +244,28 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) if (dbus_set_error_from_message(&derr, reply)) { error("Access denied: %s", derr.message); response = BNEP_CONN_NOT_ALLOWED; - } else { - char devname[16]; - int sk; - - response = BNEP_SUCCESS; - - memset(devname, 0, 16); - strncpy(devname, netdev, 16); + dbus_error_free(&derr); + goto reply; + } - /* FIXME: Is it the correct order? */ - sk = g_io_channel_unix_get_fd(ns->pauth->io); - bnep_connadd(sk, ns->id, devname); + memset(devname, 0, 16); + strncpy(devname, netdev, 16); - /* FIXME: Reply not allowed if bnep connection add fails? */ + /* FIXME: Is it the correct order? */ + sk = g_io_channel_unix_get_fd(ns->pauth->io); + if (bnep_connadd(sk, ns->id, devname) < 0) { + response = BNEP_CONN_NOT_ALLOWED; + goto reply; + } - info("Authorization succedded. New connection: %s", devname); + info("Authorization succedded. New connection: %s", devname); + response = BNEP_SUCCESS; - /* Enable routing if applied */ + /* FIXME: Enable routing if applied */ - /* FIXME: send the D-Bus message to notify the new bnep iface */ - } + /* FIXME: send the D-Bus message to notify the new bnep iface */ +reply: send_bnep_ctrl_rsp(ns->pauth->io, response); pending_auth_free(ns->pauth); -- cgit From 12575376b7b94dd7b4a145ab166f0805755c13a1 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 28 Mar 2007 17:52:43 +0000 Subject: network: making service name/security configurable --- network/server.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index e04d6de4..72f8dc4a 100644 --- a/network/server.c +++ b/network/server.c @@ -78,8 +78,10 @@ static void pending_auth_free(struct pending_auth *pauth) if (pauth->addr) g_free(pauth->addr); /* FIXME: Is it necessary close the BNEP socket? */ - if (pauth->io) + if (pauth->io) { g_io_channel_unref(pauth->io); + g_io_channel_close(pauth->io); + } g_free(pauth); } @@ -97,7 +99,8 @@ static void add_lang_attr(sdp_record_t *r) sdp_list_free(langs, 0); } -static int create_server_record(sdp_buf_t *buf, uint16_t id) +static int create_server_record(sdp_buf_t *buf, const char *name, + uint16_t id, dbus_bool_t secure) { sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto; uuid_t root_uuid, pan, l2cap, bnep; @@ -105,16 +108,13 @@ static int create_server_record(sdp_buf_t *buf, uint16_t id) sdp_list_t *proto[2]; sdp_data_t *v, *p; uint16_t psm = BNEP_PSM, version = 0x0100; - uint16_t security_desc = 0; + uint16_t security_desc = (secure ? 0x0001 : 0x0000); uint16_t net_access_type = 0xfffe; uint32_t max_net_access_rate = 0; - const char *name = "BlueZ PAN"; const char *desc = "BlueZ PAN Service"; sdp_record_t record; int ret; - /* FIXME: service name must be configurable */ - memset(&record, 0, sizeof(sdp_record_t)); sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); @@ -322,7 +322,7 @@ static gboolean connect_setup_event(GIOChannel *chan, return FALSE; if (cond & (G_IO_ERR | G_IO_HUP)) { - error("Hangup or error on L2CAP socket"); + error("Hangup or error on BNEP socket"); /* FIXME: Cancel the pending authorization if applied */ return FALSE; } @@ -522,7 +522,7 @@ fail: return -err; } -static uint32_t add_server_record(DBusConnection *conn, uint16_t id) +static uint32_t add_server_record(struct network_server *ns) { DBusMessage *msg, *reply; DBusError derr; @@ -536,7 +536,7 @@ static uint32_t add_server_record(DBusConnection *conn, uint16_t id) return 0; } - if (create_server_record(&buf, id) < 0) { + if (create_server_record(&buf, ns->name, ns->id, ns->secure) < 0) { error("Unable to allocate new service record"); dbus_message_unref(msg); return 0; @@ -546,7 +546,7 @@ static uint32_t add_server_record(DBusConnection *conn, uint16_t id) &buf.data, buf.data_size, DBUS_TYPE_INVALID); dbus_error_init(&derr); - reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &derr); + reply = dbus_connection_send_with_reply_and_block(ns->conn, msg, -1, &derr); free(buf.data); dbus_message_unref(msg); @@ -638,7 +638,7 @@ static DBusHandlerResult enable(DBusConnection *conn, return DBUS_HANDLER_RESULT_NEED_MEMORY; /* Add the service record */ - ns->record_id = add_server_record(conn, ns->id); + ns->record_id = add_server_record(ns); if (!ns->record_id) { error("Unable to register the server(0x%x) service record", ns->id); return err_failed(conn, msg, "Unable to register the service record"); @@ -916,9 +916,16 @@ int server_register(DBusConnection *conn, const char *path, uint16_t id) goto fail; } + /* Setting a default name */ + if (id == BNEP_SVC_NAP) + ns->name = g_strdup("Bluetooth NAP service"); + else + ns->name = g_strdup("Bluetooth GN service"); + ns->path = g_strdup(path); ns->id = id; ns->conn = dbus_connection_ref(conn); + info("Registered server path:%s", ns->path); return 0; -- cgit From a26656784f5bdd8b5010637b78d3604343d694d0 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 28 Mar 2007 20:59:36 +0000 Subject: network: update the service record when the attributes changed(name, security) --- network/server.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 72f8dc4a..82927162 100644 --- a/network/server.c +++ b/network/server.c @@ -159,7 +159,6 @@ static int create_server_record(sdp_buf_t *buf, const char *name, add_lang_attr(&record); - /* FIXME: Missing check the security attribute */ sdp_attr_add_new(&record, SDP_ATTR_SECURITY_DESC, SDP_UINT16, &security_desc); @@ -707,7 +706,14 @@ static DBusHandlerResult set_name(DBusConnection *conn, g_free(ns->name); ns->name = g_strdup(name); - /* FIXME: Update the service record attribute */ + if (ns->io) { + /* Server enabled - service record already registred + * Workaround: Currently it is not possible update + * one service record attribute using D-Bus methods + */ + remove_server_record(ns->conn, ns->record_id); + ns->record_id = add_server_record(ns); + } return send_message_and_unref(conn, reply); } @@ -792,6 +798,15 @@ static DBusHandlerResult set_security(DBusConnection *conn, ns->secure = secure; + if (ns->io) { + /* Server enabled - service record already registred + * Workaround: Currently it is not possible update + * one service record attribute using D-Bus methods + */ + remove_server_record(ns->conn, ns->record_id); + ns->record_id = add_server_record(ns); + } + return send_message_and_unref(conn, reply); } -- cgit From 9c2ff557a3ffade313dd5dbff6a5b86552ae8208 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 28 Mar 2007 21:11:22 +0000 Subject: network: removed ProviderName attribute from the server service record --- network/server.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 82927162..edd89c60 100644 --- a/network/server.c +++ b/network/server.c @@ -111,7 +111,7 @@ static int create_server_record(sdp_buf_t *buf, const char *name, uint16_t security_desc = (secure ? 0x0001 : 0x0000); uint16_t net_access_type = 0xfffe; uint32_t max_net_access_rate = 0; - const char *desc = "BlueZ PAN Service"; + const char *desc = "BlueZ PAN service"; sdp_record_t record; int ret; @@ -172,7 +172,7 @@ static int create_server_record(sdp_buf_t *buf, const char *name, pfseq = sdp_list_append(NULL, &profile[0]); sdp_set_profile_descs(&record, pfseq); - sdp_set_info_attr(&record, "Network Access Point", name, desc); + sdp_set_info_attr(&record, name, NULL, desc); sdp_attr_add_new(&record, SDP_ATTR_NET_ACCESS_TYPE, SDP_UINT16, &net_access_type); @@ -189,7 +189,7 @@ static int create_server_record(sdp_buf_t *buf, const char *name, pfseq = sdp_list_append(NULL, &profile[0]); sdp_set_profile_descs(&record, pfseq); - sdp_set_info_attr(&record, "Group Network Service", name, desc); + sdp_set_info_attr(&record, name, NULL, desc); } if (sdp_gen_record_pdu(&record, buf) < 0) @@ -933,9 +933,9 @@ int server_register(DBusConnection *conn, const char *path, uint16_t id) /* Setting a default name */ if (id == BNEP_SVC_NAP) - ns->name = g_strdup("Bluetooth NAP service"); + ns->name = g_strdup("BlueZ NAP service"); else - ns->name = g_strdup("Bluetooth GN service"); + ns->name = g_strdup("BlueZ GN service"); ns->path = g_strdup(path); ns->id = id; -- cgit From a74ce132aa15b199bfa727ca445db7ba9642d770 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 29 Mar 2007 18:27:01 +0000 Subject: network: reject incomming connections if there is a pending authorization --- network/server.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index edd89c60..60293cf7 100644 --- a/network/server.c +++ b/network/server.c @@ -326,8 +326,6 @@ static gboolean connect_setup_event(GIOChannel *chan, return FALSE; } - /* FIXME: Missing address setup connection request retries */ - gerr = g_io_channel_read(chan, (gchar *)pkt, sizeof(pkt) - 1, &n); if (gerr != G_IO_ERROR_NONE) return FALSE; @@ -428,9 +426,19 @@ static gboolean connect_event(GIOChannel *chan, /* FIXME: Maybe keep a list of connected devices */ ba2str(&dst, peer); - info("Incoming connection from:%s on PSM %d", peer, psm); + if (ns->pauth) { + GIOChannel *io; + error("Rejecting connection from %s\ + due pending authorization", peer); + io = g_io_channel_unix_new(nsk); + send_bnep_ctrl_rsp(io, BNEP_CONN_NOT_ALLOWED); + g_io_channel_unref(io); + g_io_channel_close(io); + close(nsk); + return TRUE; + } - /* FIXME: HOW handle multiple incomming connections? */ + info("Incoming connection from:%s on PSM %d", peer, psm); /* Setting the pending incomming connection setup */ ns->pauth = g_new0(struct pending_auth, 1); -- cgit From 675f1f3b5e07f09bca4761e7b18f3bca6fa56ddd Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 29 Mar 2007 19:10:15 +0000 Subject: network: cancel authorization if the time expires --- network/server.c | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 60293cf7..f180401e 100644 --- a/network/server.c +++ b/network/server.c @@ -227,6 +227,28 @@ static int send_bnep_ctrl_rsp(GIOChannel *chan, uint16_t response) return -gerr; } +static void cancel_authorization(struct network_server *ns) +{ + DBusMessage *msg; + const char *paddress = ns->pauth->addr; + const char *uuid = ""; + + msg = dbus_message_new_method_call("org.bluez", "/org/bluez", + "org.bluez.Database", + "CancelAuthorizationRequest"); + if (!msg) { + error("Unable to allocate new method call"); + return; + } + + dbus_message_append_args(msg, + DBUS_TYPE_STRING, &paddress, + DBUS_TYPE_STRING, &uuid, + DBUS_TYPE_INVALID); + + send_message_and_unref(ns->conn, msg); +} + static void authorization_callback(DBusPendingCall *pcall, void *data) { struct network_server *ns = data; @@ -236,15 +258,19 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) uint16_t response; int sk; - if (!ns->pauth) - goto failed; + if (!ns->pauth) { + dbus_message_unref(reply); + dbus_pending_call_unref(pcall); + return; + } dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { error("Access denied: %s", derr.message); response = BNEP_CONN_NOT_ALLOWED; dbus_error_free(&derr); - goto reply; + cancel_authorization(ns); + goto failed; } memset(devname, 0, 16); @@ -254,7 +280,7 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) sk = g_io_channel_unix_get_fd(ns->pauth->io); if (bnep_connadd(sk, ns->id, devname) < 0) { response = BNEP_CONN_NOT_ALLOWED; - goto reply; + goto failed; } info("Authorization succedded. New connection: %s", devname); @@ -264,13 +290,12 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) /* FIXME: send the D-Bus message to notify the new bnep iface */ -reply: +failed: send_bnep_ctrl_rsp(ns->pauth->io, response); pending_auth_free(ns->pauth); ns->pauth = NULL; -failed: dbus_message_unref(reply); dbus_pending_call_unref(pcall); } @@ -428,8 +453,7 @@ static gboolean connect_event(GIOChannel *chan, ba2str(&dst, peer); if (ns->pauth) { GIOChannel *io; - error("Rejecting connection from %s\ - due pending authorization", peer); + error("Rejecting %s(pending authorization)", peer); io = g_io_channel_unix_new(nsk); send_bnep_ctrl_rsp(io, BNEP_CONN_NOT_ALLOWED); g_io_channel_unref(io); @@ -438,7 +462,7 @@ static gboolean connect_event(GIOChannel *chan, return TRUE; } - info("Incoming connection from:%s on PSM %d", peer, psm); + info("Connection from:%s on PSM %d", peer, psm); /* Setting the pending incomming connection setup */ ns->pauth = g_new0(struct pending_auth, 1); -- cgit From 6c3a14c15dd13df90bdeff09628a2e434cb23d96 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 29 Mar 2007 19:14:31 +0000 Subject: network: only send cancel authorization if the error name is NoReply --- network/server.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index f180401e..1e1bede0 100644 --- a/network/server.c +++ b/network/server.c @@ -267,9 +267,12 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { error("Access denied: %s", derr.message); + if (dbus_error_has_name(&derr, DBUS_ERROR_NO_REPLY)) { + debug("Canceling authorization request"); + cancel_authorization(ns); + } response = BNEP_CONN_NOT_ALLOWED; dbus_error_free(&derr); - cancel_authorization(ns); goto failed; } -- cgit From 778fb0ca85a18c20a60cbd44c8786d60efe4d297 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 29 Mar 2007 21:49:17 +0000 Subject: network: Added bridge add interface function --- network/server.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 1e1bede0..5ae7c634 100644 --- a/network/server.c +++ b/network/server.c @@ -47,6 +47,7 @@ #define NETWORK_SERVER_INTERFACE "org.bluez.network.Server" +#include "bridge.h" #include "common.h" #include "server.h" @@ -264,6 +265,8 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) return; } + sk = g_io_channel_unix_get_fd(ns->pauth->io); + dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { error("Access denied: %s", derr.message); @@ -279,8 +282,6 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) memset(devname, 0, 16); strncpy(devname, netdev, 16); - /* FIXME: Is it the correct order? */ - sk = g_io_channel_unix_get_fd(ns->pauth->io); if (bnep_connadd(sk, ns->id, devname) < 0) { response = BNEP_CONN_NOT_ALLOWED; goto failed; @@ -289,6 +290,13 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) info("Authorization succedded. New connection: %s", devname); response = BNEP_SUCCESS; + if (bridge_add_interface("pan0", devname) < 0) { + error("Can't add %s to the bridge: %s(%d)", + devname, strerror(errno), errno); + response = BNEP_CONN_NOT_ALLOWED; + goto failed; + } + /* FIXME: Enable routing if applied */ /* FIXME: send the D-Bus message to notify the new bnep iface */ @@ -299,6 +307,8 @@ failed: pending_auth_free(ns->pauth); ns->pauth = NULL; + close(sk); + dbus_message_unref(reply); dbus_pending_call_unref(pcall); } @@ -678,8 +688,6 @@ static DBusHandlerResult enable(DBusConnection *conn, return err_failed(conn, msg, "Unable to register the service record"); } - /* FIXME: Check security */ - err = l2cap_listen(ns); if (err < 0) return err_failed(conn, msg, strerror(-err)); -- cgit From ada09c331c02c73acf9e208871a7fc04589a77fa Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 30 Mar 2007 13:54:31 +0000 Subject: network: ignore repeated BNEP conn req msg from the same device if there a pending auth --- network/server.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 5ae7c634..579e5c06 100644 --- a/network/server.c +++ b/network/server.c @@ -55,6 +55,7 @@ struct pending_auth { char *addr; /* Bluetooth Address */ GIOChannel *io; /* BNEP connection setup io channel */ + int attempts; /* BNEP setup conn requests counter */ }; /* Main server structure */ @@ -379,6 +380,14 @@ static gboolean connect_setup_event(GIOChannel *chan, return FALSE; } + if (++ns->pauth->attempts > 1) { + /* + * Ignore repeated BNEP setup connection request: there + * is a pending authorization request for this device. + */ + return TRUE; + } + /* * FIXME: According to BNEP SPEC the UUID size can be * 2-16 bytes. Currently only 2 bytes size is supported -- cgit From c08ade22068fc1003f1900a6e0989c212bbb5dd6 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 30 Mar 2007 17:40:29 +0000 Subject: network: fixed GIOChannel close/unref order --- network/server.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 579e5c06..67319107 100644 --- a/network/server.c +++ b/network/server.c @@ -79,10 +79,9 @@ static void pending_auth_free(struct pending_auth *pauth) return; if (pauth->addr) g_free(pauth->addr); - /* FIXME: Is it necessary close the BNEP socket? */ if (pauth->io) { - g_io_channel_unref(pauth->io); g_io_channel_close(pauth->io); + g_io_channel_unref(pauth->io); } g_free(pauth); } @@ -478,9 +477,8 @@ static gboolean connect_event(GIOChannel *chan, error("Rejecting %s(pending authorization)", peer); io = g_io_channel_unix_new(nsk); send_bnep_ctrl_rsp(io, BNEP_CONN_NOT_ALLOWED); - g_io_channel_unref(io); g_io_channel_close(io); - close(nsk); + g_io_channel_unref(io); return TRUE; } @@ -724,7 +722,6 @@ static DBusHandlerResult disable(DBusConnection *conn, } g_io_channel_unref(ns->io); - g_io_channel_close(ns->io); ns->io = NULL; return send_message_and_unref(conn, reply); @@ -942,8 +939,8 @@ static void server_free(struct network_server *ns) dbus_connection_unref(ns->conn); if (ns->io) { - g_io_channel_unref(ns->io); g_io_channel_close(ns->io); + g_io_channel_unref(ns->io); } g_free(ns); -- cgit From 0f09acbace55a146315d240d45132faf62ad45cf Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 2 Apr 2007 18:23:50 +0000 Subject: Add storage code. --- network/server.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) (limited to 'network/server.c') 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 #include #include +#include +#include #include #include @@ -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; +} -- cgit From eac4f4085dcfbad3344109f76bce6ab2656a6b50 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 5 Apr 2007 19:47:27 +0000 Subject: network: handle the GIOChannel errors properly --- network/server.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 0c0932ae..f61d586c 100644 --- a/network/server.c +++ b/network/server.c @@ -499,7 +499,7 @@ static gboolean connect_event(GIOChannel *chan, if (cond & (G_IO_ERR | G_IO_HUP)) { error("Hangup or error on L2CAP socket PSM 15"); - /* FIXME: Notify the userspace? */ + g_io_channel_close(chan); return FALSE; } @@ -606,7 +606,7 @@ static int l2cap_listen(struct network_server *ns) } ns->io = g_io_channel_unix_new(sk); - g_io_channel_set_close_on_unref(ns->io, TRUE); + g_io_channel_set_close_on_unref(ns->io, FALSE); g_io_add_watch(ns->io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, connect_event, ns); @@ -772,6 +772,7 @@ static DBusHandlerResult disable(DBusConnection *conn, ns->record_id = 0; } + g_io_channel_close(ns->io); g_io_channel_unref(ns->io); ns->io = NULL; -- cgit From 40d78525064e6d725a1050dea641c80640edee5d Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 5 Apr 2007 20:00:31 +0000 Subject: network: cancel pending auth if an error happens in the BNEP GIOChannel --- network/server.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index f61d586c..2a3961ca 100644 --- a/network/server.c +++ b/network/server.c @@ -277,9 +277,14 @@ static int send_bnep_ctrl_rsp(GIOChannel *chan, uint16_t response) static void cancel_authorization(struct network_server *ns) { DBusMessage *msg; - const char *paddress = ns->pauth->addr; + const char *paddress; const char *uuid = ""; + if (!ns->pauth) + return; + + paddress = ns->pauth->addr; + msg = dbus_message_new_method_call("org.bluez", "/org/bluez", "org.bluez.Database", "CancelAuthorizationRequest"); @@ -406,7 +411,7 @@ static gboolean connect_setup_event(GIOChannel *chan, if (cond & (G_IO_ERR | G_IO_HUP)) { error("Hangup or error on BNEP socket"); - /* FIXME: Cancel the pending authorization if applied */ + cancel_authorization(ns); return FALSE; } -- cgit From 4d8f5eb37c895d875a7fdcce45f03c406adfa668 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 12 Apr 2007 18:42:47 +0000 Subject: network: changed the server D-Bus path and moved storage functions to manager.c --- network/server.c | 73 +++----------------------------------------------------- 1 file changed, 3 insertions(+), 70 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 2a3961ca..e1e27341 100644 --- a/network/server.c +++ b/network/server.c @@ -30,8 +30,6 @@ #include #include #include -#include -#include #include #include @@ -51,8 +49,8 @@ #include "bridge.h" #include "common.h" +#include "manager.h" #include "server.h" -#include "textfile.h" /* Pending Authorization */ struct pending_auth { @@ -77,48 +75,6 @@ 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) @@ -753,7 +709,7 @@ static DBusHandlerResult enable(DBusConnection *conn, if (err < 0) return err_failed(conn, msg, strerror(-err)); - store_server_info(&ns->src, ns->id, TRUE); + network_store_info(&ns->src, ns->id, TRUE); return send_message_and_unref(conn, reply); } @@ -781,7 +737,7 @@ static DBusHandlerResult disable(DBusConnection *conn, g_io_channel_unref(ns->io); ns->io = NULL; - store_server_info(&ns->src, ns->id, FALSE); + network_store_info(&ns->src, ns->id, FALSE); return send_message_and_unref(conn, reply); } @@ -1002,8 +958,6 @@ 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); } @@ -1055,29 +1009,8 @@ int server_register(DBusConnection *conn, const char *addr, const char *path, 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; -} -- cgit From 2cd680bf44197f4fdba3fdfe6d042dcc373c1c52 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 13 Apr 2007 16:42:57 +0000 Subject: network: added functions prototypes for nap/gn registration --- network/server.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index e1e27341..c6215b8a 100644 --- a/network/server.c +++ b/network/server.c @@ -1014,3 +1014,15 @@ fail: server_free(ns); return -1; } + +int register_nap_from_file(const bdaddr_t *src, const char *filename) +{ + /* FIXME: extract name, description, secure, enabled, address range, routing ...*/ + return 0; +} + +int register_gn_from_file(const bdaddr_t *src, const char *filename) +{ + /* FIXME: extract name, description, secure, enabled, address range ...*/ + return 0; +} -- cgit From 235f0862a242772d8e3e51cd4f4dd8277939bbe5 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 13 Apr 2007 20:21:11 +0000 Subject: network: added register_nap_from_file --- network/server.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index c6215b8a..be6316a1 100644 --- a/network/server.c +++ b/network/server.c @@ -44,6 +44,7 @@ #include "logging.h" #include "dbus.h" #include "error.h" +#include "textfile.h" #define NETWORK_SERVER_INTERFACE "org.bluez.network.Server" @@ -64,6 +65,7 @@ struct network_server { bdaddr_t src; /* Bluetooth Local Address */ char *iface; /* Routing interface */ char *name; /* Server service name */ + char *range; /* IP Address range */ char *path; /* D-Bus path */ dbus_bool_t secure; uint32_t record_id; /* Service record id */ @@ -947,6 +949,9 @@ static void server_free(struct network_server *ns) if (ns->name) g_free(ns->name); + if (ns->range) + g_free(ns->range); + if (ns->path) g_free(ns->path); @@ -1015,13 +1020,47 @@ fail: return -1; } -int register_nap_from_file(const bdaddr_t *src, const char *filename) +int register_nap_from_file(DBusConnection *conn, const char *path, + const bdaddr_t *src, const char *filename) { - /* FIXME: extract name, description, secure, enabled, address range, routing ...*/ + struct network_server *ns; + char *str; + + ns = g_new0(struct network_server, 1); + + ns->id = BNEP_SVC_NAP; + ns->name = textfile_get(filename, "name"); + if (ns->name) { + /* Name is mandatory */ + server_free(ns); + return -1; + } + ns->secure = FALSE; + str = textfile_get(filename, "secure"); + if (str) { + if (strcmp("1", str) == 0) + ns->secure = TRUE; + g_free(str); + } + + ns->range = textfile_get(filename, "address_range"); + ns->iface = textfile_get(filename, "routing"); + + /* Register path */ + if (!dbus_connection_register_object_path(conn, path, + &server_table, ns)) { + error("D-Bus failed to register %s path", path); + server_free(ns); + return -1; + } + + /* FIXME: Missing enabled the server(if applied) */ + return 0; } -int register_gn_from_file(const bdaddr_t *src, const char *filename) +int register_gn_from_file(DBusConnection *conn, const char *path, + const bdaddr_t *src, const char *filename) { /* FIXME: extract name, description, secure, enabled, address range ...*/ return 0; -- cgit From a4bc8363b53f68c20bed8dcf5bf436c8609be199 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 13 Apr 2007 20:38:37 +0000 Subject: network: moved register_nap_from_file to server_register_from file to support gn and nap registration --- network/server.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index be6316a1..a7dc3f6b 100644 --- a/network/server.c +++ b/network/server.c @@ -1012,7 +1012,7 @@ int server_register(DBusConnection *conn, const char *addr, const char *path, ns->conn = dbus_connection_ref(conn); str2ba(addr, &ns->src); - info("Registered server path:%s", ns->path); + info("Registered server path:%s", path); return 0; fail: @@ -1020,21 +1020,22 @@ fail: return -1; } -int register_nap_from_file(DBusConnection *conn, const char *path, - const bdaddr_t *src, const char *filename) +int server_register_from_file(DBusConnection *conn, const char *path, + const bdaddr_t *src, uint16_t id, const char *filename) { struct network_server *ns; char *str; ns = g_new0(struct network_server, 1); - ns->id = BNEP_SVC_NAP; + ns->id = id; ns->name = textfile_get(filename, "name"); - if (ns->name) { + if (!ns->name) { /* Name is mandatory */ server_free(ns); return -1; } + ns->secure = FALSE; str = textfile_get(filename, "secure"); if (str) { @@ -1056,12 +1057,7 @@ int register_nap_from_file(DBusConnection *conn, const char *path, /* FIXME: Missing enabled the server(if applied) */ - return 0; -} + info("Registered server path:%s", path); -int register_gn_from_file(DBusConnection *conn, const char *path, - const bdaddr_t *src, const char *filename) -{ - /* FIXME: extract name, description, secure, enabled, address range ...*/ return 0; } -- cgit From af49fed2e0f5b71203c67fc163d29464ed534399 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 13 Apr 2007 20:58:03 +0000 Subject: network: changed server_register signature and code cleanup --- network/server.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index a7dc3f6b..2e6ae84c 100644 --- a/network/server.c +++ b/network/server.c @@ -981,8 +981,8 @@ static const DBusObjectPathVTable server_table = { .unregister_function = server_unregister, }; -int server_register(DBusConnection *conn, const char *addr, const char *path, - uint16_t id) +int server_register(DBusConnection *conn, const char *path, + bdaddr_t *src, uint16_t id) { struct network_server *ns; @@ -998,7 +998,8 @@ int server_register(DBusConnection *conn, const char *addr, const char *path, if (!dbus_connection_register_object_path(conn, path, &server_table, ns)) { error("D-Bus failed to register %s path", path); - goto fail; + server_free(ns); + return -1; } /* Setting a default name */ @@ -1010,14 +1011,11 @@ int server_register(DBusConnection *conn, const char *addr, const char *path, ns->path = g_strdup(path); ns->id = id; ns->conn = dbus_connection_ref(conn); - str2ba(addr, &ns->src); + bacpy(&ns->src, src); info("Registered server path:%s", path); return 0; -fail: - server_free(ns); - return -1; } int server_register_from_file(DBusConnection *conn, const char *path, @@ -1028,6 +1026,14 @@ int server_register_from_file(DBusConnection *conn, const char *path, ns = g_new0(struct network_server, 1); + /* Register path */ + if (!dbus_connection_register_object_path(conn, path, + &server_table, ns)) { + error("D-Bus failed to register %s path", path); + server_free(ns); + return -1; + } + ns->id = id; ns->name = textfile_get(filename, "name"); if (!ns->name) { @@ -1047,14 +1053,6 @@ int server_register_from_file(DBusConnection *conn, const char *path, ns->range = textfile_get(filename, "address_range"); ns->iface = textfile_get(filename, "routing"); - /* Register path */ - if (!dbus_connection_register_object_path(conn, path, - &server_table, ns)) { - error("D-Bus failed to register %s path", path); - server_free(ns); - return -1; - } - /* FIXME: Missing enabled the server(if applied) */ info("Registered server path:%s", path); -- cgit From ecde90ac204a58ea86026a9f9b556a52ac15187f Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 13 Apr 2007 21:32:36 +0000 Subject: Bring up interfaces on servers --- network/server.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 2e6ae84c..aaa14b41 100644 --- a/network/server.c +++ b/network/server.c @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #include @@ -266,7 +268,8 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) char devname[16]; DBusError derr; uint16_t response; - int sk; + int sk, sd; + struct ifreq ifr; if (!ns->pauth) { dbus_message_unref(reply); @@ -306,6 +309,13 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) goto failed; } + sd = socket(AF_INET6, SOCK_DGRAM, 0); + strcpy(ifr.ifr_name, devname); + ifr.ifr_flags |= IFF_UP; + if((ioctl(sd, SIOCSIFFLAGS, (caddr_t)&ifr)) == -1) { + error("Could not bring up %d", devname); + } + /* FIXME: Enable routing if applied */ /* FIXME: send the D-Bus message to notify the new bnep iface */ -- cgit From 4e12859a71297e7292c219eb9aea5ad00322c518 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 13 Apr 2007 21:49:21 +0000 Subject: Handle errors bringing up interfaces on servers --- network/server.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index aaa14b41..3134001c 100644 --- a/network/server.c +++ b/network/server.c @@ -268,7 +268,7 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) char devname[16]; DBusError derr; uint16_t response; - int sk, sd; + int sk, sd, err; struct ifreq ifr; if (!ns->pauth) { @@ -312,8 +312,10 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) sd = socket(AF_INET6, SOCK_DGRAM, 0); strcpy(ifr.ifr_name, devname); ifr.ifr_flags |= IFF_UP; - if((ioctl(sd, SIOCSIFFLAGS, (caddr_t)&ifr)) == -1) { - error("Could not bring up %d", devname); + if((ioctl(sd, SIOCSIFFLAGS, (caddr_t)&ifr)) < 0) { + err = errno; + error("Could not bring up %d. %s(%d)", devname, strerror(err), + err); } /* FIXME: Enable routing if applied */ -- cgit From dca71fe5565605289407c0d0810d066ed1f7e93f Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 13 Apr 2007 21:50:57 +0000 Subject: Fix code style --- network/server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 3134001c..053c2517 100644 --- a/network/server.c +++ b/network/server.c @@ -312,7 +312,7 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) sd = socket(AF_INET6, SOCK_DGRAM, 0); strcpy(ifr.ifr_name, devname); ifr.ifr_flags |= IFF_UP; - if((ioctl(sd, SIOCSIFFLAGS, (caddr_t)&ifr)) < 0) { + if((ioctl(sd, SIOCSIFFLAGS, (caddr_t) &ifr)) < 0) { err = errno; error("Could not bring up %d. %s(%d)", devname, strerror(err), err); -- cgit From 47895f4ab3f4de2682088dfba156106c772a92da Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Sat, 14 Apr 2007 00:19:59 +0000 Subject: network: addded server_store --- network/server.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 053c2517..9a7cd4d4 100644 --- a/network/server.c +++ b/network/server.c @@ -1071,3 +1071,31 @@ int server_register_from_file(DBusConnection *conn, const char *path, return 0; } + +int server_store(DBusConnection *conn, const char *path) +{ + struct network_server *ns; + char filename[PATH_MAX + 1]; + char addr[18]; + + if (!dbus_connection_get_object_path_data(conn, path, (void *) &ns)) + return -ENOENT; + + ba2str(&ns->src, addr); + if (ns->id == BNEP_SVC_NAP) + create_name(filename, PATH_MAX, STORAGEDIR, addr, "nap"); + else + create_name(filename, PATH_MAX, STORAGEDIR, addr, "gn"); + + textfile_put(filename, "name", ns->name); + + if (ns->iface) + textfile_put(filename, "routing", ns->iface); + + if (ns->range) + textfile_put(filename, "range", ns->range); + + textfile_put(filename, "secure", ns->secure ? "1": "0"); + + return 0; +} -- cgit From e968bf544679fbf8565b2354cb4beac3641538e4 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 16 Apr 2007 13:14:07 +0000 Subject: network: added server_remove_stored function --- network/server.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 9a7cd4d4..160f8910 100644 --- a/network/server.c +++ b/network/server.c @@ -1099,3 +1099,21 @@ int server_store(DBusConnection *conn, const char *path) return 0; } + +int server_remove_stored(DBusConnection *conn, const char *path) +{ + struct network_server *ns; + char filename[PATH_MAX + 1]; + char addr[18]; + + if (!dbus_connection_get_object_path_data(conn, path, (void *) &ns)) + return -ENOENT; + + ba2str(&ns->src, addr); + if (ns->id == BNEP_SVC_NAP) + create_name(filename, PATH_MAX, STORAGEDIR, addr, "nap"); + else + create_name(filename, PATH_MAX, STORAGEDIR, addr, "gn"); + + return remove(filename); +} -- cgit From 8c599674509651cc8e68d12ba21423dbf13305d9 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 16 Apr 2007 13:49:13 +0000 Subject: network: added function to store/update server property --- network/server.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 160f8910..f5a4b7c3 100644 --- a/network/server.c +++ b/network/server.c @@ -79,6 +79,21 @@ struct network_server { static char netdev[16] = "bnep%d"; +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 + create_name(filename, PATH_MAX, STORAGEDIR, addr, "gn"); + + return textfile_put(filename, key, value); +} + static void pending_auth_free(struct pending_auth *pauth) { if (!pauth) @@ -723,7 +738,7 @@ static DBusHandlerResult enable(DBusConnection *conn, if (err < 0) return err_failed(conn, msg, strerror(-err)); - network_store_info(&ns->src, ns->id, TRUE); + store_property(&ns->src, ns->id, "enabled", "1"); return send_message_and_unref(conn, reply); } @@ -751,7 +766,7 @@ static DBusHandlerResult disable(DBusConnection *conn, g_io_channel_unref(ns->io); ns->io = NULL; - network_store_info(&ns->src, ns->id, FALSE); + store_property(&ns->src, ns->id, "enabled", "0"); return send_message_and_unref(conn, reply); } -- cgit From 04f62adc118d1049e0aa2de19653004d4ccdf4b8 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 16 Apr 2007 13:57:46 +0000 Subject: network: missing assign src and path on server_register_from_file --- network/server.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index f5a4b7c3..1eeddb82 100644 --- a/network/server.c +++ b/network/server.c @@ -1061,6 +1061,8 @@ int server_register_from_file(DBusConnection *conn, const char *path, return -1; } + bacpy(&ns->src, src); + ns->path = g_strdup(path); ns->id = id; ns->name = textfile_get(filename, "name"); if (!ns->name) { -- cgit From 6745ef8707548a27267184c29dd126945da4b19e Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 16 Apr 2007 14:11:50 +0000 Subject: Add signals Enabled/Disabled. --- network/server.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 1eeddb82..754a37dc 100644 --- a/network/server.c +++ b/network/server.c @@ -717,7 +717,7 @@ static DBusHandlerResult enable(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_server *ns = data; - DBusMessage *reply; + DBusMessage *reply, *signal; int err; if (ns->io) @@ -740,6 +740,11 @@ static DBusHandlerResult enable(DBusConnection *conn, store_property(&ns->src, ns->id, "enabled", "1"); + signal = dbus_message_new_signal(ns->path, + NETWORK_SERVER_INTERFACE, "Enabled"); + + send_message_and_unref(conn, signal); + return send_message_and_unref(conn, reply); } @@ -747,7 +752,7 @@ static DBusHandlerResult disable(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_server *ns = data; - DBusMessage *reply; + DBusMessage *reply, *signal; reply = dbus_message_new_method_return(msg); if (!reply) @@ -768,6 +773,11 @@ static DBusHandlerResult disable(DBusConnection *conn, store_property(&ns->src, ns->id, "enabled", "0"); + signal = dbus_message_new_signal(ns->path, + NETWORK_SERVER_INTERFACE, "Disabled"); + + send_message_and_unref(conn, signal); + return send_message_and_unref(conn, reply); } -- cgit From d2692a02cf86935b4c96198eff694a01c3001890 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 16 Apr 2007 19:32:49 +0000 Subject: network: fixed default adapter --- network/server.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 754a37dc..e47c06ac 100644 --- a/network/server.c +++ b/network/server.c @@ -31,9 +31,12 @@ #include #include #include +#include #include #include +#include +#include #include #include #include @@ -723,6 +726,17 @@ static DBusHandlerResult enable(DBusConnection *conn, if (ns->io) return err_already_exists(conn, msg, "Server already enabled"); + if (bacmp(&ns->src, BDADDR_ANY) == 0) { + int dev_id; + + dev_id = hci_get_route(NULL); + if ((dev_id < 0) || (hci_devba(dev_id, &ns->src) < 0)) + return err_failed(conn, msg, "Adapter not available"); + + /* Store the server info */ + server_store(conn, ns->path); + } + reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; @@ -1114,6 +1128,8 @@ int server_store(DBusConnection *conn, const char *path) else create_name(filename, PATH_MAX, STORAGEDIR, addr, "gn"); + create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + textfile_put(filename, "name", ns->name); if (ns->iface) -- cgit From ef29c39ffc97adc9893841165f9e9a3f6a1e9a0a Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 16 Apr 2007 20:54:02 +0000 Subject: Move code to bring up interface to common and use it on connection. --- network/server.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index e47c06ac..7f4fbcf6 100644 --- a/network/server.c +++ b/network/server.c @@ -286,8 +286,7 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) char devname[16]; DBusError derr; uint16_t response; - int sk, sd, err; - struct ifreq ifr; + int sk; if (!ns->pauth) { dbus_message_unref(reply); @@ -327,14 +326,8 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) goto failed; } - sd = socket(AF_INET6, SOCK_DGRAM, 0); - strcpy(ifr.ifr_name, devname); - ifr.ifr_flags |= IFF_UP; - if((ioctl(sd, SIOCSIFFLAGS, (caddr_t) &ifr)) < 0) { - err = errno; - error("Could not bring up %d. %s(%d)", devname, strerror(err), - err); - } + bnep_if_up(devname, TRUE); + bnep_if_up("pan0", TRUE); /* FIXME: Enable routing if applied */ -- cgit From 4bae43ca784e1c1cb9d6da6b748c93532fc05c00 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 17 Apr 2007 19:48:53 +0000 Subject: Add GetInfo to network.Server interface. --- network/server.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 7f4fbcf6..f6f54474 100644 --- a/network/server.c +++ b/network/server.c @@ -50,6 +50,7 @@ #include "dbus.h" #include "error.h" #include "textfile.h" +#include "dbus-helper.h" #define NETWORK_SERVER_INTERFACE "org.bluez.network.Server" @@ -937,6 +938,38 @@ static DBusHandlerResult get_security(DBusConnection *conn, return send_message_and_unref(conn, reply); } +static DBusHandlerResult get_info(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + struct network_server *ns = data; + DBusMessage *reply; + DBusMessageIter iter; + DBusMessageIter dict; + const char *uuid; + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_message_iter_init_append(reply, &iter); + + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + 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_TYPE_STRING, &ns->name); + + uuid = bnep_uuid(ns->id); + dbus_message_iter_append_dict_entry(&dict, "uuid", + DBUS_TYPE_STRING, &uuid); + + dbus_message_iter_close_container(&iter, &dict); + + return send_message_and_unref(conn, reply); +} + static DBusHandlerResult server_message(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -975,6 +1008,9 @@ static DBusHandlerResult server_message(DBusConnection *conn, if (strcmp(member, "GetSecurity") == 0) return get_security(conn, msg, data); + if (strcmp(member, "GetInfo") == 0) + return get_info(conn, msg, data); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -- cgit From 71889d8638c31b0274e0a279b7879cd96aef7a50 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 23 Apr 2007 14:19:56 +0000 Subject: network: missing set the D-Bus connection when creating a server from file --- network/server.c | 1 + 1 file changed, 1 insertion(+) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index f6f54474..17534f9c 100644 --- a/network/server.c +++ b/network/server.c @@ -1117,6 +1117,7 @@ int server_register_from_file(DBusConnection *conn, const char *path, bacpy(&ns->src, src); ns->path = g_strdup(path); ns->id = id; + ns->conn = dbus_connection_ref(conn); ns->name = textfile_get(filename, "name"); if (!ns->name) { /* Name is mandatory */ -- cgit From 44847d5dfc0eebba1cebad1fbc89895901bfe09b Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 25 Apr 2007 22:14:22 +0000 Subject: Added UpdateServiceRecord --- network/server.c | 64 ++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 13 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 17534f9c..f50d1e06 100644 --- a/network/server.c +++ b/network/server.c @@ -658,6 +658,47 @@ static uint32_t add_server_record(struct network_server *ns) return rec_id; } +static int update_server_record(struct network_server *ns) +{ + DBusMessage *msg, *reply; + DBusError derr; + sdp_buf_t buf; + + msg = dbus_message_new_method_call("org.bluez", "/org/bluez", + "org.bluez.Database", "UpdateServiceRecord"); + if (!msg) { + error("Can't allocate new method call"); + return -ENOMEM; + } + + if (create_server_record(&buf, ns->name, ns->id, ns->secure) < 0) { + error("Unable to allocate new service record"); + dbus_message_unref(msg); + return -1; + } + + dbus_message_append_args(msg, + DBUS_TYPE_UINT32, &ns->record_id, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, + &buf.data, buf.data_size, DBUS_TYPE_INVALID); + + dbus_error_init(&derr); + reply = dbus_connection_send_with_reply_and_block(ns->conn, msg, -1, &derr); + + free(buf.data); + dbus_message_unref(msg); + + if (dbus_error_is_set(&derr) || dbus_set_error_from_message(&derr, reply)) { + error("Update service record failed: %s", derr.message); + dbus_error_free(&derr); + return -1; + } + + dbus_message_unref(reply); + + return 0; +} + static int remove_server_record(DBusConnection *conn, uint32_t rec_id) { DBusMessage *msg, *reply; @@ -818,12 +859,11 @@ static DBusHandlerResult set_name(DBusConnection *conn, ns->name = g_strdup(name); if (ns->io) { - /* Server enabled - service record already registred - * Workaround: Currently it is not possible update - * one service record attribute using D-Bus methods - */ - remove_server_record(ns->conn, ns->record_id); - ns->record_id = add_server_record(ns); + if (update_server_record(ns) < 0) { + dbus_message_unref(reply); + return err_failed(conn, msg, + "Service record attribute update failed"); + } } return send_message_and_unref(conn, reply); @@ -908,14 +948,12 @@ static DBusHandlerResult set_security(DBusConnection *conn, } ns->secure = secure; - if (ns->io) { - /* Server enabled - service record already registred - * Workaround: Currently it is not possible update - * one service record attribute using D-Bus methods - */ - remove_server_record(ns->conn, ns->record_id); - ns->record_id = add_server_record(ns); + if (update_server_record(ns) < 0) { + dbus_message_unref(reply); + return err_failed(conn, msg, + "Service record attribute update failed"); + } } return send_message_and_unref(conn, reply); -- cgit From 4cf3d33cf13dcb613bb50026a1908d18ee7b7f16 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 8 May 2007 13:48:37 +0000 Subject: Fix server load from storage and add FindServer to API. --- network/server.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 11 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index f50d1e06..0c22a67d 100644 --- a/network/server.c +++ b/network/server.c @@ -751,6 +751,24 @@ static DBusHandlerResult get_uuid(DBusConnection *conn, return send_message_and_unref(conn, reply); } +static int record_and_listen(struct network_server *ns) +{ + int err; + + /* Add the service record */ + ns->record_id = add_server_record(ns); + if (!ns->record_id) { + error("Unable to register the server(0x%x) service record", ns->id); + return -EIO; + } + + err = l2cap_listen(ns); + if (err < 0) + return -err; + + return 0; +} + static DBusHandlerResult enable(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -776,15 +794,8 @@ static DBusHandlerResult enable(DBusConnection *conn, if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; - /* Add the service record */ - ns->record_id = add_server_record(ns); - if (!ns->record_id) { - error("Unable to register the server(0x%x) service record", ns->id); - return err_failed(conn, msg, "Unable to register the service record"); - } - - err = l2cap_listen(ns); - if (err < 0) + /* Add the service record and listen l2cap */ + if ((err = record_and_listen(ns)) < 0) return err_failed(conn, msg, strerror(-err)); store_property(&ns->src, ns->id, "enabled", "1"); @@ -1174,10 +1185,15 @@ int server_register_from_file(DBusConnection *conn, const char *path, ns->range = textfile_get(filename, "address_range"); ns->iface = textfile_get(filename, "routing"); - /* FIXME: Missing enabled the server(if applied) */ - info("Registered server path:%s", path); + str = textfile_get(filename, "enabled"); + if (str) { + if (strcmp("1", str) == 0) + record_and_listen(ns); + g_free(str); + } + return 0; } @@ -1228,3 +1244,26 @@ int server_remove_stored(DBusConnection *conn, const char *path) return remove(filename); } + +int server_find_data(DBusConnection *conn, + const char *path, const char *pattern) +{ + struct network_server *ns; + + if (!dbus_connection_get_object_path_data(conn, path, (void *) &ns)) + return -1; + + if (strcasecmp(pattern, ns->name) == 0) + return 0; + + if (strcasecmp(pattern, ns->iface) == 0) + return 0; + + if (strcasecmp(pattern, bnep_name(ns->id)) == 0) + return 0; + + if (bnep_service_id(pattern) == ns->id) + return 0; + + return -1; +} -- cgit From de900f387d63bc74bebedbe52f158e7ec64129d5 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 8 May 2007 14:42:02 +0000 Subject: Fix bug on FindServer and add missing headers. --- network/server.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 0c22a67d..a3b1c068 100644 --- a/network/server.c +++ b/network/server.c @@ -1249,17 +1249,19 @@ int server_find_data(DBusConnection *conn, const char *path, const char *pattern) { struct network_server *ns; + const char *uuid; if (!dbus_connection_get_object_path_data(conn, path, (void *) &ns)) return -1; - if (strcasecmp(pattern, ns->name) == 0) + if (ns->name && strcasecmp(pattern, ns->name) == 0) return 0; - if (strcasecmp(pattern, ns->iface) == 0) + if (ns->iface && strcasecmp(pattern, ns->iface) == 0) return 0; - if (strcasecmp(pattern, bnep_name(ns->id)) == 0) + uuid = bnep_name(ns->id); + if (uuid && strcasecmp(pattern, uuid) == 0) return 0; if (bnep_service_id(pattern) == ns->id) -- cgit From a0d73b7c7ce83bdd633aca429897a89ac7667490 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 9 May 2007 14:31:27 +0000 Subject: Switch to using generic dbus framework method dispatching --- network/server.c | 102 ++++++++++++++++++++++++------------------------------- 1 file changed, 45 insertions(+), 57 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index a3b1c068..077c63b9 100644 --- a/network/server.c +++ b/network/server.c @@ -1019,50 +1019,6 @@ static DBusHandlerResult get_info(DBusConnection *conn, return send_message_and_unref(conn, reply); } -static DBusHandlerResult server_message(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - const char *iface, *member; - - iface = dbus_message_get_interface(msg); - member = dbus_message_get_member(msg); - - if (strcmp(NETWORK_SERVER_INTERFACE, iface)) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - if (strcmp(member, "GetUUID") == 0) - return get_uuid(conn, msg, data); - - if (strcmp(member, "Enable") == 0) - return enable(conn, msg, data); - - if (strcmp(member, "Disable") == 0) - return disable(conn, msg, data); - - if (strcmp(member, "SetName") == 0) - return set_name(conn, msg, data); - - if (strcmp(member, "GetName") == 0) - return get_name(conn, msg, data); - - if (strcmp(member, "SetAddressRange") == 0) - return set_address_range(conn, msg, data); - - if (strcmp(member, "SetRouting") == 0) - return set_routing(conn, msg, data); - - if (strcmp(member, "SetSecurity") == 0) - return set_security(conn, msg, data); - - if (strcmp(member, "GetSecurity") == 0) - return get_security(conn, msg, data); - - if (strcmp(member, "GetInfo") == 0) - return get_info(conn, msg, data); - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - static void server_free(struct network_server *ns) { if (!ns) @@ -1104,10 +1060,24 @@ static void server_unregister(DBusConnection *conn, void *data) server_free(ns); } -/* Virtual table to handle server object path hierarchy */ -static const DBusObjectPathVTable server_table = { - .message_function = server_message, - .unregister_function = server_unregister, +static DBusMethodVTable server_methods[] = { + { "GetUUID", get_uuid, "", "s" }, + { "Enable", enable, "", "" }, + { "Disable", disable, "", "" }, + { "SetName", set_name, "s", "" }, + { "GetName", get_name, "", "s" }, + { "SetAddressRange", set_address_range, "ss", "" }, + { "SetRouting", set_routing, "s", "" }, + { "SetSecurity", set_security, "b", "" }, + { "GetSecurity", get_security, "", "b" }, + { "GetInfo", get_info, "", "{sv}" }, + { NULL, NULL, NULL, NULL } +}; + +static DBusSignalVTable server_signals[] = { + { "Enabled", "" }, + { "Disabled", "" }, + { NULL, NULL } }; int server_register(DBusConnection *conn, const char *path, @@ -1123,14 +1093,23 @@ int server_register(DBusConnection *conn, const char *path, ns = g_new0(struct network_server, 1); - /* Register path */ - if (!dbus_connection_register_object_path(conn, path, - &server_table, ns)) { + if (!dbus_connection_create_object_path(conn, path, ns, + server_unregister)) { error("D-Bus failed to register %s path", path); server_free(ns); return -1; } + if (!dbus_connection_register_interface(conn, path, + NETWORK_SERVER_INTERFACE, + server_methods, + server_signals, NULL)) { + error("D-Bus failed to register %s interface", + NETWORK_SERVER_INTERFACE); + dbus_connection_destroy_object_path(conn, path); + return -1; + } + /* Setting a default name */ if (id == BNEP_SVC_NAP) ns->name = g_strdup("BlueZ NAP service"); @@ -1155,14 +1134,23 @@ int server_register_from_file(DBusConnection *conn, const char *path, ns = g_new0(struct network_server, 1); - /* Register path */ - if (!dbus_connection_register_object_path(conn, path, - &server_table, ns)) { + if (!dbus_connection_create_object_path(conn, path, ns, + server_unregister)) { error("D-Bus failed to register %s path", path); server_free(ns); return -1; } + if (!dbus_connection_register_interface(conn, path, + NETWORK_SERVER_INTERFACE, + server_methods, + server_signals, NULL)) { + error("D-Bus failed to register %s interface", + NETWORK_SERVER_INTERFACE); + dbus_connection_destroy_object_path(conn, path); + return -1; + } + bacpy(&ns->src, src); ns->path = g_strdup(path); ns->id = id; @@ -1203,7 +1191,7 @@ int server_store(DBusConnection *conn, const char *path) char filename[PATH_MAX + 1]; char addr[18]; - if (!dbus_connection_get_object_path_data(conn, path, (void *) &ns)) + if (!dbus_connection_get_object_user_data(conn, path, (void *) &ns)) return -ENOENT; ba2str(&ns->src, addr); @@ -1233,7 +1221,7 @@ int server_remove_stored(DBusConnection *conn, const char *path) char filename[PATH_MAX + 1]; char addr[18]; - if (!dbus_connection_get_object_path_data(conn, path, (void *) &ns)) + if (!dbus_connection_get_object_user_data(conn, path, (void *) &ns)) return -ENOENT; ba2str(&ns->src, addr); @@ -1251,7 +1239,7 @@ int server_find_data(DBusConnection *conn, struct network_server *ns; const char *uuid; - if (!dbus_connection_get_object_path_data(conn, path, (void *) &ns)) + if (!dbus_connection_get_object_user_data(conn, path, (void *) &ns)) return -1; if (ns->name && strcasecmp(pattern, ns->name) == 0) -- cgit From bec9d1838bc0bf9e8ee21f452b6e0431a3abe0bf Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 9 May 2007 19:59:18 +0000 Subject: Use dbus_connection_emit_signal to emit signals. --- network/server.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 077c63b9..8abbc592 100644 --- a/network/server.c +++ b/network/server.c @@ -773,7 +773,7 @@ static DBusHandlerResult enable(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_server *ns = data; - DBusMessage *reply, *signal; + DBusMessage *reply; int err; if (ns->io) @@ -800,10 +800,8 @@ static DBusHandlerResult enable(DBusConnection *conn, store_property(&ns->src, ns->id, "enabled", "1"); - signal = dbus_message_new_signal(ns->path, - NETWORK_SERVER_INTERFACE, "Enabled"); - - send_message_and_unref(conn, signal); + dbus_connection_emit_signal(conn, ns->path, NETWORK_SERVER_INTERFACE, + "Enabled", DBUS_TYPE_INVALID); return send_message_and_unref(conn, reply); } @@ -812,7 +810,7 @@ static DBusHandlerResult disable(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_server *ns = data; - DBusMessage *reply, *signal; + DBusMessage *reply; reply = dbus_message_new_method_return(msg); if (!reply) @@ -823,7 +821,7 @@ static DBusHandlerResult disable(DBusConnection *conn, /* Remove the service record */ if (ns->record_id) { - remove_server_record(conn, ns->record_id); + remove_server_record(conn, ns->record_id); ns->record_id = 0; } @@ -833,10 +831,8 @@ static DBusHandlerResult disable(DBusConnection *conn, store_property(&ns->src, ns->id, "enabled", "0"); - signal = dbus_message_new_signal(ns->path, - NETWORK_SERVER_INTERFACE, "Disabled"); - - send_message_and_unref(conn, signal); + dbus_connection_emit_signal(conn, ns->path, NETWORK_SERVER_INTERFACE, + "Disabled", DBUS_TYPE_INVALID); return send_message_and_unref(conn, reply); } -- cgit From 3a653f915b0e7de28e111665ba40b69ae6d6a235 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 20 Jun 2007 20:23:35 +0000 Subject: Remove CreateServer and RemoveServer, servers are always create. --- network/server.c | 104 ++++++++++++++++++++++++++----------------------------- 1 file changed, 50 insertions(+), 54 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 8abbc592..22ddda8d 100644 --- a/network/server.c +++ b/network/server.c @@ -59,11 +59,13 @@ #include "manager.h" #include "server.h" +static GIOChannel *bnep_io; + /* Pending Authorization */ struct pending_auth { - char *addr; /* Bluetooth Address */ - GIOChannel *io; /* BNEP connection setup io channel */ - int attempts; /* BNEP setup conn requests counter */ + char *addr; /* Bluetooth Address */ + GIOChannel *io; /* BNEP connection setup io channel */ + int attempts; /* BNEP setup conn requests counter */ }; /* Main server structure */ @@ -72,12 +74,12 @@ struct network_server { char *iface; /* Routing interface */ char *name; /* Server service name */ char *range; /* IP Address range */ - char *path; /* D-Bus path */ - dbus_bool_t secure; + char *path; /* D-Bus path */ + gboolean enable; /* Enable flag*/ + gboolean secure; /* Security flag*/ uint32_t record_id; /* Service record id */ uint16_t id; /* Service class identifier */ - GIOChannel *io; /* GIOChannel when listening */ - DBusConnection *conn; /* D-Bus connection */ + DBusConnection *conn; /* D-Bus connection */ struct pending_auth *pauth; /* Pending incomming connection/authorization */ }; @@ -92,8 +94,10 @@ static int store_property(bdaddr_t *src, uint16_t id, ba2str(src, addr); if (id == BNEP_SVC_NAP) create_name(filename, PATH_MAX, STORAGEDIR, addr, "nap"); - else + 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); } @@ -380,7 +384,9 @@ static int authorize_connection(struct network_server *ns) static gboolean connect_setup_event(GIOChannel *chan, GIOCondition cond, gpointer data) { - struct network_server *ns = data; + DBusConnection *conn = data; + struct network_server *ns; + char path[MAX_PATH_LENGTH]; struct bnep_setup_conn_req *req; unsigned char pkt[BNEP_MTU]; gsize n; @@ -437,7 +443,10 @@ static gboolean connect_setup_event(GIOChannel *chan, /* Getting source service: considering 2 bytes size */ role = ntohs(bt_get_unaligned((uint16_t *) pservice)); - if (role != BNEP_SVC_PANU) { + snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/%s", bnep_name(role)); + dbus_connection_get_object_user_data(conn, path, (void *) &ns); + + if (ns == NULL || ns->enable == FALSE) { response = BNEP_CONN_INVALID_SRC; goto reply; } @@ -532,7 +541,7 @@ static gboolean connect_event(GIOChannel *chan, return TRUE; } -static int l2cap_listen(struct network_server *ns) +int server_init(DBusConnection *conn, gboolean secure) { struct l2cap_options l2o; struct sockaddr_l2 l2a; @@ -578,7 +587,7 @@ static int l2cap_listen(struct network_server *ns) } /* Set link mode */ - lm = (ns->secure ? L2CAP_LM_SECURE : 0); + lm = (secure ? L2CAP_LM_SECURE : 0); if (lm && setsockopt(sk, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0) { err = errno; error("Failed to set link mode. %s(%d)", @@ -592,11 +601,11 @@ static int l2cap_listen(struct network_server *ns) goto fail; } - ns->io = g_io_channel_unix_new(sk); - g_io_channel_set_close_on_unref(ns->io, FALSE); + bnep_io = g_io_channel_unix_new(sk); + g_io_channel_set_close_on_unref(bnep_io, FALSE); - g_io_add_watch(ns->io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - connect_event, ns); + g_io_add_watch(bnep_io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + connect_event, conn); return 0; fail: @@ -762,8 +771,7 @@ static int record_and_listen(struct network_server *ns) return -EIO; } - err = l2cap_listen(ns); - if (err < 0) + if (bnep_io == NULL && (err = server_init(ns->conn, ns->secure)) < 0) return -err; return 0; @@ -776,7 +784,7 @@ static DBusHandlerResult enable(DBusConnection *conn, DBusMessage *reply; int err; - if (ns->io) + if (ns->enable) return err_already_exists(conn, msg, "Server already enabled"); if (bacmp(&ns->src, BDADDR_ANY) == 0) { @@ -816,7 +824,7 @@ static DBusHandlerResult disable(DBusConnection *conn, if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; - if (!ns->io) + if (!ns->enable) return err_failed(conn, msg, "Not enabled"); /* Remove the service record */ @@ -825,9 +833,7 @@ static DBusHandlerResult disable(DBusConnection *conn, ns->record_id = 0; } - g_io_channel_close(ns->io); - g_io_channel_unref(ns->io); - ns->io = NULL; + ns->enable = FALSE; store_property(&ns->src, ns->id, "enabled", "0"); @@ -865,7 +871,7 @@ static DBusHandlerResult set_name(DBusConnection *conn, g_free(ns->name); ns->name = g_strdup(name); - if (ns->io) { + if (ns->enable) { if (update_server_record(ns) < 0) { dbus_message_unref(reply); return err_failed(conn, msg, @@ -873,6 +879,8 @@ static DBusHandlerResult set_name(DBusConnection *conn, } } + store_property(&ns->src, ns->id, "name", ns->name); + return send_message_and_unref(conn, reply); } @@ -955,7 +963,7 @@ static DBusHandlerResult set_security(DBusConnection *conn, } ns->secure = secure; - if (ns->io) { + if (ns->enable) { if (update_server_record(ns) < 0) { dbus_message_unref(reply); return err_failed(conn, msg, @@ -963,6 +971,8 @@ static DBusHandlerResult set_security(DBusConnection *conn, } } + store_property(&ns->src, ns->id, "secure", "1"); + return send_message_and_unref(conn, reply); } @@ -1039,11 +1049,6 @@ static void server_free(struct network_server *ns) if (ns->conn) dbus_connection_unref(ns->conn); - if (ns->io) { - g_io_channel_close(ns->io); - g_io_channel_unref(ns->io); - } - g_free(ns); } @@ -1054,6 +1059,12 @@ static void server_unregister(DBusConnection *conn, void *data) info("Unregistered server path:%s", ns->path); server_free(ns); + + if (bnep_io != NULL) { + g_io_channel_close(bnep_io); + g_io_channel_unref(bnep_io); + bnep_io = NULL; + } } static DBusMethodVTable server_methods[] = { @@ -1081,10 +1092,7 @@ int server_register(DBusConnection *conn, const char *path, { struct network_server *ns; - if (!conn) - return -EINVAL; - - if (!path) + if (!conn || !path) return -EINVAL; ns = g_new0(struct network_server, 1); @@ -1109,8 +1117,10 @@ int server_register(DBusConnection *conn, const char *path, /* Setting a default name */ if (id == BNEP_SVC_NAP) ns->name = g_strdup("BlueZ NAP service"); - else + else if (id == BNEP_SVC_GN) ns->name = g_strdup("BlueZ GN service"); + else + ns->name = g_strdup("BlueZ PANU service"); ns->path = g_strdup(path); ns->id = id; @@ -1193,8 +1203,10 @@ int server_store(DBusConnection *conn, const char *path) ba2str(&ns->src, addr); if (ns->id == BNEP_SVC_NAP) create_name(filename, PATH_MAX, STORAGEDIR, addr, "nap"); - else + 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); @@ -1208,25 +1220,9 @@ int server_store(DBusConnection *conn, const char *path) textfile_put(filename, "secure", ns->secure ? "1": "0"); - return 0; -} + textfile_put(filename, "enabled", ns->enable ? "1": "0"); -int server_remove_stored(DBusConnection *conn, const char *path) -{ - struct network_server *ns; - char filename[PATH_MAX + 1]; - char addr[18]; - - if (!dbus_connection_get_object_user_data(conn, path, (void *) &ns)) - return -ENOENT; - - ba2str(&ns->src, addr); - if (ns->id == BNEP_SVC_NAP) - create_name(filename, PATH_MAX, STORAGEDIR, addr, "nap"); - else - create_name(filename, PATH_MAX, STORAGEDIR, addr, "gn"); - - return remove(filename); + return 0; } int server_find_data(DBusConnection *conn, -- cgit From 1e324b3b2e7963eea7509998aaa4fb3fa470979b Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 24 Aug 2007 20:25:51 +0000 Subject: network: fixed seg fault --- network/server.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 22ddda8d..3d17fcd0 100644 --- a/network/server.c +++ b/network/server.c @@ -384,9 +384,7 @@ static int authorize_connection(struct network_server *ns) static gboolean connect_setup_event(GIOChannel *chan, GIOCondition cond, gpointer data) { - DBusConnection *conn = data; - struct network_server *ns; - char path[MAX_PATH_LENGTH]; + struct network_server *ns = data; struct bnep_setup_conn_req *req; unsigned char pkt[BNEP_MTU]; gsize n; @@ -443,14 +441,6 @@ static gboolean connect_setup_event(GIOChannel *chan, /* Getting source service: considering 2 bytes size */ role = ntohs(bt_get_unaligned((uint16_t *) pservice)); - snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/%s", bnep_name(role)); - dbus_connection_get_object_user_data(conn, path, (void *) &ns); - - if (ns == NULL || ns->enable == FALSE) { - response = BNEP_CONN_INVALID_SRC; - goto reply; - } - /* * FIXME: Check if the connection already exists. Check if the * BNEP SPEC allows return "connection not allowed" for this case -- cgit From b439d4cb2cd66a2ffee1a7aa86c677a056c61a69 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 24 Aug 2007 21:14:41 +0000 Subject: network: fixed wrong pointer reference --- network/server.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 3d17fcd0..d1ebe3ee 100644 --- a/network/server.c +++ b/network/server.c @@ -59,7 +59,7 @@ #include "manager.h" #include "server.h" -static GIOChannel *bnep_io; +static GIOChannel *bnep_io = NULL; /* Pending Authorization */ struct pending_auth { @@ -531,7 +531,7 @@ static gboolean connect_event(GIOChannel *chan, return TRUE; } -int server_init(DBusConnection *conn, gboolean secure) +int server_init(struct network_server *ns) { struct l2cap_options l2o; struct sockaddr_l2 l2a; @@ -577,7 +577,7 @@ int server_init(DBusConnection *conn, gboolean secure) } /* Set link mode */ - lm = (secure ? L2CAP_LM_SECURE : 0); + lm = (ns->secure ? L2CAP_LM_SECURE : 0); if (lm && setsockopt(sk, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0) { err = errno; error("Failed to set link mode. %s(%d)", @@ -595,7 +595,7 @@ int server_init(DBusConnection *conn, gboolean secure) g_io_channel_set_close_on_unref(bnep_io, FALSE); g_io_add_watch(bnep_io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - connect_event, conn); + connect_event, ns); return 0; fail: @@ -761,7 +761,7 @@ static int record_and_listen(struct network_server *ns) return -EIO; } - if (bnep_io == NULL && (err = server_init(ns->conn, ns->secure)) < 0) + if (bnep_io == NULL && (err = server_init(ns)) < 0) return -err; return 0; -- cgit From 7defeed3b398d5ca874bc8e3e2fbda099b47c288 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 24 Aug 2007 21:51:52 +0000 Subject: network: fixed minor memory leak --- network/server.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index d1ebe3ee..5694bd53 100644 --- a/network/server.c +++ b/network/server.c @@ -372,6 +372,7 @@ static int authorize_connection(struct network_server *ns) if (dbus_connection_send_with_reply(ns->conn, msg, &pending, -1) == FALSE) { error("Sending of authorization request failed"); + dbus_message_unref(msg); return -EACCES; } @@ -1130,23 +1131,6 @@ int server_register_from_file(DBusConnection *conn, const char *path, ns = g_new0(struct network_server, 1); - if (!dbus_connection_create_object_path(conn, path, ns, - server_unregister)) { - error("D-Bus failed to register %s path", path); - server_free(ns); - return -1; - } - - if (!dbus_connection_register_interface(conn, path, - NETWORK_SERVER_INTERFACE, - server_methods, - server_signals, NULL)) { - error("D-Bus failed to register %s interface", - NETWORK_SERVER_INTERFACE); - dbus_connection_destroy_object_path(conn, path); - return -1; - } - bacpy(&ns->src, src); ns->path = g_strdup(path); ns->id = id; @@ -1169,8 +1153,6 @@ int server_register_from_file(DBusConnection *conn, const char *path, ns->range = textfile_get(filename, "address_range"); ns->iface = textfile_get(filename, "routing"); - info("Registered server path:%s", path); - str = textfile_get(filename, "enabled"); if (str) { if (strcmp("1", str) == 0) @@ -1178,6 +1160,25 @@ int server_register_from_file(DBusConnection *conn, const char *path, g_free(str); } + if (!dbus_connection_create_object_path(conn, path, ns, + server_unregister)) { + error("D-Bus failed to register %s path", path); + server_free(ns); + return -1; + } + + if (!dbus_connection_register_interface(conn, path, + NETWORK_SERVER_INTERFACE, + server_methods, + server_signals, NULL)) { + error("D-Bus failed to register %s interface", + NETWORK_SERVER_INTERFACE); + dbus_connection_destroy_object_path(conn, path); + return -1; + } + + info("Registered server path:%s", path); + return 0; } -- cgit From b45b4cd6326d86970392cd8d465c5c8fa891b212 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 27 Aug 2007 21:54:25 +0000 Subject: network: fixed Disable - record unregistration --- network/server.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 5694bd53..3fc6900e 100644 --- a/network/server.c +++ b/network/server.c @@ -755,15 +755,20 @@ static int record_and_listen(struct network_server *ns) { int err; + if (bnep_io == NULL && (err = server_init(ns)) < 0) + return -err; + /* Add the service record */ ns->record_id = add_server_record(ns); if (!ns->record_id) { error("Unable to register the server(0x%x) service record", ns->id); + g_io_channel_close(bnep_io); + g_io_channel_unref(bnep_io); + bnep_io = NULL; return -EIO; } - if (bnep_io == NULL && (err = server_init(ns)) < 0) - return -err; + ns->enable = TRUE; return 0; } -- cgit From da10b3ccf28d21e0bfa9ad458a350f64eb47b2be Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Tue, 28 Aug 2007 16:41:50 +0000 Subject: network: allow just one pending authorization at the same time --- network/server.c | 121 +++++++++++++++++++++++++++---------------------------- 1 file changed, 59 insertions(+), 62 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 3fc6900e..7612bd2f 100644 --- a/network/server.c +++ b/network/server.c @@ -59,13 +59,11 @@ #include "manager.h" #include "server.h" -static GIOChannel *bnep_io = NULL; - /* Pending Authorization */ struct pending_auth { char *addr; /* Bluetooth Address */ GIOChannel *io; /* BNEP connection setup io channel */ - int attempts; /* BNEP setup conn requests counter */ + DBusConnection *conn; }; /* Main server structure */ @@ -80,10 +78,11 @@ struct network_server { uint32_t record_id; /* Service record id */ uint16_t id; /* Service class identifier */ DBusConnection *conn; /* D-Bus connection */ - struct pending_auth *pauth; /* Pending incomming connection/authorization */ }; static char netdev[16] = "bnep%d"; +static GIOChannel *bnep_io = NULL; +static struct pending_auth *pending_auth = NULL; static int store_property(bdaddr_t *src, uint16_t id, const char *key, const char *value) @@ -106,12 +105,14 @@ static void pending_auth_free(struct pending_auth *pauth) { if (!pauth) return; + if (pauth->addr) g_free(pauth->addr); if (pauth->io) { g_io_channel_close(pauth->io); g_io_channel_unref(pauth->io); } + dbus_connection_unref(pauth->conn); g_free(pauth); } @@ -257,17 +258,11 @@ static int send_bnep_ctrl_rsp(GIOChannel *chan, uint16_t response) return -gerr; } -static void cancel_authorization(struct network_server *ns) +static void cancel_authorization(DBusConnection *conn, const char *address) { DBusMessage *msg; - const char *paddress; const char *uuid = ""; - if (!ns->pauth) - return; - - paddress = ns->pauth->addr; - msg = dbus_message_new_method_call("org.bluez", "/org/bluez", "org.bluez.Database", "CancelAuthorizationRequest"); @@ -277,11 +272,11 @@ static void cancel_authorization(struct network_server *ns) } dbus_message_append_args(msg, - DBUS_TYPE_STRING, &paddress, + DBUS_TYPE_STRING, &address, DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID); - send_message_and_unref(ns->conn, msg); + send_message_and_unref(conn, msg); } static void authorization_callback(DBusPendingCall *pcall, void *data) @@ -293,20 +288,20 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) uint16_t response; int sk; - if (!ns->pauth) { + if (!pending_auth) { dbus_message_unref(reply); dbus_pending_call_unref(pcall); return; } - sk = g_io_channel_unix_get_fd(ns->pauth->io); + sk = g_io_channel_unix_get_fd(pending_auth->io); dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { error("Access denied: %s", derr.message); if (dbus_error_has_name(&derr, DBUS_ERROR_NO_REPLY)) { debug("Canceling authorization request"); - cancel_authorization(ns); + cancel_authorization(pending_auth->conn, pending_auth->addr); } response = BNEP_CONN_NOT_ALLOWED; dbus_error_free(&derr); @@ -339,10 +334,10 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) /* FIXME: send the D-Bus message to notify the new bnep iface */ failed: - send_bnep_ctrl_rsp(ns->pauth->io, response); + send_bnep_ctrl_rsp(pending_auth->io, response); - pending_auth_free(ns->pauth); - ns->pauth = NULL; + pending_auth_free(pending_auth); + pending_auth = NULL; close(sk); @@ -350,7 +345,8 @@ failed: dbus_pending_call_unref(pcall); } -static int authorize_connection(struct network_server *ns) +static int authorize_connection(DBusConnection *conn, + const char *address, struct network_server *ns) { DBusMessage *msg; DBusPendingCall *pending; @@ -363,14 +359,14 @@ static int authorize_connection(struct network_server *ns) return -ENOMEM; } - debug("Requesting authorization for %s UUID:%s", ns->pauth->addr, uuid); + debug("Requesting authorization for %s UUID:%s", address, uuid); dbus_message_append_args(msg, - DBUS_TYPE_STRING, &ns->pauth->addr, + DBUS_TYPE_STRING, &address, DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID); - if (dbus_connection_send_with_reply(ns->conn, msg, &pending, -1) == FALSE) { + if (dbus_connection_send_with_reply(conn, msg, &pending, -1) == FALSE) { error("Sending of authorization request failed"); dbus_message_unref(msg); return -EACCES; @@ -385,9 +381,10 @@ static int authorize_connection(struct network_server *ns) static gboolean connect_setup_event(GIOChannel *chan, GIOCondition cond, gpointer data) { - struct network_server *ns = data; + struct network_server *ns = NULL; struct bnep_setup_conn_req *req; unsigned char pkt[BNEP_MTU]; + char path[MAX_PATH_LENGTH]; gsize n; GIOError gerr; uint8_t *pservice; @@ -398,7 +395,7 @@ static gboolean connect_setup_event(GIOChannel *chan, if (cond & (G_IO_ERR | G_IO_HUP)) { error("Hangup or error on BNEP socket"); - cancel_authorization(ns); + cancel_authorization(pending_auth->conn, pending_auth->addr); return FALSE; } @@ -417,14 +414,6 @@ static gboolean connect_setup_event(GIOChannel *chan, return FALSE; } - if (++ns->pauth->attempts > 1) { - /* - * Ignore repeated BNEP setup connection request: there - * is a pending authorization request for this device. - */ - return TRUE; - } - /* * FIXME: According to BNEP SPEC the UUID size can be * 2-16 bytes. Currently only 2 bytes size is supported @@ -438,6 +427,14 @@ static gboolean connect_setup_event(GIOChannel *chan, /* Getting destination service: considering 2 bytes size */ role = ntohs(bt_get_unaligned((uint16_t *) pservice)); + snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/%s", bnep_name(role)); + dbus_connection_get_object_user_data(pending_auth->conn, path, (void *) &ns); + + if (ns == NULL || ns->enable == FALSE) { + response = BNEP_CONN_NOT_ALLOWED; + goto reply; + } + pservice += req->uuid_size; /* Getting source service: considering 2 bytes size */ role = ntohs(bt_get_unaligned((uint16_t *) pservice)); @@ -448,10 +445,10 @@ static gboolean connect_setup_event(GIOChannel *chan, */ /* Wait authorization before reply success */ - if (authorize_connection(ns) < 0) { + if (authorize_connection(pending_auth->conn, + pending_auth->addr, ns) < 0) { response = BNEP_CONN_NOT_ALLOWED; goto reply; - } return TRUE; @@ -462,18 +459,16 @@ reply: static void connect_setup_destroy(gpointer data) { - struct network_server *ns = data; - - if (ns->pauth) { - pending_auth_free(ns->pauth); - ns->pauth = NULL; + if (pending_auth) { + pending_auth_free(pending_auth); + pending_auth = NULL; } } static gboolean connect_event(GIOChannel *chan, GIOCondition cond, gpointer data) { - struct network_server *ns = data; + DBusConnection *conn = data; struct sockaddr_l2 addr; socklen_t addrlen; char peer[18]; @@ -501,11 +496,12 @@ static gboolean connect_event(GIOChannel *chan, bacpy(&dst, &addr.l2_bdaddr); psm = btohs(addr.l2_psm); + ba2str(&dst, peer); - /* FIXME: Maybe keep a list of connected devices */ + info("Connection from: %s on PSM %d", peer, psm); - ba2str(&dst, peer); - if (ns->pauth) { + /* Only one authorization at same time */ + if (pending_auth) { GIOChannel *io; error("Rejecting %s(pending authorization)", peer); io = g_io_channel_unix_new(nsk); @@ -515,24 +511,21 @@ static gboolean connect_event(GIOChannel *chan, return TRUE; } - info("Connection from:%s on PSM %d", peer, psm); - - /* Setting the pending incomming connection setup */ - ns->pauth = g_new0(struct pending_auth, 1); - ns->pauth->addr = g_strdup(peer); - ns->pauth->io = g_io_channel_unix_new(nsk); - - g_io_channel_set_close_on_unref(ns->pauth->io, FALSE); + pending_auth = g_new0(struct pending_auth, 1); + pending_auth->addr = g_strdup(peer); + pending_auth->io = g_io_channel_unix_new(nsk); + pending_auth->conn = dbus_connection_ref(conn); + g_io_channel_set_close_on_unref(pending_auth->io, FALSE); /* New watch for BNEP setup */ - g_io_add_watch_full(ns->pauth->io, G_PRIORITY_DEFAULT, - G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - connect_setup_event, ns, &connect_setup_destroy); + g_io_add_watch_full(pending_auth->io, G_PRIORITY_DEFAULT, + G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + connect_setup_event, pending_auth, &connect_setup_destroy); return TRUE; } -int server_init(struct network_server *ns) +static int server_init(DBusConnection *conn) { struct l2cap_options l2o; struct sockaddr_l2 l2a; @@ -577,8 +570,8 @@ int server_init(struct network_server *ns) goto fail; } - /* Set link mode */ - lm = (ns->secure ? L2CAP_LM_SECURE : 0); + /* FIXME: Set link mode - it is applied to all servers */ + lm = 0; if (lm && setsockopt(sk, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0) { err = errno; error("Failed to set link mode. %s(%d)", @@ -594,10 +587,8 @@ int server_init(struct network_server *ns) bnep_io = g_io_channel_unix_new(sk); g_io_channel_set_close_on_unref(bnep_io, FALSE); - g_io_add_watch(bnep_io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - connect_event, ns); - + connect_event, conn); return 0; fail: @@ -755,7 +746,13 @@ static int record_and_listen(struct network_server *ns) { int err; - if (bnep_io == NULL && (err = server_init(ns)) < 0) + /* + * There is one socket to handle the incomming connections. NAP, + * GN and PANU servers share the same PSM. The initial BNEP message + * (setup connection request) contains the destination service + * field that defines which service the source is connecting to. + */ + if (bnep_io == NULL && (err = server_init(ns->conn)) < 0) return -err; /* Add the service record */ -- cgit From 2498466bf77ddc41596c0d20849d3706b1df2e37 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Tue, 28 Aug 2007 19:31:49 +0000 Subject: network: added verification for allowed destination/source roles according to PAN Profile --- network/server.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 7612bd2f..b7806fa8 100644 --- a/network/server.c +++ b/network/server.c @@ -378,6 +378,22 @@ static int authorize_connection(DBusConnection *conn, return 0; } +static int inline chk_role(uint16_t dst_role, uint16_t src_role) +{ + /* Allowed PAN Profile scenarios */ + switch (dst_role) { + case BNEP_SVC_NAP: + case BNEP_SVC_GN: + if (src_role == BNEP_SVC_PANU) + return 0; + break; + case BNEP_SVC_PANU: + return 0; + } + + return -EINVAL; +} + static gboolean connect_setup_event(GIOChannel *chan, GIOCondition cond, gpointer data) { @@ -388,7 +404,7 @@ static gboolean connect_setup_event(GIOChannel *chan, gsize n; GIOError gerr; uint8_t *pservice; - uint16_t role, response; + uint16_t dst_role, src_role, response; if (cond & G_IO_NVAL) return FALSE; @@ -425,9 +441,17 @@ static gboolean connect_setup_event(GIOChannel *chan, pservice = req->service; /* Getting destination service: considering 2 bytes size */ - role = ntohs(bt_get_unaligned((uint16_t *) pservice)); + dst_role = ntohs(bt_get_unaligned((uint16_t *) pservice)); + pservice += req->uuid_size; + /* Getting source service: considering 2 bytes size */ + src_role = ntohs(bt_get_unaligned((uint16_t *) pservice)); - snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/%s", bnep_name(role)); + if (chk_role(src_role, dst_role) < 0) { + response = BNEP_CONN_NOT_ALLOWED; + goto reply; + } + + snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/%s", bnep_name(dst_role)); dbus_connection_get_object_user_data(pending_auth->conn, path, (void *) &ns); if (ns == NULL || ns->enable == FALSE) { @@ -435,9 +459,6 @@ static gboolean connect_setup_event(GIOChannel *chan, goto reply; } - pservice += req->uuid_size; - /* Getting source service: considering 2 bytes size */ - role = ntohs(bt_get_unaligned((uint16_t *) pservice)); /* * FIXME: Check if the connection already exists. Check if the -- cgit From 9c9b10af24ac7b53ef02cecb2b0393cf02b8bd71 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Tue, 28 Aug 2007 22:12:53 +0000 Subject: network: disconnect clients when the server is disabled --- network/server.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index b7806fa8..9dc8eb0b 100644 --- a/network/server.c +++ b/network/server.c @@ -78,6 +78,7 @@ struct network_server { uint32_t record_id; /* Service record id */ uint16_t id; /* Service class identifier */ DBusConnection *conn; /* D-Bus connection */ + GSList *clients; /* Active connections */ }; static char netdev[16] = "bnep%d"; @@ -329,6 +330,8 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) bnep_if_up(devname, TRUE); bnep_if_up("pan0", TRUE); + ns->clients = g_slist_append(ns->clients, g_strdup(pending_auth->addr)); + /* FIXME: Enable routing if applied */ /* FIXME: send the D-Bus message to notify the new bnep iface */ @@ -459,7 +462,6 @@ static gboolean connect_setup_event(GIOChannel *chan, goto reply; } - /* * FIXME: Check if the connection already exists. Check if the * BNEP SPEC allows return "connection not allowed" for this case @@ -828,6 +830,15 @@ static DBusHandlerResult enable(DBusConnection *conn, return send_message_and_unref(conn, reply); } +static void kill_connection(void *data, void *udata) +{ + const char *address = data; + bdaddr_t dst; + + str2ba(address, &dst); + bnep_kill_connection(&dst); +} + static DBusHandlerResult disable(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -849,6 +860,8 @@ static DBusHandlerResult disable(DBusConnection *conn, ns->enable = FALSE; + g_slist_foreach(ns->clients, (GFunc) kill_connection, NULL); + store_property(&ns->src, ns->id, "enabled", "0"); dbus_connection_emit_signal(conn, ns->path, NETWORK_SERVER_INTERFACE, @@ -1063,6 +1076,11 @@ static void server_free(struct network_server *ns) if (ns->conn) dbus_connection_unref(ns->conn); + if (ns->clients) { + g_slist_foreach(ns->clients, (GFunc) g_free, NULL); + g_slist_free(ns->clients); + } + g_free(ns); } -- cgit From da81fb5e8f0c98791b0749fdde0ac8d06fa74cc9 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Tue, 28 Aug 2007 22:45:18 +0000 Subject: network: fixed wrong service record attrs for PANU --- network/server.c | 76 ++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 30 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 9dc8eb0b..4c5658f6 100644 --- a/network/server.c +++ b/network/server.c @@ -149,6 +149,52 @@ static int create_server_record(sdp_buf_t *buf, const char *name, memset(&record, 0, sizeof(sdp_record_t)); + switch (id) { + case BNEP_SVC_NAP: + sdp_uuid16_create(&pan, NAP_SVCLASS_ID); + svclass = sdp_list_append(NULL, &pan); + sdp_set_service_classes(&record, svclass); + + sdp_uuid16_create(&profile[0].uuid, NAP_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(NULL, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_set_info_attr(&record, name, NULL, desc); + + sdp_attr_add_new(&record, SDP_ATTR_NET_ACCESS_TYPE, + SDP_UINT16, &net_access_type); + sdp_attr_add_new(&record, SDP_ATTR_MAX_NET_ACCESSRATE, + SDP_UINT32, &max_net_access_rate); + break; + case BNEP_SVC_GN: + sdp_uuid16_create(&pan, GN_SVCLASS_ID); + svclass = sdp_list_append(NULL, &pan); + sdp_set_service_classes(&record, svclass); + + sdp_uuid16_create(&profile[0].uuid, GN_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(NULL, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_set_info_attr(&record, name, NULL, desc); + break; + case BNEP_SVC_PANU: + sdp_uuid16_create(&pan, PANU_SVCLASS_ID); + svclass = sdp_list_append(NULL, &pan); + sdp_set_service_classes(&record, svclass); + + sdp_uuid16_create(&profile[0].uuid, PANU_PROFILE_ID); + profile[0].version = 0x0100; + pfseq = sdp_list_append(NULL, &profile[0]); + sdp_set_profile_descs(&record, pfseq); + + sdp_set_info_attr(&record, name, NULL, desc); + break; + default: + return -1; + } + sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); sdp_set_browse_groups(&record, root); @@ -194,36 +240,6 @@ static int create_server_record(sdp_buf_t *buf, const char *name, sdp_attr_add_new(&record, SDP_ATTR_SECURITY_DESC, SDP_UINT16, &security_desc); - if (id == BNEP_SVC_NAP) { - sdp_uuid16_create(&pan, NAP_SVCLASS_ID); - svclass = sdp_list_append(NULL, &pan); - sdp_set_service_classes(&record, svclass); - - sdp_uuid16_create(&profile[0].uuid, NAP_PROFILE_ID); - profile[0].version = 0x0100; - pfseq = sdp_list_append(NULL, &profile[0]); - sdp_set_profile_descs(&record, pfseq); - - sdp_set_info_attr(&record, name, NULL, desc); - - sdp_attr_add_new(&record, SDP_ATTR_NET_ACCESS_TYPE, - SDP_UINT16, &net_access_type); - sdp_attr_add_new(&record, SDP_ATTR_MAX_NET_ACCESSRATE, - SDP_UINT32, &max_net_access_rate); - } else { - /* BNEP_SVC_GN */ - sdp_uuid16_create(&pan, GN_SVCLASS_ID); - svclass = sdp_list_append(NULL, &pan); - sdp_set_service_classes(&record, svclass); - - sdp_uuid16_create(&profile[0].uuid, GN_PROFILE_ID); - profile[0].version = 0x0100; - pfseq = sdp_list_append(NULL, &profile[0]); - sdp_set_profile_descs(&record, pfseq); - - sdp_set_info_attr(&record, name, NULL, desc); - } - if (sdp_gen_record_pdu(&record, buf) < 0) ret = -1; else -- cgit From 1dfdcaaccb924c36d6ab8380fb52ea5a9691a872 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 29 Aug 2007 14:18:01 +0000 Subject: network: minor - keep server socket always listenning --- network/server.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 4c5658f6..b8021436 100644 --- a/network/server.c +++ b/network/server.c @@ -798,9 +798,6 @@ static int record_and_listen(struct network_server *ns) ns->record_id = add_server_record(ns); if (!ns->record_id) { error("Unable to register the server(0x%x) service record", ns->id); - g_io_channel_close(bnep_io); - g_io_channel_unref(bnep_io); - bnep_io = NULL; return -EIO; } -- cgit From 176b646a7829d683055d95b5d637a3a5dfdd36c0 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 29 Aug 2007 20:32:05 +0000 Subject: network: server cleanup - added static DBusConnection and server init/exit --- network/server.c | 146 ++++++++++++++++++++++++------------------------------- 1 file changed, 64 insertions(+), 82 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index b8021436..bd19609f 100644 --- a/network/server.c +++ b/network/server.c @@ -63,7 +63,6 @@ struct pending_auth { char *addr; /* Bluetooth Address */ GIOChannel *io; /* BNEP connection setup io channel */ - DBusConnection *conn; }; /* Main server structure */ @@ -77,12 +76,12 @@ struct network_server { gboolean secure; /* Security flag*/ uint32_t record_id; /* Service record id */ uint16_t id; /* Service class identifier */ - DBusConnection *conn; /* D-Bus connection */ GSList *clients; /* Active connections */ }; static char netdev[16] = "bnep%d"; static GIOChannel *bnep_io = NULL; +static DBusConnection *connection = NULL; static struct pending_auth *pending_auth = NULL; static int store_property(bdaddr_t *src, uint16_t id, @@ -113,7 +112,6 @@ static void pending_auth_free(struct pending_auth *pauth) g_io_channel_close(pauth->io); g_io_channel_unref(pauth->io); } - dbus_connection_unref(pauth->conn); g_free(pauth); } @@ -275,7 +273,7 @@ static int send_bnep_ctrl_rsp(GIOChannel *chan, uint16_t response) return -gerr; } -static void cancel_authorization(DBusConnection *conn, const char *address) +static void cancel_authorization(const char *address) { DBusMessage *msg; const char *uuid = ""; @@ -293,7 +291,7 @@ static void cancel_authorization(DBusConnection *conn, const char *address) DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID); - send_message_and_unref(conn, msg); + send_message_and_unref(connection, msg); } static void authorization_callback(DBusPendingCall *pcall, void *data) @@ -318,7 +316,7 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) error("Access denied: %s", derr.message); if (dbus_error_has_name(&derr, DBUS_ERROR_NO_REPLY)) { debug("Canceling authorization request"); - cancel_authorization(pending_auth->conn, pending_auth->addr); + cancel_authorization(pending_auth->addr); } response = BNEP_CONN_NOT_ALLOWED; dbus_error_free(&derr); @@ -364,8 +362,7 @@ failed: dbus_pending_call_unref(pcall); } -static int authorize_connection(DBusConnection *conn, - const char *address, struct network_server *ns) +static int authorize_connection(const char *address, struct network_server *ns) { DBusMessage *msg; DBusPendingCall *pending; @@ -385,7 +382,8 @@ static int authorize_connection(DBusConnection *conn, DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID); - if (dbus_connection_send_with_reply(conn, msg, &pending, -1) == FALSE) { + if (dbus_connection_send_with_reply(connection, + msg, &pending, -1) == FALSE) { error("Sending of authorization request failed"); dbus_message_unref(msg); return -EACCES; @@ -430,7 +428,7 @@ static gboolean connect_setup_event(GIOChannel *chan, if (cond & (G_IO_ERR | G_IO_HUP)) { error("Hangup or error on BNEP socket"); - cancel_authorization(pending_auth->conn, pending_auth->addr); + cancel_authorization(pending_auth->addr); return FALSE; } @@ -471,7 +469,7 @@ static gboolean connect_setup_event(GIOChannel *chan, } snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/%s", bnep_name(dst_role)); - dbus_connection_get_object_user_data(pending_auth->conn, path, (void *) &ns); + dbus_connection_get_object_user_data(connection, path, (void *) &ns); if (ns == NULL || ns->enable == FALSE) { response = BNEP_CONN_NOT_ALLOWED; @@ -484,8 +482,7 @@ static gboolean connect_setup_event(GIOChannel *chan, */ /* Wait authorization before reply success */ - if (authorize_connection(pending_auth->conn, - pending_auth->addr, ns) < 0) { + if (authorize_connection(pending_auth->addr, ns) < 0) { response = BNEP_CONN_NOT_ALLOWED; goto reply; } @@ -507,7 +504,6 @@ static void connect_setup_destroy(gpointer data) static gboolean connect_event(GIOChannel *chan, GIOCondition cond, gpointer data) { - DBusConnection *conn = data; struct sockaddr_l2 addr; socklen_t addrlen; char peer[18]; @@ -553,7 +549,6 @@ static gboolean connect_event(GIOChannel *chan, pending_auth = g_new0(struct pending_auth, 1); pending_auth->addr = g_strdup(peer); pending_auth->io = g_io_channel_unix_new(nsk); - pending_auth->conn = dbus_connection_ref(conn); g_io_channel_set_close_on_unref(pending_auth->io, FALSE); /* New watch for BNEP setup */ @@ -564,7 +559,7 @@ static gboolean connect_event(GIOChannel *chan, return TRUE; } -static int server_init(DBusConnection *conn) +int server_init(DBusConnection *conn) { struct l2cap_options l2o; struct sockaddr_l2 l2a; @@ -624,10 +619,12 @@ static int server_init(DBusConnection *conn) goto fail; } + connection = dbus_connection_ref(conn); + bnep_io = g_io_channel_unix_new(sk); g_io_channel_set_close_on_unref(bnep_io, FALSE); g_io_add_watch(bnep_io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - connect_event, conn); + connect_event, NULL); return 0; fail: @@ -636,6 +633,18 @@ fail: return -err; } +void server_exit() +{ + if (bnep_io != NULL) { + g_io_channel_close(bnep_io); + g_io_channel_unref(bnep_io); + bnep_io = NULL; + } + + dbus_connection_unref(connection); + connection = NULL; +} + static uint32_t add_server_record(struct network_server *ns) { DBusMessage *msg, *reply; @@ -660,7 +669,8 @@ static uint32_t add_server_record(struct network_server *ns) &buf.data, buf.data_size, DBUS_TYPE_INVALID); dbus_error_init(&derr); - reply = dbus_connection_send_with_reply_and_block(ns->conn, msg, -1, &derr); + reply = dbus_connection_send_with_reply_and_block(connection, + msg, -1, &derr); free(buf.data); dbus_message_unref(msg); @@ -713,7 +723,8 @@ static int update_server_record(struct network_server *ns) &buf.data, buf.data_size, DBUS_TYPE_INVALID); dbus_error_init(&derr); - reply = dbus_connection_send_with_reply_and_block(ns->conn, msg, -1, &derr); + reply = dbus_connection_send_with_reply_and_block(connection, + msg, -1, &derr); free(buf.data); dbus_message_unref(msg); @@ -729,7 +740,7 @@ static int update_server_record(struct network_server *ns) return 0; } -static int remove_server_record(DBusConnection *conn, uint32_t rec_id) +static int remove_server_record(uint32_t rec_id) { DBusMessage *msg, *reply; DBusError derr; @@ -746,7 +757,8 @@ static int remove_server_record(DBusConnection *conn, uint32_t rec_id) DBUS_TYPE_INVALID); dbus_error_init(&derr); - reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, &derr); + reply = dbus_connection_send_with_reply_and_block(connection, + msg, -1, &derr); dbus_message_unref(msg); @@ -781,37 +793,11 @@ static DBusHandlerResult get_uuid(DBusConnection *conn, return send_message_and_unref(conn, reply); } -static int record_and_listen(struct network_server *ns) -{ - int err; - - /* - * There is one socket to handle the incomming connections. NAP, - * GN and PANU servers share the same PSM. The initial BNEP message - * (setup connection request) contains the destination service - * field that defines which service the source is connecting to. - */ - if (bnep_io == NULL && (err = server_init(ns->conn)) < 0) - return -err; - - /* Add the service record */ - ns->record_id = add_server_record(ns); - if (!ns->record_id) { - error("Unable to register the server(0x%x) service record", ns->id); - return -EIO; - } - - ns->enable = TRUE; - - return 0; -} - static DBusHandlerResult enable(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_server *ns = data; DBusMessage *reply; - int err; if (ns->enable) return err_already_exists(conn, msg, "Server already enabled"); @@ -824,16 +810,22 @@ static DBusHandlerResult enable(DBusConnection *conn, return err_failed(conn, msg, "Adapter not available"); /* Store the server info */ - server_store(conn, ns->path); + server_store(ns->path); } reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; - /* Add the service record and listen l2cap */ - if ((err = record_and_listen(ns)) < 0) - return err_failed(conn, msg, strerror(-err)); + /* Add the service record */ + ns->record_id = add_server_record(ns); + if (!ns->record_id) { + dbus_message_unref(reply); + return err_failed(conn, msg, + "service record registration failed"); + } + + ns->enable = TRUE; store_property(&ns->src, ns->id, "enabled", "1"); @@ -867,7 +859,7 @@ static DBusHandlerResult disable(DBusConnection *conn, /* Remove the service record */ if (ns->record_id) { - remove_server_record(conn, ns->record_id); + remove_server_record(ns->record_id); ns->record_id = 0; } @@ -1072,7 +1064,7 @@ static void server_free(struct network_server *ns) /* FIXME: Missing release/free all bnepX interfaces */ if (ns->record_id) - remove_server_record(ns->conn, ns->record_id); + remove_server_record(ns->record_id); if (ns->iface) g_free(ns->iface); @@ -1086,9 +1078,6 @@ static void server_free(struct network_server *ns) if (ns->path) g_free(ns->path); - if (ns->conn) - dbus_connection_unref(ns->conn); - if (ns->clients) { g_slist_foreach(ns->clients, (GFunc) g_free, NULL); g_slist_free(ns->clients); @@ -1104,12 +1093,6 @@ static void server_unregister(DBusConnection *conn, void *data) info("Unregistered server path:%s", ns->path); server_free(ns); - - if (bnep_io != NULL) { - g_io_channel_close(bnep_io); - g_io_channel_unref(bnep_io); - bnep_io = NULL; - } } static DBusMethodVTable server_methods[] = { @@ -1132,30 +1115,29 @@ static DBusSignalVTable server_signals[] = { { NULL, NULL } }; -int server_register(DBusConnection *conn, const char *path, - bdaddr_t *src, uint16_t id) +int server_register(const char *path, bdaddr_t *src, uint16_t id) { struct network_server *ns; - if (!conn || !path) + if (!path) return -EINVAL; ns = g_new0(struct network_server, 1); - if (!dbus_connection_create_object_path(conn, path, ns, + if (!dbus_connection_create_object_path(connection, path, ns, server_unregister)) { error("D-Bus failed to register %s path", path); server_free(ns); return -1; } - if (!dbus_connection_register_interface(conn, path, + if (!dbus_connection_register_interface(connection, path, NETWORK_SERVER_INTERFACE, server_methods, server_signals, NULL)) { error("D-Bus failed to register %s interface", NETWORK_SERVER_INTERFACE); - dbus_connection_destroy_object_path(conn, path); + dbus_connection_destroy_object_path(connection, path); return -1; } @@ -1169,7 +1151,6 @@ int server_register(DBusConnection *conn, const char *path, ns->path = g_strdup(path); ns->id = id; - ns->conn = dbus_connection_ref(conn); bacpy(&ns->src, src); info("Registered server path:%s", path); @@ -1177,8 +1158,8 @@ int server_register(DBusConnection *conn, const char *path, return 0; } -int server_register_from_file(DBusConnection *conn, const char *path, - const bdaddr_t *src, uint16_t id, const char *filename) +int server_register_from_file(const char *path, const bdaddr_t *src, + uint16_t id, const char *filename) { struct network_server *ns; char *str; @@ -1188,7 +1169,6 @@ int server_register_from_file(DBusConnection *conn, const char *path, bacpy(&ns->src, src); ns->path = g_strdup(path); ns->id = id; - ns->conn = dbus_connection_ref(conn); ns->name = textfile_get(filename, "name"); if (!ns->name) { /* Name is mandatory */ @@ -1209,25 +1189,27 @@ int server_register_from_file(DBusConnection *conn, const char *path, str = textfile_get(filename, "enabled"); if (str) { - if (strcmp("1", str) == 0) - record_and_listen(ns); + if (strcmp("1", str) == 0) { + ns->record_id = add_server_record(ns); + ns->enable = TRUE; + } g_free(str); } - if (!dbus_connection_create_object_path(conn, path, ns, + if (!dbus_connection_create_object_path(connection, path, ns, server_unregister)) { error("D-Bus failed to register %s path", path); server_free(ns); return -1; } - if (!dbus_connection_register_interface(conn, path, + if (!dbus_connection_register_interface(connection, path, NETWORK_SERVER_INTERFACE, server_methods, server_signals, NULL)) { error("D-Bus failed to register %s interface", NETWORK_SERVER_INTERFACE); - dbus_connection_destroy_object_path(conn, path); + dbus_connection_destroy_object_path(connection, path); return -1; } @@ -1236,13 +1218,14 @@ int server_register_from_file(DBusConnection *conn, const char *path, return 0; } -int server_store(DBusConnection *conn, const char *path) +int server_store(const char *path) { struct network_server *ns; char filename[PATH_MAX + 1]; char addr[18]; - if (!dbus_connection_get_object_user_data(conn, path, (void *) &ns)) + if (!dbus_connection_get_object_user_data(connection, + path, (void *) &ns)) return -ENOENT; ba2str(&ns->src, addr); @@ -1270,13 +1253,12 @@ int server_store(DBusConnection *conn, const char *path) return 0; } -int server_find_data(DBusConnection *conn, - const char *path, const char *pattern) +int server_find_data(const char *path, const char *pattern) { struct network_server *ns; const char *uuid; - if (!dbus_connection_get_object_user_data(conn, path, (void *) &ns)) + if (!dbus_connection_get_object_user_data(connection, path, (void *) &ns)) return -1; if (ns->name && strcasecmp(pattern, ns->name) == 0) -- cgit From e2b42635514e559b765a7cd763717995d237e7b9 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 29 Aug 2007 21:22:21 +0000 Subject: network: additional src and dst role verification --- network/server.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index bd19609f..5a441ee6 100644 --- a/network/server.c +++ b/network/server.c @@ -395,7 +395,7 @@ static int authorize_connection(const char *address, struct network_server *ns) return 0; } -static int inline chk_role(uint16_t dst_role, uint16_t src_role) +static uint16_t inline chk_role(uint16_t dst_role, uint16_t src_role) { /* Allowed PAN Profile scenarios */ switch (dst_role) { @@ -403,12 +403,17 @@ static int inline chk_role(uint16_t dst_role, uint16_t src_role) case BNEP_SVC_GN: if (src_role == BNEP_SVC_PANU) return 0; - break; + return BNEP_CONN_INVALID_SRC; case BNEP_SVC_PANU: - return 0; + if (src_role == BNEP_SVC_PANU || + src_role == BNEP_SVC_GN || + src_role == BNEP_SVC_NAP) + return 0; + + return BNEP_CONN_INVALID_SRC; } - return -EINVAL; + return BNEP_CONN_INVALID_DST; } static gboolean connect_setup_event(GIOChannel *chan, @@ -463,10 +468,9 @@ static gboolean connect_setup_event(GIOChannel *chan, /* Getting source service: considering 2 bytes size */ src_role = ntohs(bt_get_unaligned((uint16_t *) pservice)); - if (chk_role(src_role, dst_role) < 0) { - response = BNEP_CONN_NOT_ALLOWED; + response = chk_role(src_role, dst_role); + if (response) goto reply; - } snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/%s", bnep_name(dst_role)); dbus_connection_get_object_user_data(connection, path, (void *) &ns); -- cgit From d039784990775ec85aa51f080b2db9feb0604a35 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 30 Aug 2007 14:14:53 +0000 Subject: network: more robust bnep setup conn msg validation --- network/server.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 5a441ee6..672fd555 100644 --- a/network/server.c +++ b/network/server.c @@ -423,10 +423,10 @@ static gboolean connect_setup_event(GIOChannel *chan, struct bnep_setup_conn_req *req; unsigned char pkt[BNEP_MTU]; char path[MAX_PATH_LENGTH]; - gsize n; - GIOError gerr; - uint8_t *pservice; uint16_t dst_role, src_role, response; + uint8_t *pservice; + GIOError gerr; + gsize n; if (cond & G_IO_NVAL) return FALSE; @@ -437,30 +437,28 @@ static gboolean connect_setup_event(GIOChannel *chan, return FALSE; } + memset(pkt, 0, sizeof(pkt)); + n = 0; gerr = g_io_channel_read(chan, (gchar *)pkt, sizeof(pkt) - 1, &n); if (gerr != G_IO_ERROR_NONE) return FALSE; - if (n < sizeof(*req)) { - error("Invalid BNEP packet size"); - return FALSE; - } - - req = (void *)pkt; - if (req->type != BNEP_CONTROL || req->ctrl != BNEP_SETUP_CONN_REQ) { - error("Invalid BNEP control packet content"); - return FALSE; - } - + req = (struct bnep_setup_conn_req *) pkt; /* * FIXME: According to BNEP SPEC the UUID size can be * 2-16 bytes. Currently only 2 bytes size is supported */ - if (req->uuid_size != 2) { + if (req->uuid_size != 2 || n != (sizeof(*req) + req->uuid_size * 2)) { + error("Invalid BNEP packet size"); response = BNEP_CONN_INVALID_SVC; goto reply; } + if (req->type != BNEP_CONTROL || req->ctrl != BNEP_SETUP_CONN_REQ) { + error("Invalid BNEP control packet content"); + return FALSE; + } + pservice = req->service; /* Getting destination service: considering 2 bytes size */ dst_role = ntohs(bt_get_unaligned((uint16_t *) pservice)); -- cgit From 1778b4d041e6251d7411467a1db978730f8fdce0 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 31 Aug 2007 14:52:14 +0000 Subject: network: added setup msg timeout and retransmissions --- network/server.c | 216 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 127 insertions(+), 89 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 672fd555..5b741edd 100644 --- a/network/server.c +++ b/network/server.c @@ -53,6 +53,8 @@ #include "dbus-helper.h" #define NETWORK_SERVER_INTERFACE "org.bluez.network.Server" +#define SETUP_TIMEOUT 1000 +#define MAX_SETUP_ATTEMPTS 3 #include "bridge.h" #include "common.h" @@ -60,9 +62,14 @@ #include "server.h" /* Pending Authorization */ -struct pending_auth { - char *addr; /* Bluetooth Address */ - GIOChannel *io; /* BNEP connection setup io channel */ +struct setup_session { + char *address; /* Remote Bluetooth Address */ + uint16_t dst_role; /* Destination role */ + uint16_t src_role; /* Source role */ + int nsk; /* L2CAP socket */ + int attempts; /* Setup msg received */ + guint watch; /* BNEP setup watch */ + guint timeout; /* Max setup time */ }; /* Main server structure */ @@ -82,7 +89,7 @@ struct network_server { static char netdev[16] = "bnep%d"; static GIOChannel *bnep_io = NULL; static DBusConnection *connection = NULL; -static struct pending_auth *pending_auth = NULL; +static GSList *setup_sessions = NULL; static int store_property(bdaddr_t *src, uint16_t id, const char *key, const char *value) @@ -101,18 +108,15 @@ static int store_property(bdaddr_t *src, uint16_t id, return textfile_put(filename, key, value); } -static void pending_auth_free(struct pending_auth *pauth) +static void setup_free(struct setup_session *s) { - if (!pauth) - return; + g_free(s->address); + g_free(s); +} - if (pauth->addr) - g_free(pauth->addr); - if (pauth->io) { - g_io_channel_close(pauth->io); - g_io_channel_unref(pauth->io); - } - g_free(pauth); +static int setup_cmp(const struct setup_session *s, const char *addr) +{ + return strcmp(s->address, addr); } static void add_lang_attr(sdp_record_t *r) @@ -210,7 +214,7 @@ static int create_server_record(sdp_buf_t *buf, const char *name, /* Supported protocols */ { - uint16_t ptype[] = { + uint16_t ptype[] = { 0x0800, /* IPv4 */ 0x0806, /* ARP */ }; @@ -258,25 +262,21 @@ static int create_server_record(sdp_buf_t *buf, const char *name, return ret; } -static int send_bnep_ctrl_rsp(GIOChannel *chan, uint16_t response) +static ssize_t send_bnep_ctrl_rsp(int sk, uint16_t response) { struct bnep_control_rsp rsp; - GIOError gerr; - gsize n; rsp.type = BNEP_CONTROL; rsp.ctrl = BNEP_SETUP_CONN_RSP; rsp.resp = htons(response); - gerr = g_io_channel_write(chan, (gchar *)&rsp, sizeof(rsp), &n); - - return -gerr; + return send(sk, &rsp, sizeof(rsp), 0); } -static void cancel_authorization(const char *address) +static void cancel_authorization(struct setup_session *s) { DBusMessage *msg; - const char *uuid = ""; + const char *uuid; msg = dbus_message_new_method_call("org.bluez", "/org/bluez", "org.bluez.Database", @@ -286,8 +286,9 @@ static void cancel_authorization(const char *address) return; } + uuid = bnep_uuid(s->dst_role); dbus_message_append_args(msg, - DBUS_TYPE_STRING, &address, + DBUS_TYPE_STRING, &s->address, DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID); @@ -296,29 +297,32 @@ static void cancel_authorization(const char *address) static void authorization_callback(DBusPendingCall *pcall, void *data) { - struct network_server *ns = data; + struct setup_session *s = data; + struct network_server *ns = NULL; DBusMessage *reply = dbus_pending_call_steal_reply(pcall); - char devname[16]; + char path[MAX_PATH_LENGTH], devname[16]; + uint16_t response = BNEP_CONN_NOT_ALLOWED; DBusError derr; - uint16_t response; - int sk; - if (!pending_auth) { + if (!g_slist_find(setup_sessions, s)) { dbus_message_unref(reply); - dbus_pending_call_unref(pcall); return; } - sk = g_io_channel_unix_get_fd(pending_auth->io); + snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/%s", bnep_name(s->dst_role)); + dbus_connection_get_object_user_data(connection, path, (void *) &ns); + + /* Server can be disabled in the meantime */ + if (ns == NULL || ns->enable == FALSE) + goto failed; dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { error("Access denied: %s", derr.message); if (dbus_error_has_name(&derr, DBUS_ERROR_NO_REPLY)) { debug("Canceling authorization request"); - cancel_authorization(pending_auth->addr); + cancel_authorization(s); } - response = BNEP_CONN_NOT_ALLOWED; dbus_error_free(&derr); goto failed; } @@ -326,10 +330,8 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) memset(devname, 0, 16); strncpy(devname, netdev, 16); - if (bnep_connadd(sk, ns->id, devname) < 0) { - response = BNEP_CONN_NOT_ALLOWED; + if (bnep_connadd(s->nsk, s->dst_role, devname) < 0) goto failed; - } info("Authorization succedded. New connection: %s", devname); response = BNEP_SUCCESS; @@ -337,36 +339,53 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) if (bridge_add_interface("pan0", devname) < 0) { error("Can't add %s to the bridge: %s(%d)", devname, strerror(errno), errno); - response = BNEP_CONN_NOT_ALLOWED; goto failed; } bnep_if_up(devname, TRUE); bnep_if_up("pan0", TRUE); - ns->clients = g_slist_append(ns->clients, g_strdup(pending_auth->addr)); + ns->clients = g_slist_append(ns->clients, g_strdup(s->address)); /* FIXME: Enable routing if applied */ /* FIXME: send the D-Bus message to notify the new bnep iface */ failed: - send_bnep_ctrl_rsp(pending_auth->io, response); + send_bnep_ctrl_rsp(s->nsk, response); + dbus_message_unref(reply); +} - pending_auth_free(pending_auth); - pending_auth = NULL; +static void setup_watch_destroy(void *data) +{ + struct setup_session *s; + GSList *l; - close(sk); + /* + * Remote initiated: socket HUP + * Authorization: denied/accepted + */ + l = g_slist_find(setup_sessions, data); + if (!l) + return; - dbus_message_unref(reply); - dbus_pending_call_unref(pcall); + s = l->data; + + setup_sessions = g_slist_remove(setup_sessions, s); + + /* Remove active watches */ + if (s->watch) + g_source_remove(s->watch); + if (s->timeout) + g_source_remove(s->timeout); + setup_free(s); } -static int authorize_connection(const char *address, struct network_server *ns) +static int authorize_connection(struct setup_session *s) { DBusMessage *msg; DBusPendingCall *pending; - const char *uuid = ""; /* FIXME: */ + const char *uuid; msg = dbus_message_new_method_call("org.bluez", "/org/bluez", "org.bluez.Database", "RequestAuthorization"); @@ -375,10 +394,11 @@ static int authorize_connection(const char *address, struct network_server *ns) return -ENOMEM; } - debug("Requesting authorization for %s UUID:%s", address, uuid); + uuid = bnep_uuid(s->dst_role); + debug("Requesting authorization for %s UUID:%s", s->address, uuid); dbus_message_append_args(msg, - DBUS_TYPE_STRING, &address, + DBUS_TYPE_STRING, &s->address, DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID); @@ -389,7 +409,9 @@ static int authorize_connection(const char *address, struct network_server *ns) return -EACCES; } - dbus_pending_call_set_notify(pending, authorization_callback, ns, NULL); + dbus_pending_call_set_notify(pending, + authorization_callback, s, setup_watch_destroy); + dbus_pending_call_unref(pending); dbus_message_unref(msg); return 0; @@ -419,38 +441,39 @@ static uint16_t inline chk_role(uint16_t dst_role, uint16_t src_role) static gboolean connect_setup_event(GIOChannel *chan, GIOCondition cond, gpointer data) { + struct setup_session *s = data; struct network_server *ns = NULL; struct bnep_setup_conn_req *req; unsigned char pkt[BNEP_MTU]; char path[MAX_PATH_LENGTH]; - uint16_t dst_role, src_role, response; + uint16_t response; uint8_t *pservice; - GIOError gerr; - gsize n; + ssize_t r; + int sk; if (cond & G_IO_NVAL) return FALSE; if (cond & (G_IO_ERR | G_IO_HUP)) { error("Hangup or error on BNEP socket"); - cancel_authorization(pending_auth->addr); + /* If there is a pending authorization */ + if (s->attempts) + cancel_authorization(s); return FALSE; } + sk = g_io_channel_unix_get_fd(chan); memset(pkt, 0, sizeof(pkt)); - n = 0; - gerr = g_io_channel_read(chan, (gchar *)pkt, sizeof(pkt) - 1, &n); - if (gerr != G_IO_ERROR_NONE) - return FALSE; + r = recv(sk, pkt, sizeof(pkt) - 1, 0); req = (struct bnep_setup_conn_req *) pkt; - /* + /* * FIXME: According to BNEP SPEC the UUID size can be * 2-16 bytes. Currently only 2 bytes size is supported */ - if (req->uuid_size != 2 || n != (sizeof(*req) + req->uuid_size * 2)) { + if (req->uuid_size != 2 || r != (sizeof(*req) + req->uuid_size * 2)) { error("Invalid BNEP packet size"); - response = BNEP_CONN_INVALID_SVC; + response = BNEP_CONN_INVALID_SVC; goto reply; } @@ -461,16 +484,16 @@ static gboolean connect_setup_event(GIOChannel *chan, pservice = req->service; /* Getting destination service: considering 2 bytes size */ - dst_role = ntohs(bt_get_unaligned((uint16_t *) pservice)); + s->dst_role = ntohs(bt_get_unaligned((uint16_t *) pservice)); pservice += req->uuid_size; /* Getting source service: considering 2 bytes size */ - src_role = ntohs(bt_get_unaligned((uint16_t *) pservice)); + s->src_role = ntohs(bt_get_unaligned((uint16_t *) pservice)); - response = chk_role(src_role, dst_role); + response = chk_role(s->src_role, s->dst_role); if (response) goto reply; - snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/%s", bnep_name(dst_role)); + snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/%s", bnep_name(s->dst_role)); dbus_connection_get_object_user_data(connection, path, (void *) &ns); if (ns == NULL || ns->enable == FALSE) { @@ -478,35 +501,41 @@ static gboolean connect_setup_event(GIOChannel *chan, goto reply; } - /* - * FIXME: Check if the connection already exists. Check if the - * BNEP SPEC allows return "connection not allowed" for this case - */ + if (s->timeout) { + g_source_remove(s->timeout); + s->timeout = 0; + } + + if (++s->attempts > MAX_SETUP_ATTEMPTS) { + /* Retransmission */ + response = BNEP_CONN_NOT_ALLOWED; + goto reply; + } /* Wait authorization before reply success */ - if (authorize_connection(pending_auth->addr, ns) < 0) { + if (authorize_connection(s) < 0) { response = BNEP_CONN_NOT_ALLOWED; goto reply; } return TRUE; reply: - send_bnep_ctrl_rsp(chan, response); + send_bnep_ctrl_rsp(sk, response); return FALSE; } -static void connect_setup_destroy(gpointer data) +static gboolean setup_timeout(void *data) { - if (pending_auth) { - pending_auth_free(pending_auth); - pending_auth = NULL; - } + setup_watch_destroy(data); + return FALSE; } static gboolean connect_event(GIOChannel *chan, GIOCondition cond, gpointer data) { struct sockaddr_l2 addr; + struct setup_session *s; + GIOChannel *io; socklen_t addrlen; char peer[18]; bdaddr_t dst; @@ -537,26 +566,29 @@ static gboolean connect_event(GIOChannel *chan, info("Connection from: %s on PSM %d", peer, psm); - /* Only one authorization at same time */ - if (pending_auth) { - GIOChannel *io; - error("Rejecting %s(pending authorization)", peer); - io = g_io_channel_unix_new(nsk); - send_bnep_ctrl_rsp(io, BNEP_CONN_NOT_ALLOWED); - g_io_channel_close(io); - g_io_channel_unref(io); + if (g_slist_find_custom(setup_sessions, peer, + (GCompareFunc) setup_cmp)) { + error("Pending connection setup session"); + close(nsk); return TRUE; } - pending_auth = g_new0(struct pending_auth, 1); - pending_auth->addr = g_strdup(peer); - pending_auth->io = g_io_channel_unix_new(nsk); - g_io_channel_set_close_on_unref(pending_auth->io, FALSE); + s = g_new0(struct setup_session, 1); + s->address = g_strdup(peer); + s->nsk = nsk; + io = g_io_channel_unix_new(nsk); + g_io_channel_set_close_on_unref(io, TRUE); /* New watch for BNEP setup */ - g_io_add_watch_full(pending_auth->io, G_PRIORITY_DEFAULT, + s->watch = g_io_add_watch_full(io, G_PRIORITY_DEFAULT, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - connect_setup_event, pending_auth, &connect_setup_destroy); + connect_setup_event, s, &setup_watch_destroy); + g_io_channel_unref(io); + + /* Remove the timeout at the first valid msg */ + s->timeout = g_timeout_add(SETUP_TIMEOUT, setup_timeout, s); + + setup_sessions = g_slist_append(setup_sessions, s); return TRUE; } @@ -637,6 +669,12 @@ fail: void server_exit() { + if (setup_sessions) { + g_slist_foreach(setup_sessions, (GFunc) setup_free, NULL); + g_slist_free(setup_sessions); + setup_sessions = NULL; + } + if (bnep_io != NULL) { g_io_channel_close(bnep_io); g_io_channel_unref(bnep_io); -- cgit From 2033d8e42102bb6513e5ea71e147a8a7dcce1420 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 28 Sep 2007 13:15:53 +0000 Subject: Add support for config file. --- network/server.c | 1 - 1 file changed, 1 deletion(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 5b741edd..39cb4067 100644 --- a/network/server.c +++ b/network/server.c @@ -59,7 +59,6 @@ #include "bridge.h" #include "common.h" #include "manager.h" -#include "server.h" /* Pending Authorization */ struct setup_session { -- cgit From b94d1033b7c6919ca4705cf11139fb8224c3ecde Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 28 Sep 2007 13:19:21 +0000 Subject: Add bridge name support. --- network/server.c | 44 +++++++++++++++++++++++++++++++------------- 1 file changed, 31 insertions(+), 13 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 39cb4067..76be55b3 100644 --- a/network/server.c +++ b/network/server.c @@ -73,22 +73,24 @@ struct setup_session { /* Main server structure */ struct network_server { - bdaddr_t src; /* Bluetooth Local Address */ - char *iface; /* Routing interface */ - char *name; /* Server service name */ - char *range; /* IP Address range */ - char *path; /* D-Bus path */ - gboolean enable; /* Enable flag*/ - gboolean secure; /* Security flag*/ - uint32_t record_id; /* Service record id */ - uint16_t id; /* Service class identifier */ - GSList *clients; /* Active connections */ + bdaddr_t src; /* Bluetooth Local Address */ + char *bridge; /* Bridge interface */ + char *iface; /* Routing interface */ + char *name; /* Server service name */ + char *range; /* IP Address range */ + char *path; /* D-Bus path */ + gboolean enable; /* Enable flag */ + gboolean secure; /* Security flag */ + uint32_t record_id; /* Service record id */ + uint16_t id; /* Service class identifier */ + GSList *clients; /* Active connections */ }; -static char netdev[16] = "bnep%d"; +static struct server_conf *conf = NULL; static GIOChannel *bnep_io = NULL; static DBusConnection *connection = NULL; static GSList *setup_sessions = NULL; +static const char *prefix = NULL; static int store_property(bdaddr_t *src, uint16_t id, const char *key, const char *value) @@ -327,7 +329,7 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) } memset(devname, 0, 16); - strncpy(devname, netdev, 16); + strncpy(devname, prefix, strlen(prefix)); if (bnep_connadd(s->nsk, s->dst_role, devname) < 0) goto failed; @@ -592,7 +594,8 @@ static gboolean connect_event(GIOChannel *chan, return TRUE; } -int server_init(DBusConnection *conn) +int server_init(DBusConnection *conn, const char *iface_prefix, + struct server_conf *server_conf) { struct l2cap_options l2o; struct sockaddr_l2 l2a; @@ -653,6 +656,8 @@ int server_init(DBusConnection *conn) } connection = dbus_connection_ref(conn); + conf = server_conf; + prefix = iface_prefix; bnep_io = g_io_channel_unix_new(sk); g_io_channel_set_close_on_unref(bnep_io, FALSE); @@ -682,6 +687,7 @@ void server_exit() dbus_connection_unref(connection); connection = NULL; + conf = NULL; } static uint32_t add_server_record(struct network_server *ns) @@ -1190,6 +1196,12 @@ int server_register(const char *path, bdaddr_t *src, uint16_t id) ns->path = g_strdup(path); ns->id = id; + if (id == BNEP_SVC_NAP) + ns->bridge = conf->nap_iface; + else if (id == BNEP_SVC_GN) + ns->bridge = conf->gn_iface; + else + ns->bridge = conf->panu_iface; bacpy(&ns->src, src); info("Registered server path:%s", path); @@ -1208,6 +1220,12 @@ int server_register_from_file(const char *path, const bdaddr_t *src, bacpy(&ns->src, src); ns->path = g_strdup(path); ns->id = id; + if (id == BNEP_SVC_NAP) + ns->bridge = conf->nap_iface; + else if (id == BNEP_SVC_GN) + ns->bridge = conf->gn_iface; + else + ns->bridge = conf->panu_iface; ns->name = textfile_get(filename, "name"); if (!ns->name) { /* Name is mandatory */ -- cgit From a87f1daabf62c0f45dfb9e1c5f21cec75477d342 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 28 Sep 2007 13:21:42 +0000 Subject: Add support for script execution. --- network/server.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 76be55b3..b1257760 100644 --- a/network/server.c +++ b/network/server.c @@ -337,14 +337,14 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) info("Authorization succedded. New connection: %s", devname); response = BNEP_SUCCESS; - if (bridge_add_interface("pan0", devname) < 0) { + if (bridge_add_interface(ns->bridge, devname) < 0) { error("Can't add %s to the bridge: %s(%d)", devname, strerror(errno), errno); goto failed; } - bnep_if_up(devname, TRUE); - bnep_if_up("pan0", TRUE); + bnep_if_up(devname, NULL); + bnep_if_up(ns->bridge, NULL); ns->clients = g_slist_append(ns->clients, g_strdup(s->address)); -- cgit From 6113615ecfb8026a6a3ce0af38fc79ec8abec748 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 28 Sep 2007 13:23:51 +0000 Subject: Rework configuration file to use roles. --- network/server.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index b1257760..80ab49a1 100644 --- a/network/server.c +++ b/network/server.c @@ -74,7 +74,6 @@ struct setup_session { /* Main server structure */ struct network_server { bdaddr_t src; /* Bluetooth Local Address */ - char *bridge; /* Bridge interface */ char *iface; /* Routing interface */ char *name; /* Server service name */ char *range; /* IP Address range */ @@ -86,7 +85,6 @@ struct network_server { GSList *clients; /* Active connections */ }; -static struct server_conf *conf = NULL; static GIOChannel *bnep_io = NULL; static DBusConnection *connection = NULL; static GSList *setup_sessions = NULL; @@ -304,6 +302,7 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) char path[MAX_PATH_LENGTH], devname[16]; uint16_t response = BNEP_CONN_NOT_ALLOWED; DBusError derr; + const char *bridge; if (!g_slist_find(setup_sessions, s)) { dbus_message_unref(reply); @@ -337,14 +336,18 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) info("Authorization succedded. New connection: %s", devname); response = BNEP_SUCCESS; - if (bridge_add_interface(ns->bridge, devname) < 0) { + if (bridge_add_interface(ns->id, devname) < 0) { error("Can't add %s to the bridge: %s(%d)", devname, strerror(errno), errno); goto failed; } - bnep_if_up(devname, NULL); - bnep_if_up(ns->bridge, NULL); + bridge = bridge_get_name(ns->id); + if (bridge) { + bnep_if_up(devname, 0); + bnep_if_up(bridge, ns->id); + } else + bnep_if_up(devname, ns->id); ns->clients = g_slist_append(ns->clients, g_strdup(s->address)); @@ -594,8 +597,7 @@ static gboolean connect_event(GIOChannel *chan, return TRUE; } -int server_init(DBusConnection *conn, const char *iface_prefix, - struct server_conf *server_conf) +int server_init(DBusConnection *conn, const char *iface_prefix) { struct l2cap_options l2o; struct sockaddr_l2 l2a; @@ -656,7 +658,6 @@ int server_init(DBusConnection *conn, const char *iface_prefix, } connection = dbus_connection_ref(conn); - conf = server_conf; prefix = iface_prefix; bnep_io = g_io_channel_unix_new(sk); @@ -687,7 +688,6 @@ void server_exit() dbus_connection_unref(connection); connection = NULL; - conf = NULL; } static uint32_t add_server_record(struct network_server *ns) @@ -1195,13 +1195,6 @@ int server_register(const char *path, bdaddr_t *src, uint16_t id) ns->name = g_strdup("BlueZ PANU service"); ns->path = g_strdup(path); - ns->id = id; - if (id == BNEP_SVC_NAP) - ns->bridge = conf->nap_iface; - else if (id == BNEP_SVC_GN) - ns->bridge = conf->gn_iface; - else - ns->bridge = conf->panu_iface; bacpy(&ns->src, src); info("Registered server path:%s", path); @@ -1220,12 +1213,6 @@ int server_register_from_file(const char *path, const bdaddr_t *src, bacpy(&ns->src, src); ns->path = g_strdup(path); ns->id = id; - if (id == BNEP_SVC_NAP) - ns->bridge = conf->nap_iface; - else if (id == BNEP_SVC_GN) - ns->bridge = conf->gn_iface; - else - ns->bridge = conf->panu_iface; ns->name = textfile_get(filename, "name"); if (!ns->name) { /* Name is mandatory */ -- cgit From ec7083e9e5ba28b679f231c7bc341330feddf2ce Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 28 Sep 2007 13:25:27 +0000 Subject: Fixes codestyle, bridge creation and some code cleanup. --- network/server.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 80ab49a1..de30f72e 100644 --- a/network/server.c +++ b/network/server.c @@ -80,6 +80,7 @@ struct network_server { char *path; /* D-Bus path */ gboolean enable; /* Enable flag */ gboolean secure; /* Security flag */ + gboolean up; /* Interface up flag */ uint32_t record_id; /* Service record id */ uint16_t id; /* Service class identifier */ GSList *clients; /* Active connections */ @@ -345,14 +346,14 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) bridge = bridge_get_name(ns->id); if (bridge) { bnep_if_up(devname, 0); - bnep_if_up(bridge, ns->id); + if (!ns->up) + bnep_if_up(bridge, ns->id); } else bnep_if_up(devname, ns->id); + ns->up = TRUE; ns->clients = g_slist_append(ns->clients, g_strdup(s->address)); - /* FIXME: Enable routing if applied */ - /* FIXME: send the D-Bus message to notify the new bnep iface */ failed: -- cgit From d26525ada19fa8bb1a5d379dc14d68352161a221 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 28 Sep 2007 13:26:25 +0000 Subject: Fix bridge removal on exit. --- network/server.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index de30f72e..e9fc2506 100644 --- a/network/server.c +++ b/network/server.c @@ -346,11 +346,13 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) bridge = bridge_get_name(ns->id); if (bridge) { bnep_if_up(devname, 0); - if (!ns->up) + if (!ns->up) { bnep_if_up(bridge, ns->id); + ns->iface = g_strdup(bridge); + ns->up = TRUE; + } } else bnep_if_up(devname, ns->id); - ns->up = TRUE; ns->clients = g_slist_append(ns->clients, g_strdup(s->address)); @@ -1138,6 +1140,9 @@ static void server_unregister(DBusConnection *conn, void *data) info("Unregistered server path:%s", ns->path); + if (ns->up) + bnep_if_down(ns->iface); + server_free(ns); } -- cgit From 7b4212920e58f58b15c69146a109f02d365e2286 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 28 Sep 2007 13:28:50 +0000 Subject: Fix bug on panu server. --- network/server.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index e9fc2506..b5a2c6d0 100644 --- a/network/server.c +++ b/network/server.c @@ -178,7 +178,7 @@ static int create_server_record(sdp_buf_t *buf, const char *name, profile[0].version = 0x0100; pfseq = sdp_list_append(NULL, &profile[0]); sdp_set_profile_descs(&record, pfseq); - + sdp_set_info_attr(&record, name, NULL, desc); break; case BNEP_SVC_PANU: @@ -337,14 +337,14 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) info("Authorization succedded. New connection: %s", devname); response = BNEP_SUCCESS; - if (bridge_add_interface(ns->id, devname) < 0) { - error("Can't add %s to the bridge: %s(%d)", - devname, strerror(errno), errno); - goto failed; - } - bridge = bridge_get_name(ns->id); if (bridge) { + if (bridge_add_interface(ns->id, devname) < 0) { + error("Can't add %s to the bridge: %s(%d)", + devname, strerror(errno), errno); + goto failed; + } + bnep_if_up(devname, 0); if (!ns->up) { bnep_if_up(bridge, ns->id); @@ -1140,9 +1140,6 @@ static void server_unregister(DBusConnection *conn, void *data) info("Unregistered server path:%s", ns->path); - if (ns->up) - bnep_if_down(ns->iface); - server_free(ns); } -- cgit From 54943abd65058d7c24fbf9384759181c16913a96 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 28 Sep 2007 13:30:48 +0000 Subject: Add secure link mode. --- network/server.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index b5a2c6d0..ac87ad19 100644 --- a/network/server.c +++ b/network/server.c @@ -600,7 +600,8 @@ static gboolean connect_event(GIOChannel *chan, return TRUE; } -int server_init(DBusConnection *conn, const char *iface_prefix) +int server_init(DBusConnection *conn, const char *iface_prefix, + gboolean secure) { struct l2cap_options l2o; struct sockaddr_l2 l2a; @@ -645,8 +646,7 @@ int server_init(DBusConnection *conn, const char *iface_prefix) goto fail; } - /* FIXME: Set link mode - it is applied to all servers */ - lm = 0; + lm = secure? L2CAP_LM_SECURE : 0; if (lm && setsockopt(sk, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0) { err = errno; error("Failed to set link mode. %s(%d)", -- cgit From da7741d54263d6de3475b8c10db3c1dd3ebaebaf Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 28 Sep 2007 13:32:50 +0000 Subject: Improve bridge and network interfaces manipulation. --- network/server.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index ac87ad19..a349bc32 100644 --- a/network/server.c +++ b/network/server.c @@ -80,7 +80,6 @@ struct network_server { char *path; /* D-Bus path */ gboolean enable; /* Enable flag */ gboolean secure; /* Security flag */ - gboolean up; /* Interface up flag */ uint32_t record_id; /* Service record id */ uint16_t id; /* Service class identifier */ GSList *clients; /* Active connections */ @@ -346,11 +345,6 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) } bnep_if_up(devname, 0); - if (!ns->up) { - bnep_if_up(bridge, ns->id); - ns->iface = g_strdup(bridge); - ns->up = TRUE; - } } else bnep_if_up(devname, ns->id); -- cgit From b9b690ea90c9aa0519f4d86eb1e82f7198d710f2 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 28 Sep 2007 13:36:45 +0000 Subject: Remove GetSecurity and SetSecurity. --- network/server.c | 75 +++++--------------------------------------------------- 1 file changed, 6 insertions(+), 69 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index a349bc32..6ac7789f 100644 --- a/network/server.c +++ b/network/server.c @@ -79,7 +79,6 @@ struct network_server { char *range; /* IP Address range */ char *path; /* D-Bus path */ gboolean enable; /* Enable flag */ - gboolean secure; /* Security flag */ uint32_t record_id; /* Service record id */ uint16_t id; /* Service class identifier */ GSList *clients; /* Active connections */ @@ -89,6 +88,7 @@ static GIOChannel *bnep_io = NULL; static DBusConnection *connection = NULL; static GSList *setup_sessions = NULL; static const char *prefix = NULL; +static gboolean security = TRUE; static int store_property(bdaddr_t *src, uint16_t id, const char *key, const char *value) @@ -133,7 +133,7 @@ static void add_lang_attr(sdp_record_t *r) } static int create_server_record(sdp_buf_t *buf, const char *name, - uint16_t id, dbus_bool_t secure) + uint16_t id) { sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto; uuid_t root_uuid, pan, l2cap, bnep; @@ -141,7 +141,7 @@ static int create_server_record(sdp_buf_t *buf, const char *name, sdp_list_t *proto[2]; sdp_data_t *v, *p; uint16_t psm = BNEP_PSM, version = 0x0100; - uint16_t security_desc = (secure ? 0x0001 : 0x0000); + uint16_t security_desc = (security ? 0x0001 : 0x0000); uint16_t net_access_type = 0xfffe; uint32_t max_net_access_rate = 0; const char *desc = "BlueZ PAN service"; @@ -647,6 +647,7 @@ int server_init(DBusConnection *conn, const char *iface_prefix, strerror(err), err); goto fail; } + security = secure; if (listen(sk, 1) < 0) { err = errno; @@ -701,7 +702,7 @@ static uint32_t add_server_record(struct network_server *ns) return 0; } - if (create_server_record(&buf, ns->name, ns->id, ns->secure) < 0) { + if (create_server_record(&buf, ns->name, ns->id) < 0) { error("Unable to allocate new service record"); dbus_message_unref(msg); return 0; @@ -753,7 +754,7 @@ static int update_server_record(struct network_server *ns) return -ENOMEM; } - if (create_server_record(&buf, ns->name, ns->id, ns->secure) < 0) { + if (create_server_record(&buf, ns->name, ns->id) < 0) { error("Unable to allocate new service record"); dbus_message_unref(msg); return -1; @@ -1015,58 +1016,6 @@ static DBusHandlerResult set_routing(DBusConnection *conn, DBusMessage *msg, return send_message_and_unref(conn, reply); } -static DBusHandlerResult set_security(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - struct network_server *ns = data; - DBusMessage *reply; - DBusError derr; - dbus_bool_t secure; - - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_error_init(&derr); - if (!dbus_message_get_args(msg, &derr, - DBUS_TYPE_BOOLEAN, &secure, - DBUS_TYPE_INVALID)) { - err_invalid_args(conn, msg, derr.message); - dbus_error_free(&derr); - return DBUS_HANDLER_RESULT_HANDLED; - } - - ns->secure = secure; - if (ns->enable) { - if (update_server_record(ns) < 0) { - dbus_message_unref(reply); - return err_failed(conn, msg, - "Service record attribute update failed"); - } - } - - store_property(&ns->src, ns->id, "secure", "1"); - - return send_message_and_unref(conn, reply); -} - -static DBusHandlerResult get_security(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - struct network_server *ns = data; - DBusMessage *reply; - - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_append_args(reply, - DBUS_TYPE_BOOLEAN, &ns->secure, - DBUS_TYPE_INVALID); - - return send_message_and_unref(conn, reply); -} - static DBusHandlerResult get_info(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -1145,8 +1094,6 @@ static DBusMethodVTable server_methods[] = { { "GetName", get_name, "", "s" }, { "SetAddressRange", set_address_range, "ss", "" }, { "SetRouting", set_routing, "s", "" }, - { "SetSecurity", set_security, "b", "" }, - { "GetSecurity", get_security, "", "b" }, { "GetInfo", get_info, "", "{sv}" }, { NULL, NULL, NULL, NULL } }; @@ -1217,14 +1164,6 @@ int server_register_from_file(const char *path, const bdaddr_t *src, return -1; } - ns->secure = FALSE; - str = textfile_get(filename, "secure"); - if (str) { - if (strcmp("1", str) == 0) - ns->secure = TRUE; - g_free(str); - } - ns->range = textfile_get(filename, "address_range"); ns->iface = textfile_get(filename, "routing"); @@ -1287,8 +1226,6 @@ int server_store(const char *path) if (ns->range) textfile_put(filename, "range", ns->range); - textfile_put(filename, "secure", ns->secure ? "1": "0"); - textfile_put(filename, "enabled", ns->enable ? "1": "0"); return 0; -- cgit From a558e0071fe657965e0b3928d72fd2318aa03087 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 28 Sep 2007 13:37:54 +0000 Subject: Fix problem with server storage. --- network/server.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 6ac7789f..702c8fb3 100644 --- a/network/server.c +++ b/network/server.c @@ -1139,6 +1139,7 @@ int server_register(const char *path, bdaddr_t *src, uint16_t id) ns->name = g_strdup("BlueZ PANU service"); ns->path = g_strdup(path); + ns->id = id; bacpy(&ns->src, src); info("Registered server path:%s", path); @@ -1205,8 +1206,10 @@ int server_store(const char *path) char addr[18]; if (!dbus_connection_get_object_user_data(connection, - path, (void *) &ns)) + path, (void *) &ns)) { + error("Unable to salve %s on storage", path); return -ENOENT; + } ba2str(&ns->src, addr); if (ns->id == BNEP_SVC_NAP) -- cgit From 583b6403808f16202ea6ace958209002e5441cd9 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 28 Sep 2007 13:38:45 +0000 Subject: Add IsEnabled to server interface. --- network/server.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 702c8fb3..4ac7328f 100644 --- a/network/server.c +++ b/network/server.c @@ -918,6 +918,22 @@ static DBusHandlerResult disable(DBusConnection *conn, return send_message_and_unref(conn, reply); } +static DBusHandlerResult is_enabled(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + struct network_server *ns = data; + DBusMessage *reply; + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &ns->enable, + DBUS_TYPE_INVALID); + + return send_message_and_unref(conn, reply); +} + static DBusHandlerResult set_name(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -1090,6 +1106,7 @@ static DBusMethodVTable server_methods[] = { { "GetUUID", get_uuid, "", "s" }, { "Enable", enable, "", "" }, { "Disable", disable, "", "" }, + { "IsEnabled", is_enabled, "", "b" }, { "SetName", set_name, "s", "" }, { "GetName", get_name, "", "s" }, { "SetAddressRange", set_address_range, "ss", "" }, -- cgit From 70f0f80c49b989f346bd3932f26bffcbdb7f75db Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 3 Oct 2007 18:49:14 +0000 Subject: Fix dict signatures. --- network/server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 4ac7328f..dd4c816a 100644 --- a/network/server.c +++ b/network/server.c @@ -1111,7 +1111,7 @@ static DBusMethodVTable server_methods[] = { { "GetName", get_name, "", "s" }, { "SetAddressRange", set_address_range, "ss", "" }, { "SetRouting", set_routing, "s", "" }, - { "GetInfo", get_info, "", "{sv}" }, + { "GetInfo", get_info, "", "a{sv}" }, { NULL, NULL, NULL, NULL } }; -- cgit From c95ffdc65e97a75e65dbbd22e7fae7086346595e Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 22 Oct 2007 20:19:53 +0000 Subject: Fixes cross storage and adapter path. --- network/server.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index dd4c816a..1622d102 100644 --- a/network/server.c +++ b/network/server.c @@ -848,7 +848,7 @@ static DBusHandlerResult enable(DBusConnection *conn, if (bacmp(&ns->src, BDADDR_ANY) == 0) { int dev_id; - dev_id = hci_get_route(NULL); + dev_id = hci_get_route(&ns->src); if ((dev_id < 0) || (hci_devba(dev_id, &ns->src) < 0)) return err_failed(conn, msg, "Adapter not available"); @@ -1170,6 +1170,9 @@ int server_register_from_file(const char *path, const bdaddr_t *src, struct network_server *ns; char *str; + if (!path) + return -EINVAL; + ns = g_new0(struct network_server, 1); bacpy(&ns->src, src); -- cgit From a67fa98d477404a1b65e283b646db77914106c35 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 31 Oct 2007 14:48:55 +0000 Subject: Remove bridge creation of NAP and make a better use of ahavi-autoipd. --- network/server.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 1622d102..e9db7df9 100644 --- a/network/server.c +++ b/network/server.c @@ -640,7 +640,7 @@ int server_init(DBusConnection *conn, const char *iface_prefix, goto fail; } - lm = secure? L2CAP_LM_SECURE : 0; + lm = secure ? L2CAP_LM_SECURE : 0; if (lm && setsockopt(sk, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0) { err = errno; error("Failed to set link mode. %s(%d)", @@ -662,6 +662,10 @@ int server_init(DBusConnection *conn, const char *iface_prefix, g_io_channel_set_close_on_unref(bnep_io, FALSE); g_io_add_watch(bnep_io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, connect_event, NULL); + + if (bridge_create(BNEP_SVC_GN) < 0) + error("Can't create GN bridge"); + return 0; fail: @@ -684,6 +688,9 @@ void server_exit() bnep_io = NULL; } + if (bridge_remove(BNEP_SVC_GN) < 0) + error("Can't remove GN bridge"); + dbus_connection_unref(connection); connection = NULL; } -- cgit From 980c9cff04d70d6301c9538647872156b1b425eb Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 31 Oct 2007 14:52:08 +0000 Subject: Make the connection to fail if unable to add a interface to bridges. --- network/server.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index e9db7df9..8c7bfb0d 100644 --- a/network/server.c +++ b/network/server.c @@ -334,7 +334,6 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) goto failed; info("Authorization succedded. New connection: %s", devname); - response = BNEP_SUCCESS; bridge = bridge_get_name(ns->id); if (bridge) { @@ -348,9 +347,9 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) } else bnep_if_up(devname, ns->id); - ns->clients = g_slist_append(ns->clients, g_strdup(s->address)); + response = BNEP_SUCCESS; - /* FIXME: send the D-Bus message to notify the new bnep iface */ + ns->clients = g_slist_append(ns->clients, g_strdup(s->address)); failed: send_bnep_ctrl_rsp(s->nsk, response); -- cgit From 7e88afe4f8307c092172ff3c3b76c2f95ab00293 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 26 Nov 2007 13:43:17 +0000 Subject: Update services to new error codes and helper functions --- network/server.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 8c7bfb0d..a335569c 100644 --- a/network/server.c +++ b/network/server.c @@ -849,14 +849,14 @@ static DBusHandlerResult enable(DBusConnection *conn, DBusMessage *reply; if (ns->enable) - return err_already_exists(conn, msg, "Server already enabled"); + return error_already_exists(conn, msg, "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 err_failed(conn, msg, "Adapter not available"); + return error_failed(conn, msg, "Adapter not available"); /* Store the server info */ server_store(ns->path); @@ -870,7 +870,7 @@ static DBusHandlerResult enable(DBusConnection *conn, ns->record_id = add_server_record(ns); if (!ns->record_id) { dbus_message_unref(reply); - return err_failed(conn, msg, + return error_failed(conn, msg, "service record registration failed"); } @@ -904,7 +904,7 @@ static DBusHandlerResult disable(DBusConnection *conn, return DBUS_HANDLER_RESULT_NEED_MEMORY; if (!ns->enable) - return err_failed(conn, msg, "Not enabled"); + return error_failed(conn, msg, "Not enabled"); /* Remove the service record */ if (ns->record_id) { @@ -956,13 +956,13 @@ static DBusHandlerResult set_name(DBusConnection *conn, if (!dbus_message_get_args(msg, &derr, DBUS_TYPE_STRING, &name, DBUS_TYPE_INVALID)) { - err_invalid_args(conn, msg, derr.message); + error_invalid_arguments(conn, msg, derr.message); dbus_error_free(&derr); return DBUS_HANDLER_RESULT_HANDLED; } if (!name || (strlen(name) == 0)) - return err_invalid_args(conn, msg, "Invalid name"); + return error_invalid_arguments(conn, msg, "Invalid name"); if (ns->name) g_free(ns->name); @@ -971,7 +971,7 @@ static DBusHandlerResult set_name(DBusConnection *conn, if (ns->enable) { if (update_server_record(ns) < 0) { dbus_message_unref(reply); - return err_failed(conn, msg, + return error_failed(conn, msg, "Service record attribute update failed"); } } @@ -1022,14 +1022,14 @@ static DBusHandlerResult set_routing(DBusConnection *conn, DBusMessage *msg, if (!dbus_message_get_args(msg, &derr, DBUS_TYPE_STRING, &iface, DBUS_TYPE_INVALID)) { - err_invalid_args(conn, msg, derr.message); + error_invalid_arguments(conn, msg, derr.message); dbus_error_free(&derr); return DBUS_HANDLER_RESULT_HANDLED; } /* FIXME: Check if the interface is valid/UP */ if (!iface || (strlen(iface) == 0)) - return err_invalid_args(conn, msg, "Invalid interface"); + return error_invalid_arguments(conn, msg, "Invalid interface"); if (ns->iface) g_free(ns->iface); -- cgit From e823c15e43a6f924779e466d434c51157002d9ee Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 2 Feb 2008 03:37:05 +0000 Subject: Update copyright information --- network/server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index a335569c..18d58e42 100644 --- a/network/server.c +++ b/network/server.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2004-2007 Marcel Holtmann + * Copyright (C) 2004-2008 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify -- cgit From 84070adc0a6a50037789b0fc3b4f4c87efd63867 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 8 Feb 2008 19:00:23 +0000 Subject: Add bridge name to debug when it fails to attach any interface. --- network/server.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 18d58e42..2778a952 100644 --- a/network/server.c +++ b/network/server.c @@ -338,8 +338,9 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) bridge = bridge_get_name(ns->id); if (bridge) { if (bridge_add_interface(ns->id, devname) < 0) { - error("Can't add %s to the bridge: %s(%d)", - devname, strerror(errno), errno); + error("Can't add %s to the bridge %s: %s(%d)", + devname, bridge, strerror(errno), + errno); goto failed; } -- cgit From 00a4f42d8f57683489c2bfa2434d813ea33d6bd2 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 26 Mar 2008 18:17:26 +0000 Subject: network: Add/Remove records directly instead of use D-Bus messages --- network/server.c | 197 +++++++++++++------------------------------------------ 1 file changed, 45 insertions(+), 152 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 2778a952..e6ead192 100644 --- a/network/server.c +++ b/network/server.c @@ -51,6 +51,7 @@ #include "error.h" #include "textfile.h" #include "dbus-helper.h" +#include "sdpd.h" #define NETWORK_SERVER_INTERFACE "org.bluez.network.Server" #define SETUP_TIMEOUT 1000 @@ -132,8 +133,7 @@ static void add_lang_attr(sdp_record_t *r) sdp_list_free(langs, 0); } -static int create_server_record(sdp_buf_t *buf, const char *name, - uint16_t id) +sdp_record_t *server_record_new(const char *name, uint16_t id) { sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto; uuid_t root_uuid, pan, l2cap, bnep; @@ -145,60 +145,64 @@ static int create_server_record(sdp_buf_t *buf, const char *name, uint16_t net_access_type = 0xfffe; uint32_t max_net_access_rate = 0; const char *desc = "BlueZ PAN service"; - sdp_record_t record; - int ret; + sdp_record_t *record; - memset(&record, 0, sizeof(sdp_record_t)); + record = sdp_record_alloc(); + if (!record) + return NULL; + + record->attrlist = NULL; + record->pattern = NULL; switch (id) { case BNEP_SVC_NAP: sdp_uuid16_create(&pan, NAP_SVCLASS_ID); svclass = sdp_list_append(NULL, &pan); - sdp_set_service_classes(&record, svclass); + sdp_set_service_classes(record, svclass); sdp_uuid16_create(&profile[0].uuid, NAP_PROFILE_ID); profile[0].version = 0x0100; pfseq = sdp_list_append(NULL, &profile[0]); - sdp_set_profile_descs(&record, pfseq); + sdp_set_profile_descs(record, pfseq); - sdp_set_info_attr(&record, name, NULL, desc); + sdp_set_info_attr(record, name, NULL, desc); - sdp_attr_add_new(&record, SDP_ATTR_NET_ACCESS_TYPE, + sdp_attr_add_new(record, SDP_ATTR_NET_ACCESS_TYPE, SDP_UINT16, &net_access_type); - sdp_attr_add_new(&record, SDP_ATTR_MAX_NET_ACCESSRATE, + sdp_attr_add_new(record, SDP_ATTR_MAX_NET_ACCESSRATE, SDP_UINT32, &max_net_access_rate); break; case BNEP_SVC_GN: sdp_uuid16_create(&pan, GN_SVCLASS_ID); svclass = sdp_list_append(NULL, &pan); - sdp_set_service_classes(&record, svclass); + sdp_set_service_classes(record, svclass); sdp_uuid16_create(&profile[0].uuid, GN_PROFILE_ID); profile[0].version = 0x0100; pfseq = sdp_list_append(NULL, &profile[0]); - sdp_set_profile_descs(&record, pfseq); + sdp_set_profile_descs(record, pfseq); - sdp_set_info_attr(&record, name, NULL, desc); + sdp_set_info_attr(record, name, NULL, desc); break; case BNEP_SVC_PANU: sdp_uuid16_create(&pan, PANU_SVCLASS_ID); svclass = sdp_list_append(NULL, &pan); - sdp_set_service_classes(&record, svclass); + sdp_set_service_classes(record, svclass); sdp_uuid16_create(&profile[0].uuid, PANU_PROFILE_ID); profile[0].version = 0x0100; pfseq = sdp_list_append(NULL, &profile[0]); - sdp_set_profile_descs(&record, pfseq); + sdp_set_profile_descs(record, pfseq); - sdp_set_info_attr(&record, name, NULL, desc); + sdp_set_info_attr(record, name, NULL, desc); break; default: - return -1; + return NULL; } sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root = sdp_list_append(NULL, &root_uuid); - sdp_set_browse_groups(&record, root); + sdp_set_browse_groups(record, root); sdp_uuid16_create(&l2cap, L2CAP_UUID); proto[0] = sdp_list_append(NULL, &l2cap); @@ -234,18 +238,13 @@ static int create_server_record(sdp_buf_t *buf, const char *name, apseq = sdp_list_append(apseq, proto[1]); aproto = sdp_list_append(NULL, apseq); - sdp_set_access_protos(&record, aproto); + sdp_set_access_protos(record, aproto); - add_lang_attr(&record); + add_lang_attr(record); - sdp_attr_add_new(&record, SDP_ATTR_SECURITY_DESC, + sdp_attr_add_new(record, SDP_ATTR_SECURITY_DESC, SDP_UINT16, &security_desc); - if (sdp_gen_record_pdu(&record, buf) < 0) - ret = -1; - else - ret = 0; - sdp_data_free(p); sdp_data_free(v); sdp_list_free(apseq, NULL); @@ -255,10 +254,8 @@ static int create_server_record(sdp_buf_t *buf, const char *name, sdp_list_free(proto[1], NULL); sdp_list_free(svclass, NULL); sdp_list_free(pfseq, NULL); - sdp_list_free(record.attrlist, (sdp_free_func_t) sdp_data_free); - sdp_list_free(record.pattern, free); - return ret; + return record; } static ssize_t send_bnep_ctrl_rsp(int sk, uint16_t response) @@ -695,133 +692,25 @@ void server_exit() connection = NULL; } -static uint32_t add_server_record(struct network_server *ns) +uint32_t register_server_record(struct network_server *ns) { - DBusMessage *msg, *reply; - DBusError derr; - dbus_uint32_t rec_id; - sdp_buf_t buf; - - msg = dbus_message_new_method_call("org.bluez", "/org/bluez", - "org.bluez.Database", "AddServiceRecord"); - if (!msg) { - error("Can't allocate new method call"); - return 0; - } + sdp_record_t *record; - if (create_server_record(&buf, ns->name, ns->id) < 0) { + record = server_record_new(ns->name, ns->id); + if (!record) { error("Unable to allocate new service record"); - dbus_message_unref(msg); return 0; } - dbus_message_append_args(msg, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, - &buf.data, buf.data_size, DBUS_TYPE_INVALID); - - dbus_error_init(&derr); - reply = dbus_connection_send_with_reply_and_block(connection, - msg, -1, &derr); - - free(buf.data); - dbus_message_unref(msg); - - if (dbus_error_is_set(&derr) || dbus_set_error_from_message(&derr, reply)) { - error("Adding service record failed: %s", derr.message); - dbus_error_free(&derr); + if (add_record_to_server(&ns->src, record) < 0) { + error("Failed to register service record"); + sdp_record_free(record); return 0; } - dbus_message_get_args(reply, &derr, DBUS_TYPE_UINT32, &rec_id, - DBUS_TYPE_INVALID); - - if (dbus_error_is_set(&derr)) { - error("Invalid arguments to AddServiceRecord reply: %s", derr.message); - dbus_message_unref(reply); - dbus_error_free(&derr); - return 0; - } - - dbus_message_unref(reply); - - debug("add_server_record: got record id 0x%x", rec_id); - - return rec_id; -} - -static int update_server_record(struct network_server *ns) -{ - DBusMessage *msg, *reply; - DBusError derr; - sdp_buf_t buf; - - msg = dbus_message_new_method_call("org.bluez", "/org/bluez", - "org.bluez.Database", "UpdateServiceRecord"); - if (!msg) { - error("Can't allocate new method call"); - return -ENOMEM; - } - - if (create_server_record(&buf, ns->name, ns->id) < 0) { - error("Unable to allocate new service record"); - dbus_message_unref(msg); - return -1; - } - - dbus_message_append_args(msg, - DBUS_TYPE_UINT32, &ns->record_id, - DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, - &buf.data, buf.data_size, DBUS_TYPE_INVALID); - - dbus_error_init(&derr); - reply = dbus_connection_send_with_reply_and_block(connection, - msg, -1, &derr); - - free(buf.data); - dbus_message_unref(msg); - - if (dbus_error_is_set(&derr) || dbus_set_error_from_message(&derr, reply)) { - error("Update service record failed: %s", derr.message); - dbus_error_free(&derr); - return -1; - } - - dbus_message_unref(reply); + debug("register_server_record: got record id 0x%x", record->handle); - return 0; -} - -static int remove_server_record(uint32_t rec_id) -{ - DBusMessage *msg, *reply; - DBusError derr; - - msg = dbus_message_new_method_call("org.bluez", "/org/bluez", - "org.bluez.Database", "RemoveServiceRecord"); - if (!msg) { - error("Can't allocate new method call"); - return -ENOMEM; - } - - dbus_message_append_args(msg, - DBUS_TYPE_UINT32, &rec_id, - DBUS_TYPE_INVALID); - - dbus_error_init(&derr); - reply = dbus_connection_send_with_reply_and_block(connection, - msg, -1, &derr); - - dbus_message_unref(msg); - - if (dbus_error_is_set(&derr)) { - error("Removing service record 0x%x failed: %s", - rec_id, derr.message); - dbus_error_free(&derr); - return -1; - } - - dbus_message_unref(reply); - - return 0; + return record->handle; } static DBusHandlerResult get_uuid(DBusConnection *conn, @@ -868,7 +757,7 @@ static DBusHandlerResult enable(DBusConnection *conn, return DBUS_HANDLER_RESULT_NEED_MEMORY; /* Add the service record */ - ns->record_id = add_server_record(ns); + ns->record_id = register_server_record(ns); if (!ns->record_id) { dbus_message_unref(reply); return error_failed(conn, msg, @@ -909,7 +798,7 @@ static DBusHandlerResult disable(DBusConnection *conn, /* Remove the service record */ if (ns->record_id) { - remove_server_record(ns->record_id); + remove_record_from_server(ns->record_id); ns->record_id = 0; } @@ -969,12 +858,16 @@ static DBusHandlerResult set_name(DBusConnection *conn, g_free(ns->name); ns->name = g_strdup(name); - if (ns->enable) { - if (update_server_record(ns) < 0) { + if (ns->enable && ns->record_id) { + uint32_t handle = register_server_record(ns); + if (!handle) { dbus_message_unref(reply); return error_failed(conn, msg, "Service record attribute update failed"); } + + remove_record_from_server(ns->record_id); + ns->record_id = handle; } store_property(&ns->src, ns->id, "name", ns->name); @@ -1078,7 +971,7 @@ static void server_free(struct network_server *ns) /* FIXME: Missing release/free all bnepX interfaces */ if (ns->record_id) - remove_server_record(ns->record_id); + remove_record_from_server(ns->record_id); if (ns->iface) g_free(ns->iface); @@ -1198,7 +1091,7 @@ int server_register_from_file(const char *path, const bdaddr_t *src, str = textfile_get(filename, "enabled"); if (str) { if (strcmp("1", str) == 0) { - ns->record_id = add_server_record(ns); + ns->record_id = register_server_record(ns); ns->enable = TRUE; } g_free(str); -- cgit From 8afaade1916c8961fc54dfe69c4d719bbf85adeb Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 26 Mar 2008 20:23:16 +0000 Subject: network: missing static modifier --- network/server.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index e6ead192..474b6d11 100644 --- a/network/server.c +++ b/network/server.c @@ -29,8 +29,6 @@ #include #include #include -#include -#include #include #include @@ -133,7 +131,7 @@ static void add_lang_attr(sdp_record_t *r) sdp_list_free(langs, 0); } -sdp_record_t *server_record_new(const char *name, uint16_t id) +static sdp_record_t *server_record_new(const char *name, uint16_t id) { sdp_list_t *svclass, *pfseq, *apseq, *root, *aproto; uuid_t root_uuid, pan, l2cap, bnep; @@ -692,7 +690,7 @@ void server_exit() connection = NULL; } -uint32_t register_server_record(struct network_server *ns) +static uint32_t register_server_record(struct network_server *ns) { sdp_record_t *record; -- cgit From 488db954d40281fda44f73dbf808bbd80f695915 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 14 Apr 2008 18:29:57 +0000 Subject: network: Use new Authorization API --- network/server.c | 91 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 27 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 474b6d11..88ff533f 100644 --- a/network/server.c +++ b/network/server.c @@ -46,6 +46,7 @@ #include "logging.h" #include "dbus.h" +#include "plugin.h" #include "error.h" #include "textfile.h" #include "dbus-helper.h" @@ -289,20 +290,15 @@ static void cancel_authorization(struct setup_session *s) send_message_and_unref(connection, msg); } -static void authorization_callback(DBusPendingCall *pcall, void *data) +static void connection_setup(struct setup_session *s) { - struct setup_session *s = data; struct network_server *ns = NULL; - DBusMessage *reply = dbus_pending_call_steal_reply(pcall); char path[MAX_PATH_LENGTH], devname[16]; uint16_t response = BNEP_CONN_NOT_ALLOWED; - DBusError derr; const char *bridge; - if (!g_slist_find(setup_sessions, s)) { - dbus_message_unref(reply); + if (!g_slist_find(setup_sessions, s)) return; - } snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/%s", bnep_name(s->dst_role)); dbus_connection_get_object_user_data(connection, path, (void *) &ns); @@ -311,17 +307,6 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) if (ns == NULL || ns->enable == FALSE) goto failed; - dbus_error_init(&derr); - if (dbus_set_error_from_message(&derr, reply)) { - error("Access denied: %s", derr.message); - if (dbus_error_has_name(&derr, DBUS_ERROR_NO_REPLY)) { - debug("Canceling authorization request"); - cancel_authorization(s); - } - dbus_error_free(&derr); - goto failed; - } - memset(devname, 0, 16); strncpy(devname, prefix, strlen(prefix)); @@ -349,7 +334,6 @@ static void authorization_callback(DBusPendingCall *pcall, void *data) failed: send_bnep_ctrl_rsp(s->nsk, response); - dbus_message_unref(reply); } static void setup_watch_destroy(void *data) @@ -377,24 +361,61 @@ static void setup_watch_destroy(void *data) setup_free(s); } -static int authorize_connection(struct setup_session *s) +static void req_auth_cb_old(DBusPendingCall *pcall, void *user_data) +{ + DBusMessage *reply = dbus_pending_call_steal_reply(pcall); + struct setup_session *s = user_data; + DBusError derr; + + dbus_error_init(&derr); + if (dbus_set_error_from_message(&derr, reply)) { + error("Access denied: %s", derr.message); + if (dbus_error_has_name(&derr, DBUS_ERROR_NO_REPLY)) { + cancel_authorization(s); + } + dbus_error_free(&derr); + } else + connection_setup(s); + + dbus_message_unref(reply); +} + +static void req_auth_cb(DBusError *derr, void *user_data) +{ + struct setup_session *s = user_data; + + if (!g_slist_find(setup_sessions, s)) + return; + + if (derr) { + error("Access denied: %s", derr->message); + if (dbus_error_has_name(derr, DBUS_ERROR_NO_REPLY)) { + bdaddr_t dst; + str2ba(s->address, &dst); + plugin_cancel_auth(&dst); + } + } else + connection_setup(s); + + setup_watch_destroy(s); +} + +static int req_auth_old(const char *address, const char *uuid, void *user_data) { DBusMessage *msg; DBusPendingCall *pending; - const char *uuid; msg = dbus_message_new_method_call("org.bluez", "/org/bluez", "org.bluez.Database", "RequestAuthorization"); if (!msg) { - error("Unable to allocat new RequestAuthorization method call"); + error("Unable to allocate new RequestAuthorization method call"); return -ENOMEM; } - uuid = bnep_uuid(s->dst_role); - debug("Requesting authorization for %s UUID:%s", s->address, uuid); + debug("Requesting authorization for %s UUID:%s", address, uuid); dbus_message_append_args(msg, - DBUS_TYPE_STRING, &s->address, + DBUS_TYPE_STRING, &address, DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID); @@ -406,13 +427,29 @@ static int authorize_connection(struct setup_session *s) } dbus_pending_call_set_notify(pending, - authorization_callback, s, setup_watch_destroy); + req_auth_cb_old, user_data, setup_watch_destroy); dbus_pending_call_unref(pending); dbus_message_unref(msg); return 0; } +static int authorize_connection(bdaddr_t *src, struct setup_session *s) +{ + const char *uuid; + bdaddr_t dst; + int ret_val; + + uuid = bnep_uuid(s->dst_role); + str2ba(s->address, &dst); + + ret_val = plugin_req_auth(src, &dst, uuid, req_auth_cb, s); + if (ret_val < 0) + return req_auth_old(s->address, uuid, s); + else + return ret_val; +} + static uint16_t inline chk_role(uint16_t dst_role, uint16_t src_role) { /* Allowed PAN Profile scenarios */ @@ -509,7 +546,7 @@ static gboolean connect_setup_event(GIOChannel *chan, } /* Wait authorization before reply success */ - if (authorize_connection(s) < 0) { + if (authorize_connection(&ns->src, s) < 0) { response = BNEP_CONN_NOT_ALLOWED; goto reply; } -- cgit From a19826fc877b376b9456e612b1a82daba8661724 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Tue, 29 Apr 2008 23:02:37 +0000 Subject: network: cleanup --- network/server.c | 393 +++++++++++++++++++++++++++++++------------------------ 1 file changed, 222 insertions(+), 171 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 88ff533f..f3e6a995 100644 --- a/network/server.c +++ b/network/server.c @@ -66,9 +66,12 @@ struct setup_session { uint16_t dst_role; /* Destination role */ uint16_t src_role; /* Source role */ int nsk; /* L2CAP socket */ - int attempts; /* Setup msg received */ - guint watch; /* BNEP setup watch */ - guint timeout; /* Max setup time */ + guint watch; /* BNEP socket watch */ +}; + +struct timeout { + guint id; /* Timeout id */ + guint watch; /* BNEP socket watch */ }; /* Main server structure */ @@ -86,10 +89,49 @@ struct network_server { static GIOChannel *bnep_io = NULL; static DBusConnection *connection = NULL; -static GSList *setup_sessions = NULL; +static struct setup_session *setup = NULL; +static GSList *servers = NULL; static const char *prefix = NULL; static gboolean security = TRUE; +static struct setup_session *setup_session_new(gchar *address, + uint16_t dst_role, uint16_t src_role, int nsk, guint watch) +{ + struct setup_session *setup; + + setup = g_new0(struct setup_session, 1); + setup->address = g_strdup(address); + setup->dst_role = dst_role; + setup->src_role = src_role; + setup->nsk = nsk; + setup->watch = watch; + + return setup; +} + +static void setup_session_free(struct setup_session *setup) +{ + g_source_remove(setup->watch); + g_free(setup->address); + 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) { @@ -107,17 +149,6 @@ static int store_property(bdaddr_t *src, uint16_t id, return textfile_put(filename, key, value); } -static void setup_free(struct setup_session *s) -{ - g_free(s->address); - g_free(s); -} - -static int setup_cmp(const struct setup_session *s, const char *addr) -{ - return strcmp(s->address, addr); -} - static void add_lang_attr(sdp_record_t *r) { sdp_lang_attr_t base_lang; @@ -257,18 +288,18 @@ static sdp_record_t *server_record_new(const char *name, uint16_t id) return record; } -static ssize_t send_bnep_ctrl_rsp(int sk, uint16_t response) +static ssize_t send_bnep_ctrl_rsp(int sk, uint16_t val) { struct bnep_control_rsp rsp; rsp.type = BNEP_CONTROL; rsp.ctrl = BNEP_SETUP_CONN_RSP; - rsp.resp = htons(response); + rsp.resp = htons(val); return send(sk, &rsp, sizeof(rsp), 0); } -static void cancel_authorization(struct setup_session *s) +static void cancel_authorization_old() { DBusMessage *msg; const char *uuid; @@ -281,39 +312,34 @@ static void cancel_authorization(struct setup_session *s) return; } - uuid = bnep_uuid(s->dst_role); + uuid = bnep_uuid(setup->dst_role); dbus_message_append_args(msg, - DBUS_TYPE_STRING, &s->address, + DBUS_TYPE_STRING, &setup->address, DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID); send_message_and_unref(connection, msg); } -static void connection_setup(struct setup_session *s) +static int server_connadd(struct network_server *ns, int nsk, + const gchar *address, uint16_t dst_role) { - struct network_server *ns = NULL; - char path[MAX_PATH_LENGTH], devname[16]; - uint16_t response = BNEP_CONN_NOT_ALLOWED; + char devname[16]; const char *bridge; - - if (!g_slist_find(setup_sessions, s)) - return; - - snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/%s", bnep_name(s->dst_role)); - dbus_connection_get_object_user_data(connection, path, (void *) &ns); + int err; /* Server can be disabled in the meantime */ - if (ns == NULL || ns->enable == FALSE) - goto failed; + if (ns->enable == FALSE) + return -EPERM; memset(devname, 0, 16); strncpy(devname, prefix, strlen(prefix)); - if (bnep_connadd(s->nsk, s->dst_role, devname) < 0) - goto failed; + err = bnep_connadd(nsk, dst_role, devname); + if (err < 0) + return err; - info("Authorization succedded. New connection: %s", devname); + info("Added new connection: %s", devname); bridge = bridge_get_name(ns->id); if (bridge) { @@ -321,83 +347,85 @@ static void connection_setup(struct setup_session *s) error("Can't add %s to the bridge %s: %s(%d)", devname, bridge, strerror(errno), errno); - goto failed; + return -EPERM; } bnep_if_up(devname, 0); } else bnep_if_up(devname, ns->id); - response = BNEP_SUCCESS; - - ns->clients = g_slist_append(ns->clients, g_strdup(s->address)); - -failed: - send_bnep_ctrl_rsp(s->nsk, response); -} - -static void setup_watch_destroy(void *data) -{ - struct setup_session *s; - GSList *l; - - /* - * Remote initiated: socket HUP - * Authorization: denied/accepted - */ - l = g_slist_find(setup_sessions, data); - if (!l) - return; - - s = l->data; + ns->clients = g_slist_append(ns->clients, g_strdup(address)); - setup_sessions = g_slist_remove(setup_sessions, s); - - /* Remove active watches */ - if (s->watch) - g_source_remove(s->watch); - if (s->timeout) - g_source_remove(s->timeout); - setup_free(s); + return 0; } static void req_auth_cb_old(DBusPendingCall *pcall, void *user_data) { + struct network_server *ns = user_data; DBusMessage *reply = dbus_pending_call_steal_reply(pcall); - struct setup_session *s = user_data; DBusError derr; + uint16_t val; + + if (!setup) { + info("Authorization cancelled: Client exited"); + return; + } dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { error("Access denied: %s", derr.message); if (dbus_error_has_name(&derr, DBUS_ERROR_NO_REPLY)) { - cancel_authorization(s); + cancel_authorization_old(); } dbus_error_free(&derr); - } else - connection_setup(s); + val = BNEP_CONN_NOT_ALLOWED; + goto done; + } + + if (server_connadd(ns, setup->nsk, + setup->address, setup->dst_role) < 0) + val = BNEP_CONN_NOT_ALLOWED; + else + val = BNEP_SUCCESS; +done: + send_bnep_ctrl_rsp(setup->nsk, val); dbus_message_unref(reply); + setup_session_free(setup); + setup = NULL; } static void req_auth_cb(DBusError *derr, void *user_data) { - struct setup_session *s = user_data; + struct network_server *ns = user_data; + uint16_t val; - if (!g_slist_find(setup_sessions, s)) + if (!setup) { + info("Authorization cancelled: Client exited"); return; + } if (derr) { error("Access denied: %s", derr->message); if (dbus_error_has_name(derr, DBUS_ERROR_NO_REPLY)) { bdaddr_t dst; - str2ba(s->address, &dst); + str2ba(setup->address, &dst); plugin_cancel_auth(&dst); } - } else - connection_setup(s); + val = BNEP_CONN_NOT_ALLOWED; + goto done; + } + + if (server_connadd(ns, setup->nsk, + setup->address, setup->dst_role) < 0) + val = BNEP_CONN_NOT_ALLOWED; + else + val = BNEP_SUCCESS; - setup_watch_destroy(s); +done: + send_bnep_ctrl_rsp(setup->nsk, val); + setup_session_free(setup); + setup = NULL; } static int req_auth_old(const char *address, const char *uuid, void *user_data) @@ -427,30 +455,30 @@ static int req_auth_old(const char *address, const char *uuid, void *user_data) } dbus_pending_call_set_notify(pending, - req_auth_cb_old, user_data, setup_watch_destroy); + req_auth_cb_old, user_data, NULL); dbus_pending_call_unref(pending); dbus_message_unref(msg); return 0; } -static int authorize_connection(bdaddr_t *src, struct setup_session *s) +static int authorize_connection(struct network_server *ns, const char *address) { const char *uuid; bdaddr_t dst; int ret_val; - uuid = bnep_uuid(s->dst_role); - str2ba(s->address, &dst); + uuid = bnep_uuid(ns->id); + str2ba(address, &dst); - ret_val = plugin_req_auth(src, &dst, uuid, req_auth_cb, s); + ret_val = plugin_req_auth(&ns->src, &dst, uuid, req_auth_cb, ns); if (ret_val < 0) - return req_auth_old(s->address, uuid, s); + return req_auth_old(address, uuid, ns); else return ret_val; } -static uint16_t inline chk_role(uint16_t dst_role, uint16_t src_role) +static uint16_t inline bnep_setup_chk(uint16_t dst_role, uint16_t src_role) { /* Allowed PAN Profile scenarios */ switch (dst_role) { @@ -471,108 +499,145 @@ static uint16_t inline chk_role(uint16_t dst_role, uint16_t src_role) return BNEP_CONN_INVALID_DST; } -static gboolean connect_setup_event(GIOChannel *chan, - GIOCondition cond, gpointer data) +static uint16_t bnep_setup_decode(struct bnep_setup_conn_req *req, + uint16_t *dst_role, uint16_t *src_role) { - struct setup_session *s = data; - struct network_server *ns = NULL; - struct bnep_setup_conn_req *req; - unsigned char pkt[BNEP_MTU]; - char path[MAX_PATH_LENGTH]; - uint16_t response; - uint8_t *pservice; - ssize_t r; - int sk; + uint8_t *dest, *source; + + dest = req->service; + source = req->service + req->uuid_size; + + switch (req->uuid_size) { + case 2: /* UUID16 */ + *dst_role = ntohs(bt_get_unaligned((uint16_t *) dest)); + *src_role = ntohs(bt_get_unaligned((uint16_t *) source)); + break; + case 4: /* UUID32 */ + case 16: /* UUID128 */ + *dst_role = ntohl(bt_get_unaligned((uint32_t *) dest)); + *src_role = ntohl(bt_get_unaligned((uint32_t *) source)); + break; + default: + return BNEP_CONN_INVALID_SVC; + } + + return 0; +} + +static gboolean bnep_setup(GIOChannel *chan, + GIOCondition cond, gpointer user_data) +{ + struct timeout *to = user_data; + struct network_server *ns; + uint8_t packet[BNEP_MTU]; + struct bnep_setup_conn_req *req = (void *) packet; + struct sockaddr_l2 sa; + socklen_t size; + char address[18]; + uint16_t rsp, src_role, dst_role; + int n, sk; if (cond & G_IO_NVAL) return FALSE; if (cond & (G_IO_ERR | G_IO_HUP)) { error("Hangup or error on BNEP socket"); - /* If there is a pending authorization */ - if (s->attempts) - cancel_authorization(s); return FALSE; } sk = g_io_channel_unix_get_fd(chan); - memset(pkt, 0, sizeof(pkt)); - r = recv(sk, pkt, sizeof(pkt) - 1, 0); - req = (struct bnep_setup_conn_req *) pkt; - /* - * FIXME: According to BNEP SPEC the UUID size can be - * 2-16 bytes. Currently only 2 bytes size is supported - */ - if (req->uuid_size != 2 || r != (sizeof(*req) + req->uuid_size * 2)) { - error("Invalid BNEP packet size"); - response = BNEP_CONN_INVALID_SVC; - goto reply; + /* Reading BNEP_SETUP_CONNECTION_REQUEST_MSG */ + n = read(sk, packet, sizeof(packet)); + if (n < 0) { + error("read(): %s(%d)", strerror(errno), errno); + return FALSE; } - if (req->type != BNEP_CONTROL || req->ctrl != BNEP_SETUP_CONN_REQ) { - error("Invalid BNEP control packet content"); + if (req->type != BNEP_CONTROL || req->ctrl != BNEP_SETUP_CONN_REQ) return FALSE; - } - pservice = req->service; - /* Getting destination service: considering 2 bytes size */ - s->dst_role = ntohs(bt_get_unaligned((uint16_t *) pservice)); - pservice += req->uuid_size; - /* Getting source service: considering 2 bytes size */ - s->src_role = ntohs(bt_get_unaligned((uint16_t *) pservice)); + rsp = bnep_setup_decode(req, &dst_role, &src_role); + if (rsp) + goto reply; - response = chk_role(s->src_role, s->dst_role); - if (response) + rsp = bnep_setup_chk(dst_role, src_role); + if (rsp) goto reply; - snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/%s", bnep_name(s->dst_role)); - dbus_connection_get_object_user_data(connection, path, (void *) &ns); + size = sizeof(sa); + if (getsockname(sk, (struct sockaddr *) &sa, &size) < 0) { + rsp = BNEP_CONN_NOT_ALLOWED; + goto reply; + } - if (ns == NULL || ns->enable == FALSE) { - response = BNEP_CONN_NOT_ALLOWED; + ba2str(&sa.l2_bdaddr, address); + ns = server_find(&sa.l2_bdaddr, dst_role); + if (!ns || ns->enable == FALSE) { + error("Server unavailable: %s (0x%x)", address, dst_role); + rsp = BNEP_CONN_NOT_ALLOWED; goto reply; } - if (s->timeout) { - g_source_remove(s->timeout); - s->timeout = 0; + if (getpeername(sk, (struct sockaddr *) &sa, &size) < 0) { + rsp = BNEP_CONN_NOT_ALLOWED; + goto reply; } - if (++s->attempts > MAX_SETUP_ATTEMPTS) { - /* Retransmission */ - response = BNEP_CONN_NOT_ALLOWED; + ba2str(&sa.l2_bdaddr, address); + + if (setup) { + error("Connection rejected: Pending authorization"); + rsp = BNEP_CONN_NOT_ALLOWED; goto reply; } /* Wait authorization before reply success */ - if (authorize_connection(&ns->src, s) < 0) { - response = BNEP_CONN_NOT_ALLOWED; + if (authorize_connection(ns, address) < 0) { + rsp = BNEP_CONN_NOT_ALLOWED; goto reply; } + setup = setup_session_new(address, dst_role, src_role, sk, to->watch); + + g_source_remove(to->id); + to->id = 0; + return TRUE; + reply: - send_bnep_ctrl_rsp(sk, response); + send_bnep_ctrl_rsp(sk, rsp); + return FALSE; } -static gboolean setup_timeout(void *data) +static void setup_destroy(void *user_data) { - setup_watch_destroy(data); + struct timeout *to = user_data; + + if (to->id) + g_source_remove(to->id); + + g_free(to); +} + +static gboolean timeout_cb(void *user_data) +{ + struct timeout *to = user_data; + + to->id = 0; + g_source_remove(to->watch); + return FALSE; } static gboolean connect_event(GIOChannel *chan, - GIOCondition cond, gpointer data) + GIOCondition cond, gpointer user_data) { struct sockaddr_l2 addr; - struct setup_session *s; + struct timeout *to; GIOChannel *io; socklen_t addrlen; - char peer[18]; - bdaddr_t dst; - unsigned short psm; int sk, nsk; if (cond & G_IO_NVAL) @@ -590,38 +655,25 @@ static gboolean connect_event(GIOChannel *chan, addrlen = sizeof(addr); nsk = accept(sk, (struct sockaddr *) &addr, &addrlen); - if (nsk < 0) - return TRUE; - - bacpy(&dst, &addr.l2_bdaddr); - psm = btohs(addr.l2_psm); - ba2str(&dst, peer); - - info("Connection from: %s on PSM %d", peer, psm); - - if (g_slist_find_custom(setup_sessions, peer, - (GCompareFunc) setup_cmp)) { - error("Pending connection setup session"); - close(nsk); + if (nsk < 0) { + error("accept(): %s(%d)", strerror(errno), errno); return TRUE; } - s = g_new0(struct setup_session, 1); - s->address = g_strdup(peer); - s->nsk = nsk; - io = g_io_channel_unix_new(nsk); g_io_channel_set_close_on_unref(io, TRUE); - /* New watch for BNEP setup */ - s->watch = g_io_add_watch_full(io, G_PRIORITY_DEFAULT, - G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - connect_setup_event, s, &setup_watch_destroy); - g_io_channel_unref(io); - - /* Remove the timeout at the first valid msg */ - s->timeout = g_timeout_add(SETUP_TIMEOUT, setup_timeout, s); - setup_sessions = g_slist_append(setup_sessions, s); + /* + * BNEP_SETUP_CONNECTION_REQUEST_MSG shall be received and + * user shall authorize the incomming connection before + * the time expires. + */ + to = g_malloc0(sizeof(struct timeout)); + to->id = g_timeout_add(SETUP_TIMEOUT, timeout_cb, to); + to->watch = g_io_add_watch_full(io, G_PRIORITY_DEFAULT, + G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + bnep_setup, to, setup_destroy); + g_io_channel_unref(io); return TRUE; } @@ -708,12 +760,6 @@ fail: void server_exit() { - if (setup_sessions) { - g_slist_foreach(setup_sessions, (GFunc) setup_free, NULL); - g_slist_free(setup_sessions); - setup_sessions = NULL; - } - if (bnep_io != NULL) { g_io_channel_close(bnep_io); g_io_channel_unref(bnep_io); @@ -1034,6 +1080,7 @@ static void server_unregister(DBusConnection *conn, void *data) info("Unregistered server path:%s", ns->path); + servers = g_slist_remove(servers, ns); server_free(ns); } @@ -1094,6 +1141,8 @@ int server_register(const char *path, bdaddr_t *src, uint16_t id) ns->id = id; bacpy(&ns->src, src); + servers = g_slist_append(servers, ns); + info("Registered server path:%s", path); return 0; @@ -1149,6 +1198,8 @@ int server_register_from_file(const char *path, const bdaddr_t *src, return -1; } + servers = g_slist_append(servers, ns); + info("Registered server path:%s", path); return 0; -- cgit From 9491a544f622e40453265c30f24ce44a61440cc1 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 1 May 2008 13:52:26 +0000 Subject: Moving authorization code to dbus-service.c --- network/server.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index f3e6a995..0915d9d4 100644 --- a/network/server.c +++ b/network/server.c @@ -46,10 +46,10 @@ #include "logging.h" #include "dbus.h" -#include "plugin.h" #include "error.h" #include "textfile.h" #include "dbus-helper.h" +#include "dbus-service.h" #include "sdpd.h" #define NETWORK_SERVER_INTERFACE "org.bluez.network.Server" @@ -410,7 +410,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); - plugin_cancel_auth(&dst); + service_cancel_auth(&dst); } val = BNEP_CONN_NOT_ALLOWED; goto done; @@ -471,7 +471,7 @@ static int authorize_connection(struct network_server *ns, const char *address) uuid = bnep_uuid(ns->id); str2ba(address, &dst); - ret_val = plugin_req_auth(&ns->src, &dst, uuid, req_auth_cb, ns); + ret_val = service_req_auth(&ns->src, &dst, uuid, req_auth_cb, ns); if (ret_val < 0) return req_auth_old(address, uuid, ns); else -- cgit From 93123d3eccdb503246f10b40ef2b62418bda6e8f Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 2 May 2008 20:56:40 +0000 Subject: Check trusted device list before request authorization --- network/server.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 0915d9d4..046b20b3 100644 --- a/network/server.c +++ b/network/server.c @@ -592,14 +592,16 @@ static gboolean bnep_setup(GIOChannel *chan, goto reply; } + setup = setup_session_new(address, dst_role, src_role, sk, to->watch); + /* Wait authorization before reply success */ if (authorize_connection(ns, address) < 0) { + setup_session_free(setup); + setup = NULL; rsp = BNEP_CONN_NOT_ALLOWED; goto reply; } - setup = setup_session_new(address, dst_role, src_role, sk, to->watch); - g_source_remove(to->id); to->id = 0; -- cgit From e7d668ac9e813bc9922ee7d771848bd8822d5d1f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 8 May 2008 20:23:45 +0000 Subject: Move D-Bus watch functions into libgdbus --- network/server.c | 1 - 1 file changed, 1 deletion(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 046b20b3..f4fb5176 100644 --- a/network/server.c +++ b/network/server.c @@ -45,7 +45,6 @@ #include #include "logging.h" -#include "dbus.h" #include "error.h" #include "textfile.h" #include "dbus-helper.h" -- cgit From 15ea15b3a752f0487bc50d0ea04925f1b9d33dcb Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 8 May 2008 22:19:14 +0000 Subject: Move D-Bus object and interface helpers into libgdbus --- network/server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index f4fb5176..71b45b22 100644 --- a/network/server.c +++ b/network/server.c @@ -43,11 +43,11 @@ #include #include +#include #include "logging.h" #include "error.h" #include "textfile.h" -#include "dbus-helper.h" #include "dbus-service.h" #include "sdpd.h" -- cgit From 3642221a7953346bb326b5aa23075e96e4cf5e0b Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 16 May 2008 12:39:38 +0000 Subject: Make network service to use bt_l2cap_listen. --- network/server.c | 106 ++++++++----------------------------------------------- 1 file changed, 15 insertions(+), 91 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 71b45b22..5d493e5f 100644 --- a/network/server.c +++ b/network/server.c @@ -50,6 +50,7 @@ #include "textfile.h" #include "dbus-service.h" #include "sdpd.h" +#include "glib-helper.h" #define NETWORK_SERVER_INTERFACE "org.bluez.network.Server" #define SETUP_TIMEOUT 1000 @@ -632,37 +633,17 @@ static gboolean timeout_cb(void *user_data) return FALSE; } -static gboolean connect_event(GIOChannel *chan, - GIOCondition cond, gpointer user_data) +static void connect_event(GIOChannel *chan, int err, const bdaddr_t *src, + const bdaddr_t *dst, gpointer user_data) { - struct sockaddr_l2 addr; struct timeout *to; - GIOChannel *io; - socklen_t addrlen; - int sk, nsk; - if (cond & G_IO_NVAL) - return FALSE; - - if (cond & (G_IO_ERR | G_IO_HUP)) { - error("Hangup or error on L2CAP socket PSM 15"); - g_io_channel_close(chan); - return FALSE; - } - - sk = g_io_channel_unix_get_fd(chan); - - memset(&addr, 0, sizeof(addr)); - addrlen = sizeof(addr); - - nsk = accept(sk, (struct sockaddr *) &addr, &addrlen); - if (nsk < 0) { + if (err < 0) { error("accept(): %s(%d)", strerror(errno), errno); - return TRUE; + return; } - io = g_io_channel_unix_new(nsk); - g_io_channel_set_close_on_unref(io, TRUE); + g_io_channel_set_close_on_unref(chan, TRUE); /* * BNEP_SETUP_CONNECTION_REQUEST_MSG shall be received and @@ -671,92 +652,35 @@ static gboolean connect_event(GIOChannel *chan, */ to = g_malloc0(sizeof(struct timeout)); to->id = g_timeout_add(SETUP_TIMEOUT, timeout_cb, to); - to->watch = g_io_add_watch_full(io, G_PRIORITY_DEFAULT, + 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); - g_io_channel_unref(io); + g_io_channel_unref(chan); - return TRUE; + return; } int server_init(DBusConnection *conn, const char *iface_prefix, gboolean secure) { - struct l2cap_options l2o; - struct sockaddr_l2 l2a; - socklen_t olen; - int sk, lm, err; - - /* Create L2CAP socket and bind it to PSM BNEP */ - sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); - if (sk < 0) { - err = errno; - error("Cannot create L2CAP socket. %s(%d)", - strerror(err), err); - return -err; - } - - memset(&l2a, 0, sizeof(l2a)); - l2a.l2_family = AF_BLUETOOTH; - bacpy(&l2a.l2_bdaddr, BDADDR_ANY); - l2a.l2_psm = htobs(BNEP_PSM); - - if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a))) { - err = errno; - error("Bind failed. %s(%d)", strerror(err), err); - goto fail; - } - - /* Setup L2CAP options according to BNEP spec */ - memset(&l2o, 0, sizeof(l2o)); - olen = sizeof(l2o); - if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen) < 0) { - err = errno; - error("Failed to get L2CAP options. %s(%d)", - strerror(err), err); - goto fail; - } - - l2o.imtu = l2o.omtu = BNEP_MTU; - if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)) < 0) { - err = errno; - error("Failed to set L2CAP options. %s(%d)", - strerror(err), err); - goto fail; - } + int lm; lm = secure ? L2CAP_LM_SECURE : 0; - if (lm && setsockopt(sk, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0) { - err = errno; - error("Failed to set link mode. %s(%d)", - strerror(err), err); - goto fail; - } - security = secure; - - if (listen(sk, 1) < 0) { - err = errno; - error("Listen failed. %s(%d)", strerror(err), err); - goto fail; - } + security = secure; connection = dbus_connection_ref(conn); prefix = iface_prefix; - bnep_io = g_io_channel_unix_new(sk); + 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); - g_io_add_watch(bnep_io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - connect_event, NULL); if (bridge_create(BNEP_SVC_GN) < 0) error("Can't create GN bridge"); return 0; -fail: - - close(sk); - errno = err; - return -err; } void server_exit() -- cgit From 30751fe0c0430e0757c018de4f8e6bceee5e85f7 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 20 May 2008 21:54:12 +0000 Subject: Fix issues with missing include for PATH_MAX --- network/server.c | 1 + 1 file changed, 1 insertion(+) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 5d493e5f..ade50a7a 100644 --- a/network/server.c +++ b/network/server.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include -- cgit From 4698b260ee4b278884ef3160e4990e5090373092 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 3 Jun 2008 12:31:42 +0000 Subject: Fixes missing parts of network which didn't use libgdbus. --- network/server.c | 202 +++++++++++++++++++++++++++---------------------------- 1 file changed, 100 insertions(+), 102 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index ade50a7a..b306242b 100644 --- a/network/server.c +++ b/network/server.c @@ -95,6 +95,14 @@ static GSList *servers = NULL; static const char *prefix = NULL; static gboolean security = TRUE; +gint find_server(gconstpointer a, gconstpointer b) +{ + const struct network_server *ns = a; + const char *path = b; + + return strcmp(ns->path, path); +} + static struct setup_session *setup_session_new(gchar *address, uint16_t dst_role, uint16_t src_role, int nsk, guint watch) { @@ -720,8 +728,8 @@ static uint32_t register_server_record(struct network_server *ns) return record->handle; } -static DBusHandlerResult get_uuid(DBusConnection *conn, - DBusMessage *msg, void *data) +static DBusMessage *get_uuid(DBusConnection *conn, + DBusMessage *msg, void *data) { struct network_server *ns = data; DBusMessage *reply; @@ -729,31 +737,46 @@ static DBusHandlerResult get_uuid(DBusConnection *conn, reply = dbus_message_new_method_return(msg); if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + return NULL; uuid = bnep_uuid(ns->id); dbus_message_append_args(reply, DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID); - return send_message_and_unref(conn, reply); + return reply; } -static DBusHandlerResult enable(DBusConnection *conn, - DBusMessage *msg, void *data) +static inline DBusMessage *failed(DBusMessage *msg, const char *description) +{ + return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", + description); +} + +static inline DBusMessage *invalid_arguments(DBusMessage *msg, + const char *description) +{ + return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments", + description); +} + +static DBusMessage *enable(DBusConnection *conn, + DBusMessage *msg, void *data) { struct network_server *ns = data; DBusMessage *reply; if (ns->enable) - return error_already_exists(conn, msg, "Server already enabled"); + return g_dbus_create_error(msg, ERROR_INTERFACE + ".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 error_failed(conn, msg, "Adapter not available"); + return failed(msg, "Adapter not available"); /* Store the server info */ server_store(ns->path); @@ -761,14 +784,13 @@ static DBusHandlerResult enable(DBusConnection *conn, reply = dbus_message_new_method_return(msg); if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + return NULL; /* Add the service record */ ns->record_id = register_server_record(ns); if (!ns->record_id) { dbus_message_unref(reply); - return error_failed(conn, msg, - "service record registration failed"); + return failed(msg, "Service record registration failed"); } ns->enable = TRUE; @@ -778,7 +800,7 @@ static DBusHandlerResult enable(DBusConnection *conn, dbus_connection_emit_signal(conn, ns->path, NETWORK_SERVER_INTERFACE, "Enabled", DBUS_TYPE_INVALID); - return send_message_and_unref(conn, reply); + return reply; } static void kill_connection(void *data, void *udata) @@ -790,18 +812,18 @@ static void kill_connection(void *data, void *udata) bnep_kill_connection(&dst); } -static DBusHandlerResult disable(DBusConnection *conn, - DBusMessage *msg, void *data) +static DBusMessage *disable(DBusConnection *conn, + DBusMessage *msg, void *data) { struct network_server *ns = data; DBusMessage *reply; reply = dbus_message_new_method_return(msg); if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + return NULL; if (!ns->enable) - return error_failed(conn, msg, "Not enabled"); + return failed(msg, "Not enabled"); /* Remove the service record */ if (ns->record_id) { @@ -818,48 +840,43 @@ static DBusHandlerResult disable(DBusConnection *conn, dbus_connection_emit_signal(conn, ns->path, NETWORK_SERVER_INTERFACE, "Disabled", DBUS_TYPE_INVALID); - return send_message_and_unref(conn, reply); + return reply; } -static DBusHandlerResult is_enabled(DBusConnection *conn, DBusMessage *msg, - void *data) +static DBusMessage *is_enabled(DBusConnection *conn, DBusMessage *msg, + void *data) { struct network_server *ns = data; DBusMessage *reply; reply = dbus_message_new_method_return(msg); if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + return NULL; dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &ns->enable, DBUS_TYPE_INVALID); - return send_message_and_unref(conn, reply); + return reply; } -static DBusHandlerResult set_name(DBusConnection *conn, - DBusMessage *msg, void *data) +static DBusMessage *set_name(DBusConnection *conn, + DBusMessage *msg, void *data) { struct network_server *ns = data; DBusMessage *reply; - DBusError derr; const char *name; reply = dbus_message_new_method_return(msg); if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + return NULL; - dbus_error_init(&derr); - if (!dbus_message_get_args(msg, &derr, + if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &name, - DBUS_TYPE_INVALID)) { - error_invalid_arguments(conn, msg, derr.message); - dbus_error_free(&derr); - return DBUS_HANDLER_RESULT_HANDLED; - } + DBUS_TYPE_INVALID)) + return NULL; if (!name || (strlen(name) == 0)) - return error_invalid_arguments(conn, msg, "Invalid name"); + return invalid_arguments(msg, "Invalid name"); if (ns->name) g_free(ns->name); @@ -869,7 +886,7 @@ static DBusHandlerResult set_name(DBusConnection *conn, uint32_t handle = register_server_record(ns); if (!handle) { dbus_message_unref(reply); - return error_failed(conn, msg, + return failed(msg, "Service record attribute update failed"); } @@ -879,11 +896,11 @@ static DBusHandlerResult set_name(DBusConnection *conn, store_property(&ns->src, ns->id, "name", ns->name); - return send_message_and_unref(conn, reply); + return reply; } -static DBusHandlerResult get_name(DBusConnection *conn, - DBusMessage *msg, void *data) +static DBusMessage *get_name(DBusConnection *conn, + DBusMessage *msg, void *data) { struct network_server *ns = data; char name[] = ""; @@ -892,55 +909,45 @@ static DBusHandlerResult get_name(DBusConnection *conn, reply = dbus_message_new_method_return(msg); if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + return NULL; dbus_message_append_args(reply, DBUS_TYPE_STRING, &pname, DBUS_TYPE_INVALID); - return send_message_and_unref(conn, reply); + return reply; } -static DBusHandlerResult set_address_range(DBusConnection *conn, +static DBusMessage *set_address_range(DBusConnection *conn, DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + return NULL; } -static DBusHandlerResult set_routing(DBusConnection *conn, DBusMessage *msg, +static DBusMessage *set_routing(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_server *ns = data; - DBusMessage *reply; - DBusError derr; const char *iface; - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_error_init(&derr); - if (!dbus_message_get_args(msg, &derr, + if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &iface, - DBUS_TYPE_INVALID)) { - error_invalid_arguments(conn, msg, derr.message); - dbus_error_free(&derr); - return DBUS_HANDLER_RESULT_HANDLED; - } + DBUS_TYPE_INVALID)) + return NULL; /* FIXME: Check if the interface is valid/UP */ if (!iface || (strlen(iface) == 0)) - return error_invalid_arguments(conn, msg, "Invalid interface"); + return invalid_arguments(msg, "Invalid interface"); if (ns->iface) g_free(ns->iface); ns->iface = g_strdup(iface); - return send_message_and_unref(conn, reply); + return dbus_message_new_method_return(msg); } -static DBusHandlerResult get_info(DBusConnection *conn, - DBusMessage *msg, void *data) +static DBusMessage *get_info(DBusConnection *conn, + DBusMessage *msg, void *data) { struct network_server *ns = data; DBusMessage *reply; @@ -950,7 +957,7 @@ static DBusHandlerResult get_info(DBusConnection *conn, reply = dbus_message_new_method_return(msg); if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + return NULL; dbus_message_iter_init_append(reply, &iter); @@ -968,7 +975,7 @@ static DBusHandlerResult get_info(DBusConnection *conn, dbus_message_iter_close_container(&iter, &dict); - return send_message_and_unref(conn, reply); + return reply; } static void server_free(struct network_server *ns) @@ -1000,7 +1007,7 @@ static void server_free(struct network_server *ns) g_free(ns); } -static void server_unregister(DBusConnection *conn, void *data) +static void server_unregister(void *data) { struct network_server *ns = data; @@ -1010,23 +1017,23 @@ static void server_unregister(DBusConnection *conn, void *data) server_free(ns); } -static DBusMethodVTable server_methods[] = { - { "GetUUID", get_uuid, "", "s" }, - { "Enable", enable, "", "" }, - { "Disable", disable, "", "" }, - { "IsEnabled", is_enabled, "", "b" }, - { "SetName", set_name, "s", "" }, - { "GetName", get_name, "", "s" }, - { "SetAddressRange", set_address_range, "ss", "" }, - { "SetRouting", set_routing, "s", "" }, - { "GetInfo", get_info, "", "a{sv}" }, - { NULL, NULL, NULL, NULL } +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 }, + { } }; -static DBusSignalVTable server_signals[] = { +static GDBusSignalTable server_signals[] = { { "Enabled", "" }, { "Disabled", "" }, - { NULL, NULL } + { } }; int server_register(const char *path, bdaddr_t *src, uint16_t id) @@ -1038,20 +1045,13 @@ int server_register(const char *path, bdaddr_t *src, uint16_t id) ns = g_new0(struct network_server, 1); - if (!dbus_connection_create_object_path(connection, path, ns, - server_unregister)) { - error("D-Bus failed to register %s path", path); - server_free(ns); - return -1; - } - - if (!dbus_connection_register_interface(connection, path, - NETWORK_SERVER_INTERFACE, - server_methods, - server_signals, NULL)) { + 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); - dbus_connection_destroy_object_path(connection, path); + server_free(ns); return -1; } @@ -1107,20 +1107,13 @@ int server_register_from_file(const char *path, const bdaddr_t *src, g_free(str); } - if (!dbus_connection_create_object_path(connection, path, ns, - server_unregister)) { - error("D-Bus failed to register %s path", path); - server_free(ns); - return -1; - } - - if (!dbus_connection_register_interface(connection, path, - NETWORK_SERVER_INTERFACE, - server_methods, - server_signals, NULL)) { + 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); - dbus_connection_destroy_object_path(connection, path); + server_free(ns); return -1; } @@ -1136,13 +1129,15 @@ int server_store(const char *path) struct network_server *ns; char filename[PATH_MAX + 1]; char addr[18]; + GSList *l; - if (!dbus_connection_get_object_user_data(connection, - path, (void *) &ns)) { + 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"); @@ -1170,10 +1165,13 @@ int server_find_data(const char *path, const char *pattern) { struct network_server *ns; const char *uuid; + GSList *l; - if (!dbus_connection_get_object_user_data(connection, path, (void *) &ns)) + 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; -- cgit From f269e27ce7e39e6484cf02a137dcda7458a7fd85 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 6 Jun 2008 10:20:21 +0000 Subject: Fix the last remains of sending helpers --- network/server.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index b306242b..c7b2b778 100644 --- a/network/server.c +++ b/network/server.c @@ -327,7 +327,9 @@ static void cancel_authorization_old() DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID); - send_message_and_unref(connection, msg); + dbus_connection_send(connection, msg, NULL); + + dbus_message_unref(msg); } static int server_connadd(struct network_server *ns, int nsk, -- cgit From f80a7215275b229a597cf8d2bbc7e4e208af522c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 7 Jun 2008 19:30:24 +0000 Subject: Use g_dbus_emit_signal for sending D-Bus signals --- network/server.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index c7b2b778..4d046602 100644 --- a/network/server.c +++ b/network/server.c @@ -799,7 +799,7 @@ static DBusMessage *enable(DBusConnection *conn, store_property(&ns->src, ns->id, "enabled", "1"); - dbus_connection_emit_signal(conn, ns->path, NETWORK_SERVER_INTERFACE, + g_dbus_emit_signal(conn, ns->path, NETWORK_SERVER_INTERFACE, "Enabled", DBUS_TYPE_INVALID); return reply; @@ -839,7 +839,7 @@ static DBusMessage *disable(DBusConnection *conn, store_property(&ns->src, ns->id, "enabled", "0"); - dbus_connection_emit_signal(conn, ns->path, NETWORK_SERVER_INTERFACE, + g_dbus_emit_signal(conn, ns->path, NETWORK_SERVER_INTERFACE, "Disabled", DBUS_TYPE_INVALID); return reply; -- cgit From 22ec945f109d9d1e21a8cfbc6e2dec3dd4b88c8e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 7 Jun 2008 20:09:25 +0000 Subject: Move some D-Bus helpers around --- network/server.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 4d046602..8c0a84cf 100644 --- a/network/server.c +++ b/network/server.c @@ -46,6 +46,8 @@ #include #include +#include "../hcid/dbus-common.h" + #include "logging.h" #include "error.h" #include "textfile.h" -- cgit From bbec31284f7e4e960c07bddd9fd1d7ee5c990118 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 16 Jun 2008 19:43:09 +0000 Subject: Remove calls to RequestAuthorization. --- network/server.c | 100 ++----------------------------------------------------- 1 file changed, 2 insertions(+), 98 deletions(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 8c0a84cf..7d951765 100644 --- a/network/server.c +++ b/network/server.c @@ -310,30 +310,6 @@ static ssize_t send_bnep_ctrl_rsp(int sk, uint16_t val) return send(sk, &rsp, sizeof(rsp), 0); } -static void cancel_authorization_old() -{ - DBusMessage *msg; - const char *uuid; - - msg = dbus_message_new_method_call("org.bluez", "/org/bluez", - "org.bluez.Database", - "CancelAuthorizationRequest"); - if (!msg) { - error("Unable to allocate new method call"); - return; - } - - uuid = bnep_uuid(setup->dst_role); - dbus_message_append_args(msg, - DBUS_TYPE_STRING, &setup->address, - DBUS_TYPE_STRING, &uuid, - DBUS_TYPE_INVALID); - - dbus_connection_send(connection, msg, NULL); - - dbus_message_unref(msg); -} - static int server_connadd(struct network_server *ns, int nsk, const gchar *address, uint16_t dst_role) { @@ -372,42 +348,6 @@ static int server_connadd(struct network_server *ns, int nsk, return 0; } -static void req_auth_cb_old(DBusPendingCall *pcall, void *user_data) -{ - struct network_server *ns = user_data; - DBusMessage *reply = dbus_pending_call_steal_reply(pcall); - DBusError derr; - uint16_t val; - - if (!setup) { - info("Authorization cancelled: Client exited"); - return; - } - - dbus_error_init(&derr); - if (dbus_set_error_from_message(&derr, reply)) { - error("Access denied: %s", derr.message); - if (dbus_error_has_name(&derr, DBUS_ERROR_NO_REPLY)) { - cancel_authorization_old(); - } - dbus_error_free(&derr); - val = BNEP_CONN_NOT_ALLOWED; - goto done; - } - - if (server_connadd(ns, setup->nsk, - setup->address, setup->dst_role) < 0) - val = BNEP_CONN_NOT_ALLOWED; - else - val = BNEP_SUCCESS; - -done: - send_bnep_ctrl_rsp(setup->nsk, val); - dbus_message_unref(reply); - setup_session_free(setup); - setup = NULL; -} - static void req_auth_cb(DBusError *derr, void *user_data) { struct network_server *ns = user_data; @@ -441,40 +381,6 @@ done: setup = NULL; } -static int req_auth_old(const char *address, const char *uuid, void *user_data) -{ - DBusMessage *msg; - DBusPendingCall *pending; - - msg = dbus_message_new_method_call("org.bluez", "/org/bluez", - "org.bluez.Database", "RequestAuthorization"); - if (!msg) { - error("Unable to allocate new RequestAuthorization method call"); - return -ENOMEM; - } - - debug("Requesting authorization for %s UUID:%s", address, uuid); - - dbus_message_append_args(msg, - DBUS_TYPE_STRING, &address, - DBUS_TYPE_STRING, &uuid, - DBUS_TYPE_INVALID); - - if (dbus_connection_send_with_reply(connection, - msg, &pending, -1) == FALSE) { - error("Sending of authorization request failed"); - dbus_message_unref(msg); - return -EACCES; - } - - dbus_pending_call_set_notify(pending, - req_auth_cb_old, user_data, NULL); - dbus_pending_call_unref(pending); - dbus_message_unref(msg); - - return 0; -} - static int authorize_connection(struct network_server *ns, const char *address) { const char *uuid; @@ -485,10 +391,8 @@ static int authorize_connection(struct network_server *ns, const char *address) str2ba(address, &dst); ret_val = service_req_auth(&ns->src, &dst, uuid, req_auth_cb, ns); - if (ret_val < 0) - return req_auth_old(address, uuid, ns); - else - return ret_val; + + return ret_val; } static uint16_t inline bnep_setup_chk(uint16_t dst_role, uint16_t src_role) -- cgit From e8ca2351ee3ba3f8b2b99731972234f42ae9b64b Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 17 Jun 2008 19:37:36 +0000 Subject: Fix authorization mechanism for 3.x. --- network/server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network/server.c') diff --git a/network/server.c b/network/server.c index 7d951765..e94964ae 100644 --- a/network/server.c +++ b/network/server.c @@ -363,7 +363,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(&dst); + service_cancel_auth(&ns->src, &dst); } val = BNEP_CONN_NOT_ALLOWED; goto done; -- cgit