From c761480865c6b65e370e2bba750c86c226a7fc3f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 27 Oct 2006 14:46:36 +0000 Subject: Add skeletons for service implementations --- network/Makefile.am | 12 ++++++++++++ network/main.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 network/Makefile.am create mode 100644 network/main.c (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am new file mode 100644 index 00000000..78cdd390 --- /dev/null +++ b/network/Makefile.am @@ -0,0 +1,12 @@ + +noinst_PROGRAMS = bt.networkd + +bt_networkd_SOURCES = main.c + +bt_networkd_LDADD = @DBUS_LIBS@ @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a + +AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ + +INCLUDES = -I$(top_srcdir)/common + +MAINTAINERCLEANFILES = Makefile.in diff --git a/network/main.c b/network/main.c new file mode 100644 index 00000000..c04bb251 --- /dev/null +++ b/network/main.c @@ -0,0 +1,34 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2005-2006 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 +#include + +int main(int argc, char *argv[]) +{ + return 0; +} -- cgit From cc918032d62f4df51657055649df8ee92cab0020 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 19 Jan 2007 21:55:53 +0000 Subject: Rename service and install it --- network/Makefile.am | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index 78cdd390..c0c196fc 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -1,9 +1,12 @@ -noinst_PROGRAMS = bt.networkd +servicedir = $(libdir)/bluetooth -bt_networkd_SOURCES = main.c +service_PROGRAMS = bluetoothd-service-network -bt_networkd_LDADD = @DBUS_LIBS@ @BLUEZ_LIBS@ $(top_builddir)/common/libhelper.a +bluetoothd_service_network_SOURCES = main.c + +LDADD = $(top_builddir)/common/libhelper.a \ + @DBUS_LIBS@ @BLUEZ_LIBS@ AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ -- cgit From 884cfe825db1a0e8c98aa6a604fd4588a1de1340 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 20 Jan 2007 02:36:57 +0000 Subject: Don't install services that are in experimental state --- network/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index c0c196fc..362c7af6 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -1,7 +1,7 @@ servicedir = $(libdir)/bluetooth -service_PROGRAMS = bluetoothd-service-network +noinst_PROGRAMS = bluetoothd-service-network bluetoothd_service_network_SOURCES = main.c -- cgit 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/Makefile.am | 15 +++++++++++++-- network/connection.c | 28 ++++++++++++++++++++++++++++ network/connection.h | 22 ++++++++++++++++++++++ network/main.c | 2 +- network/manager.c | 28 ++++++++++++++++++++++++++++ network/manager.h | 22 ++++++++++++++++++++++ network/server.c | 28 ++++++++++++++++++++++++++++ network/server.h | 22 ++++++++++++++++++++++ 8 files changed, 164 insertions(+), 3 deletions(-) create mode 100644 network/connection.c create mode 100644 network/connection.h create mode 100644 network/manager.c create mode 100644 network/manager.h create mode 100644 network/server.c create mode 100644 network/server.h (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index 362c7af6..fe6e3110 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -1,15 +1,26 @@ +if NETWORKSERVICE +if CONFIGFILES +confdir = $(sysconfdir)/bluetooth + +conf_DATA = network.service +endif + servicedir = $(libdir)/bluetooth noinst_PROGRAMS = bluetoothd-service-network -bluetoothd_service_network_SOURCES = main.c +bluetoothd_service_network_SOURCES = main.c \ + manager.h manager.c server.h server.c connection.h connection.c LDADD = $(top_builddir)/common/libhelper.a \ - @DBUS_LIBS@ @BLUEZ_LIBS@ + @DBUS_LIBS@ @BLUEZ_LIBS@ +endif AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ INCLUDES = -I$(top_srcdir)/common +EXTRA_DIST = network.service network-api.txt + MAINTAINERCLEANFILES = Makefile.in diff --git a/network/connection.c b/network/connection.c new file mode 100644 index 00000000..bd733cb2 --- /dev/null +++ b/network/connection.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 "connection.h" diff --git a/network/connection.h b/network/connection.h new file mode 100644 index 00000000..e87dd676 --- /dev/null +++ b/network/connection.h @@ -0,0 +1,22 @@ +/* + * + * 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 + * + */ diff --git a/network/main.c b/network/main.c index c04bb251..7f643c58 100644 --- a/network/main.c +++ b/network/main.c @@ -2,7 +2,7 @@ * * BlueZ - Bluetooth protocol stack for Linux * - * Copyright (C) 2005-2006 Marcel Holtmann + * Copyright (C) 2004-2007 Marcel Holtmann * * * This program is free software; you can redistribute it and/or modify diff --git a/network/manager.c b/network/manager.c new file mode 100644 index 00000000..90d20927 --- /dev/null +++ b/network/manager.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 "manager.h" diff --git a/network/manager.h b/network/manager.h new file mode 100644 index 00000000..e87dd676 --- /dev/null +++ b/network/manager.h @@ -0,0 +1,22 @@ +/* + * + * 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 + * + */ 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" diff --git a/network/server.h b/network/server.h new file mode 100644 index 00000000..e87dd676 --- /dev/null +++ b/network/server.h @@ -0,0 +1,22 @@ +/* + * + * 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 + * + */ -- cgit From 855cf216127e1fd6f6aba60c3761a0ead17ae910 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 9 Mar 2007 15:37:57 +0000 Subject: Create init and exit functions --- network/main.c | 6 ++++++ network/manager.c | 9 +++++++++ network/manager.h | 3 +++ 3 files changed, 18 insertions(+) (limited to 'network') diff --git a/network/main.c b/network/main.c index 7f643c58..e51c73aa 100644 --- a/network/main.c +++ b/network/main.c @@ -28,7 +28,13 @@ #include #include +#include "manager.h" + int main(int argc, char *argv[]) { + network_init(); + + network_exit(); + return 0; } diff --git a/network/manager.c b/network/manager.c index 90d20927..33679a51 100644 --- a/network/manager.c +++ b/network/manager.c @@ -26,3 +26,12 @@ #endif #include "manager.h" + +int network_init(void) +{ + return 0; +} + +void network_exit(void) +{ +} diff --git a/network/manager.h b/network/manager.h index e87dd676..b659d8dc 100644 --- a/network/manager.h +++ b/network/manager.h @@ -20,3 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ + +int network_init(void); +void network_exit(void); -- cgit From ff7979aa540abd58cd3e465974480b9d7d46d1cd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 9 Mar 2007 15:44:48 +0000 Subject: Add API document and service description file --- network/network-api.txt | 12 ++++++++++++ network/network.service | 5 +++++ 2 files changed, 17 insertions(+) create mode 100644 network/network-api.txt create mode 100644 network/network.service (limited to 'network') diff --git a/network/network-api.txt b/network/network-api.txt new file mode 100644 index 00000000..f10e676a --- /dev/null +++ b/network/network-api.txt @@ -0,0 +1,12 @@ +Bluetooth network service API description +***************************************** + +Copyright (C) 2006-2007 Marcel Holtmann + + +Network Manager hierarchy +========================= + +Service org.bluez.network +Interface org.bluez.network.Manager +Object path /org/bluez/network diff --git a/network/network.service b/network/network.service new file mode 100644 index 00000000..444bdff3 --- /dev/null +++ b/network/network.service @@ -0,0 +1,5 @@ +[Bluetooth Service] +Identifier=network +Name=Network service +Description=Bluetooth Personal Area Network service +Autostart=false -- cgit From f612aabb413e813f8800ff85f341e994885a5692 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 9 Mar 2007 15:46:51 +0000 Subject: Don't forget to link against GLib --- network/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index fe6e3110..ab7fe934 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -14,10 +14,10 @@ bluetoothd_service_network_SOURCES = main.c \ manager.h manager.c server.h server.c connection.h connection.c LDADD = $(top_builddir)/common/libhelper.a \ - @DBUS_LIBS@ @BLUEZ_LIBS@ + @GLIB_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@ endif -AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ +AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ @GLIB_CFLAGS@ INCLUDES = -I$(top_srcdir)/common -- cgit From e7e20e6343bd6b8c9b3100e66a612900ab94caff Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 9 Mar 2007 22:12:19 +0000 Subject: Network: main loop creation --- network/main.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'network') diff --git a/network/main.c b/network/main.c index e51c73aa..776ea517 100644 --- a/network/main.c +++ b/network/main.c @@ -26,15 +26,57 @@ #endif #include +#include +#include +#include #include +#include +#include + +#include "dbus.h" +#include "logging.h" #include "manager.h" +static GMainLoop *main_loop; + +static void sig_term(int sig) +{ + g_main_loop_quit(main_loop); +} + int main(int argc, char *argv[]) { + struct sigaction sa; + + start_logging("network", "Bluetooth Network daemon"); + + memset(&sa, 0, sizeof(sa)); + sa.sa_flags = SA_NOCLDSTOP; + sa.sa_handler = sig_term; + sigaction(SIGTERM, &sa, NULL); + sigaction(SIGINT, &sa, NULL); + + sa.sa_handler = SIG_IGN; + sigaction(SIGCHLD, &sa, NULL); + sigaction(SIGPIPE, &sa, NULL); + + enable_debug(); + + /* Create event loop */ + main_loop = g_main_loop_new(NULL, FALSE); + network_init(); + g_main_loop_run(main_loop); + network_exit(); + g_main_loop_unref(main_loop); + + info("Exit"); + + stop_logging(); + return 0; } -- cgit From 29b4c4f802c7e9cfc40d70721f77caf25c409821 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 12 Mar 2007 01:06:47 +0000 Subject: Network: added server methods skeleton --- network/manager.c | 207 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ network/manager.h | 1 + 2 files changed, 208 insertions(+) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 33679a51..ab77cfe0 100644 --- a/network/manager.c +++ b/network/manager.c @@ -25,13 +25,220 @@ #include #endif +#include +#include +#include + +#include + +#include "logging.h" +#include "dbus.h" + +#define NETWORK_PATH "/org/bluez/network" +#define NETWORK_MANAGER_INTERFACE "org.bluez.network.Manager" +#define NETWORK_ERROR_INTERFACE "org.bluez.Error" + #include "manager.h" +struct manager { + bdaddr_t src; /* Local adapter BT address */ + GSList *servers; /* Network registered servers paths */ +}; + +static DBusConnection *connection = NULL; + +static DBusHandlerResult err_unknown_connection(DBusConnection *conn, + DBusMessage *msg) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult list_servers(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult create_server(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult remove_server(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult list_connections(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult create_connection(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult remove_connections(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult manager_message(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + const char *path, *iface, *member; + + path = dbus_message_get_path(msg); + iface = dbus_message_get_interface(msg); + member = dbus_message_get_member(msg); + + /* Catching fallback paths */ + if (strcmp(NETWORK_PATH, path) != 0) + return err_unknown_connection(conn, msg); + + /* Accept messages from the manager interface only */ + if (strcmp(NETWORK_MANAGER_INTERFACE, iface)) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + if (strcmp(member, "ListServers") == 0) + return list_servers(conn, msg, data); + + if (strcmp(member, "CreateServer") == 0) + return create_server(conn, msg, data); + + if (strcmp(member, "RemoveServer") == 0) + return remove_server(conn, msg, data); + + if (strcmp(member, "ListConnections") == 0) + return list_connections(conn, msg, data); + + if (strcmp(member, "CreateConnection") == 0) + return create_connection(conn, msg, data); + + if (strcmp(member, "RemoveConnections") == 0) + return remove_connections(conn, msg, data); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static void manager_free(struct manager *mgr) +{ + if (!mgr) + return; + + g_free (mgr); +} +static void manager_unregister(DBusConnection *conn, void *data) +{ + struct manager *mgr = data; + + info("Unregistered manager path"); + + manager_free(mgr); +} + +/* Virtual table to handle manager object path hierarchy */ +static const DBusObjectPathVTable manager_table = { + .message_function = manager_message, + .unregister_function = manager_unregister, +}; + +int network_dbus_init(void) +{ + struct manager *mgr; + bdaddr_t src; + int dev_id; + + connection = init_dbus(NULL, NULL, NULL); + if (!connection) + return -1; + + dbus_connection_set_exit_on_disconnect(connection, TRUE); + + mgr = g_new0(struct manager, 1); + + /* Fallback to catch invalid device path */ + if (!dbus_connection_register_fallback(connection, NETWORK_PATH, + &manager_table, mgr)) { + error("D-Bus failed to register %s path", NETWORK_PATH); + goto fail; + } + + info("Registered manager path:%s", NETWORK_PATH); + + /* Set the default adapter */ + bacpy(&src, BDADDR_ANY); + dev_id = hci_get_route(&src); + if (dev_id < 0) { + error("Bluetooth device not available"); + goto fail; + } + + if (hci_devba(dev_id, &src) < 0) { + error("Can't get local adapter device info"); + goto fail; + } + + bacpy(&mgr->src, &src); + + return 0; + +fail: + manager_free(mgr); + + return -1; +} + +void network_dbus_exit(void) +{ + dbus_connection_unregister_object_path(connection, NETWORK_PATH); + + dbus_connection_unref(connection); +} + +void internal_service(const char *identifier) +{ + DBusMessage *msg, *reply; + const char *name = "Network service", *desc = ""; + + info("Registering service"); + + msg = dbus_message_new_method_call("org.bluez", "/org/bluez", + "org.bluez.Database", "RegisterService"); + if (!msg) { + error("Can't create service register method"); + return; + } + + dbus_message_append_args(msg, DBUS_TYPE_STRING, &identifier, + DBUS_TYPE_STRING, &name, + DBUS_TYPE_STRING, &desc, DBUS_TYPE_INVALID); + + reply = dbus_connection_send_with_reply_and_block(connection, msg, -1, NULL); + if (!reply) { + error("Can't register service"); + return; + } + + dbus_message_unref(msg); + dbus_message_unref(reply); + + dbus_connection_flush(connection); +} + int network_init(void) { + network_dbus_init(); return 0; } void network_exit(void) { + network_dbus_exit(); } diff --git a/network/manager.h b/network/manager.h index b659d8dc..81467c1a 100644 --- a/network/manager.h +++ b/network/manager.h @@ -23,3 +23,4 @@ int network_init(void); void network_exit(void); +void internal_service(const char *identifier); -- cgit From 6bd2d4e0d8f2a74c1ec87a9de3d00a612e9c7bf7 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 12 Mar 2007 20:15:15 +0000 Subject: Network: support for standalone start mode --- network/main.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'network') diff --git a/network/main.c b/network/main.c index 776ea517..9b201bf2 100644 --- a/network/main.c +++ b/network/main.c @@ -68,6 +68,9 @@ int main(int argc, char *argv[]) network_init(); + if (argc > 1 && !strcmp(argv[1], "-s")) + internal_service("network"); + g_main_loop_run(main_loop); network_exit(); -- cgit From 7e39b983e5cead54bca67953aa92f6ecb4d78fa2 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Tue, 13 Mar 2007 18:20:18 +0000 Subject: Network: Added unknown connection path fallback --- network/manager.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index ab77cfe0..982eb015 100644 --- a/network/manager.c +++ b/network/manager.c @@ -50,7 +50,10 @@ static DBusConnection *connection = NULL; static DBusHandlerResult err_unknown_connection(DBusConnection *conn, DBusMessage *msg) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + return send_message_and_unref(conn, + dbus_message_new_error(msg, + NETWORK_ERROR_INTERFACE ".UnknownConnection", + "Unknown connection path")); } static DBusHandlerResult list_servers(DBusConnection *conn, @@ -134,6 +137,7 @@ static void manager_free(struct manager *mgr) g_free (mgr); } + static void manager_unregister(DBusConnection *conn, void *data) { struct manager *mgr = data; -- cgit From 9411bce4baf65cc7891f6899cb602a96c4ac26b3 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 15 Mar 2007 13:42:30 +0000 Subject: Network: Added ListServers --- network/manager.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 982eb015..8487bbb1 100644 --- a/network/manager.c +++ b/network/manager.c @@ -59,7 +59,30 @@ static DBusHandlerResult err_unknown_connection(DBusConnection *conn, static DBusHandlerResult list_servers(DBusConnection *conn, DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct manager *mgr = data; + DBusMessage *reply; + GSList *l; + DBusMessageIter iter; + DBusMessageIter array_iter; + + 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_TYPE_STRING_AS_STRING, &array_iter); + + for (l = mgr->servers; l; l = l->next) { + const char *server = l->data; + + dbus_message_iter_append_basic(&array_iter, + DBUS_TYPE_STRING, &server); + } + + dbus_message_iter_close_container(&iter, &array_iter); + + return send_message_and_unref(conn, reply); } static DBusHandlerResult create_server(DBusConnection *conn, -- cgit From 74b17da9af9fb4930677000ccbd74495adb3d4c6 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 15 Mar 2007 14:23:47 +0000 Subject: Network: Added network connection methods skeleton --- network/connection.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index bd733cb2..cdcdcbb1 100644 --- a/network/connection.c +++ b/network/connection.c @@ -25,4 +25,131 @@ #include #endif +#include + +#include + +#include "logging.h" +#include "dbus.h" + +#define NETWORK_CONNECTION_INTERFACE "org.bluez.network.Manager" +#define NETWORK_ERROR_INTERFACE "org.bluez.Error" + #include "connection.h" + +struct network_conn { + char *path; +}; + +static DBusHandlerResult get_address(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult get_uuid(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 get_descriptor(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult get_interface(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult connect(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult disconnect(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult is_connected(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static DBusHandlerResult connection_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_CONNECTION_INTERFACE, iface)) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + if (strcmp(member, "GetAddress") == 0) + return get_address(conn, msg, data); + + if (strcmp(member, "GetUUID") == 0) + return get_uuid(conn, msg, data); + + if (strcmp(member, "GetName") == 0) + return get_name(conn, msg, data); + + if (strcmp(member, "GetDescription") == 0) + return get_descriptor(conn, msg, data); + + if (strcmp(member, "GetInterface") == 0) + return get_interface(conn, msg, data); + + if (strcmp(member, "Connect") == 0) + return connect(conn, msg, data); + + if (strcmp(member, "Disconnect") == 0) + return disconnect(conn, msg, data); + + if (strcmp(member, "IsConnected") == 0) + return is_connected(conn, msg, data); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static void connection_free(struct network_conn *nc) +{ + if (!nc) + return; + + if (nc->path) + g_free(nc->path); + + g_free(nc); +} + +static void connection_unregister(DBusConnection *conn, void *data) +{ + struct network_conn *nc = data; + + info("Unregistered connection path %s", nc->path); + + connection_free(nc); +} + +/* Virtual table to handle connection object path hierarchy */ +static const DBusObjectPathVTable connection_table = { + .message_function = connection_message, + .unregister_function = connection_unregister, +}; + -- cgit From 57821cca7bfdb47cd3ddc32e70b6779a4a6cca2d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 16 Mar 2007 18:17:27 +0000 Subject: Add error specific skeleton files --- network/Makefile.am | 3 ++- network/error.c | 28 ++++++++++++++++++++++++++++ network/error.h | 22 ++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 network/error.c create mode 100644 network/error.h (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index ab7fe934..22a7aef3 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -11,7 +11,8 @@ servicedir = $(libdir)/bluetooth noinst_PROGRAMS = bluetoothd-service-network bluetoothd_service_network_SOURCES = main.c \ - manager.h manager.c server.h server.c connection.h connection.c + manager.h manager.c error.h error.c \ + server.h server.c connection.h connection.c LDADD = $(top_builddir)/common/libhelper.a \ @GLIB_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@ diff --git a/network/error.c b/network/error.c new file mode 100644 index 00000000..55c459da --- /dev/null +++ b/network/error.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 "error.h" diff --git a/network/error.h b/network/error.h new file mode 100644 index 00000000..e87dd676 --- /dev/null +++ b/network/error.h @@ -0,0 +1,22 @@ +/* + * + * 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 + * + */ -- cgit From 7ba9c777c7755dc380443f29f41fcd2a61e1b7df Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 16 Mar 2007 19:58:29 +0000 Subject: Add minimal support for bridge creation and removal --- network/Makefile.am | 3 ++- network/bridge.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++++ network/bridge.h | 28 ++++++++++++++++++++ network/main.c | 4 +-- network/manager.c | 17 ++++++++++++ 5 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 network/bridge.c create mode 100644 network/bridge.h (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index 22a7aef3..094f95e8 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -12,7 +12,8 @@ noinst_PROGRAMS = bluetoothd-service-network bluetoothd_service_network_SOURCES = main.c \ manager.h manager.c error.h error.c \ - server.h server.c connection.h connection.c + server.h server.c bridge.h bridge.c \ + connection.h connection.c LDADD = $(top_builddir)/common/libhelper.a \ @GLIB_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@ diff --git a/network/bridge.c b/network/bridge.c new file mode 100644 index 00000000..76c2a507 --- /dev/null +++ b/network/bridge.c @@ -0,0 +1,76 @@ +/* + * + * 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 +#include +#include +#include + +#include +#include + +#include "bridge.h" + +static int bridge_socket = -1; + +int bridge_init(void) +{ + bridge_socket = socket(AF_INET, SOCK_STREAM, 0); + if (bridge_socket < 0) + return -errno; + + return 0; +} + +void bridge_cleanup(void) +{ + close(bridge_socket); + + bridge_socket = -1; +} + +int bridge_create(const char *name) +{ + int err; + + err = ioctl(bridge_socket, SIOCBRADDBR, name); + if (err < 0) + return -errno; + + return 0; +} + +int bridge_remove(const char *name) +{ + int err; + + err = ioctl(bridge_socket, SIOCBRDELBR, name); + if (err < 0) + return -errno; + + return 0; +} diff --git a/network/bridge.h b/network/bridge.h new file mode 100644 index 00000000..45e744d3 --- /dev/null +++ b/network/bridge.h @@ -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 + * + */ + +int bridge_init(void); +void bridge_cleanup(void); + +int bridge_create(const char *name); +int bridge_remove(const char *name); diff --git a/network/main.c b/network/main.c index 9b201bf2..5e8f2739 100644 --- a/network/main.c +++ b/network/main.c @@ -66,11 +66,11 @@ int main(int argc, char *argv[]) /* Create event loop */ main_loop = g_main_loop_new(NULL, FALSE); - network_init(); - if (argc > 1 && !strcmp(argv[1], "-s")) internal_service("network"); + network_init(); + g_main_loop_run(main_loop); network_exit(); diff --git a/network/manager.c b/network/manager.c index 8487bbb1..26ebf57b 100644 --- a/network/manager.c +++ b/network/manager.c @@ -38,6 +38,7 @@ #define NETWORK_MANAGER_INTERFACE "org.bluez.network.Manager" #define NETWORK_ERROR_INTERFACE "org.bluez.Error" +#include "bridge.h" #include "manager.h" struct manager { @@ -262,10 +263,26 @@ void internal_service(const char *identifier) int network_init(void) { network_dbus_init(); + + if (bridge_init() < 0) { + error("Can't init bridge module"); + return -1; + } + + if (bridge_create("pan0") < 0) { + error("Can't create bridge"); + return -1; + } + return 0; } void network_exit(void) { + if (bridge_remove("pan0") < 0) + error("Can't remove bridge"); + + bridge_cleanup(); + network_dbus_exit(); } -- 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') 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 851ad267e554850ae2cbfd486922cbcfb897f8b5 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 19 Mar 2007 13:24:41 +0000 Subject: - Fix standalone init when there is no bluetooth adapter. --- network/connection.c | 26 ++++++++++++++++++++++++++ network/connection.h | 1 + network/main.c | 6 ++++-- network/manager.c | 6 ++---- 4 files changed, 33 insertions(+), 6 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index cdcdcbb1..4966a7e1 100644 --- a/network/connection.c +++ b/network/connection.c @@ -33,6 +33,7 @@ #include "dbus.h" #define NETWORK_CONNECTION_INTERFACE "org.bluez.network.Manager" +#define NETWORK_CONNECTION_PATH "/org/bluez/network/connection" #define NETWORK_ERROR_INTERFACE "org.bluez.Error" #include "connection.h" @@ -153,3 +154,28 @@ static const DBusObjectPathVTable connection_table = { .unregister_function = connection_unregister, }; +int connection_register(DBusConnection *conn, const char *path) +{ + struct network_conn *nc; + static int nc_uid = 0; + + if (!conn) + return -1; + + nc = g_new0(struct network_conn, 1); + + /* register path */ + if (!dbus_connection_register_object_path(conn, path, + &connection_table, nc)) { + error("D-Bus failed to register %s path", path); + goto fail; + } + + nc->path = g_strdup(path); + info("Registered connection path:%s", path); + + return 0; +fail: + connection_free(nc); + return -1; +} diff --git a/network/connection.h b/network/connection.h index e87dd676..b2dc2ab3 100644 --- a/network/connection.h +++ b/network/connection.h @@ -20,3 +20,4 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ +int connection_register(DBusConnection *conn, const char *path); diff --git a/network/main.c b/network/main.c index 5e8f2739..d0daf429 100644 --- a/network/main.c +++ b/network/main.c @@ -66,15 +66,17 @@ int main(int argc, char *argv[]) /* Create event loop */ main_loop = g_main_loop_new(NULL, FALSE); + if (network_init() == -1) + goto fail; + if (argc > 1 && !strcmp(argv[1], "-s")) internal_service("network"); - network_init(); - g_main_loop_run(main_loop); network_exit(); +fail: g_main_loop_unref(main_loop); info("Exit"); diff --git a/network/manager.c b/network/manager.c index 26ebf57b..e0265af7 100644 --- a/network/manager.c +++ b/network/manager.c @@ -191,7 +191,7 @@ int network_dbus_init(void) mgr = g_new0(struct manager, 1); - /* Fallback to catch invalid device path */ + /* Fallback to catch invalid network path */ if (!dbus_connection_register_fallback(connection, NETWORK_PATH, &manager_table, mgr)) { error("D-Bus failed to register %s path", NETWORK_PATH); @@ -262,8 +262,6 @@ void internal_service(const char *identifier) int network_init(void) { - network_dbus_init(); - if (bridge_init() < 0) { error("Can't init bridge module"); return -1; @@ -274,7 +272,7 @@ int network_init(void) return -1; } - return 0; + return network_dbus_init(); } void network_exit(void) -- 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/connection.c | 4 +--- network/error.c | 12 ++++++++++++ network/error.h | 6 ++++++ network/manager.c | 12 +----------- network/server.c | 25 +++++++++++++++++++++++++ network/server.h | 1 + 6 files changed, 46 insertions(+), 14 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 4966a7e1..e6d4d221 100644 --- a/network/connection.c +++ b/network/connection.c @@ -31,10 +31,9 @@ #include "logging.h" #include "dbus.h" +#include "error.h" #define NETWORK_CONNECTION_INTERFACE "org.bluez.network.Manager" -#define NETWORK_CONNECTION_PATH "/org/bluez/network/connection" -#define NETWORK_ERROR_INTERFACE "org.bluez.Error" #include "connection.h" @@ -157,7 +156,6 @@ static const DBusObjectPathVTable connection_table = { int connection_register(DBusConnection *conn, const char *path) { struct network_conn *nc; - static int nc_uid = 0; if (!conn) return -1; diff --git a/network/error.c b/network/error.c index 55c459da..8c0924d5 100644 --- a/network/error.c +++ b/network/error.c @@ -26,3 +26,15 @@ #endif #include "error.h" + +#define NETWORK_ERROR_INTERFACE "org.bluez.Error" + +DBusHandlerResult err_unknown_connection(DBusConnection *conn, + DBusMessage *msg) +{ + return send_message_and_unref(conn, + dbus_message_new_error(msg, + NETWORK_ERROR_INTERFACE ".UnknownConnection", + "Unknown connection path")); +} + diff --git a/network/error.h b/network/error.h index e87dd676..3572bf27 100644 --- a/network/error.h +++ b/network/error.h @@ -20,3 +20,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ + +#include "dbus.h" + +DBusHandlerResult err_unknown_connection(DBusConnection *conn, + DBusMessage *msg); + diff --git a/network/manager.c b/network/manager.c index e0265af7..e10a4e33 100644 --- a/network/manager.c +++ b/network/manager.c @@ -32,12 +32,11 @@ #include #include "logging.h" -#include "dbus.h" #define NETWORK_PATH "/org/bluez/network" #define NETWORK_MANAGER_INTERFACE "org.bluez.network.Manager" -#define NETWORK_ERROR_INTERFACE "org.bluez.Error" +#include "error.h" #include "bridge.h" #include "manager.h" @@ -48,15 +47,6 @@ struct manager { static DBusConnection *connection = NULL; -static DBusHandlerResult err_unknown_connection(DBusConnection *conn, - DBusMessage *msg) -{ - return send_message_and_unref(conn, - dbus_message_new_error(msg, - NETWORK_ERROR_INTERFACE ".UnknownConnection", - "Unknown connection path")); -} - static DBusHandlerResult list_servers(DBusConnection *conn, DBusMessage *msg, void *data) { 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; +} diff --git a/network/server.h b/network/server.h index e87dd676..33f997a9 100644 --- a/network/server.h +++ b/network/server.h @@ -20,3 +20,4 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ +int server_register(DBusConnection *conn, const char *path); -- cgit From d56a98ac7b81e416b7f9e43ae7dfcb7b6a573dd1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 19 Mar 2007 19:17:33 +0000 Subject: Add skeleton for HAL support --- network/Makefile.am | 2 +- network/hal.c | 37 +++++++++++++++++++++++++++++++++++++ network/hal.h | 25 +++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 network/hal.c create mode 100644 network/hal.h (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index 094f95e8..aa3412b6 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -13,7 +13,7 @@ noinst_PROGRAMS = bluetoothd-service-network bluetoothd_service_network_SOURCES = main.c \ manager.h manager.c error.h error.c \ server.h server.c bridge.h bridge.c \ - connection.h connection.c + hal.h hal.c connection.h connection.c LDADD = $(top_builddir)/common/libhelper.a \ @GLIB_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@ diff --git a/network/hal.c b/network/hal.c new file mode 100644 index 00000000..f024282e --- /dev/null +++ b/network/hal.c @@ -0,0 +1,37 @@ +/* + * + * 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 "hal.h" + +int hal_init(void) +{ + return 0; +} + +void hal_cleanup(void) +{ +} diff --git a/network/hal.h b/network/hal.h new file mode 100644 index 00000000..769f203b --- /dev/null +++ b/network/hal.h @@ -0,0 +1,25 @@ +/* + * + * 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 + * + */ + +int hal_init(void); +void hal_cleanup(void); -- cgit From 37ca3ab5974892ba7a4a87420a70bafa070db812 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 19 Mar 2007 19:27:28 +0000 Subject: Check for HAL support --- network/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index aa3412b6..686fad9a 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -16,10 +16,10 @@ bluetoothd_service_network_SOURCES = main.c \ hal.h hal.c connection.h connection.c LDADD = $(top_builddir)/common/libhelper.a \ - @GLIB_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@ + @GLIB_LIBS@ @HAL_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@ endif -AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ @GLIB_CFLAGS@ +AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ @HAL_CFLAGS@ @GLIB_CFLAGS@ INCLUDES = -I$(top_srcdir)/common -- cgit From e867e1dc937eedbaa3ac7f678f4703fab78d2d4e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 19 Mar 2007 19:46:43 +0000 Subject: Try to init the HAL context --- network/hal.c | 36 +++++++++++++++++++++++++++++++++++- network/hal.h | 4 +++- network/main.c | 5 +++++ 3 files changed, 43 insertions(+), 2 deletions(-) (limited to 'network') diff --git a/network/hal.c b/network/hal.c index f024282e..79e2b6e5 100644 --- a/network/hal.c +++ b/network/hal.c @@ -25,13 +25,47 @@ #include #endif +#include + +#include +#include + +#include "logging.h" + #include "hal.h" -int hal_init(void) +static LibHalContext *hal_ctx = NULL; + +int hal_init(DBusConnection *conn) { + hal_ctx = libhal_ctx_new(); + if (!hal_ctx) + return -ENOMEM; + + if (libhal_ctx_set_dbus_connection(hal_ctx, conn) == FALSE) { + libhal_ctx_free(hal_ctx); + hal_ctx = NULL; + return -EIO; + } + + if (libhal_ctx_init(hal_ctx, NULL) == FALSE) { + error("Unable to init HAL context"); + libhal_ctx_free(hal_ctx); + hal_ctx = NULL; + return -EIO; + } + return 0; } void hal_cleanup(void) { + if (!hal_ctx) + return; + + libhal_ctx_shutdown(hal_ctx, NULL); + + libhal_ctx_free(hal_ctx); + + hal_ctx = NULL; } diff --git a/network/hal.h b/network/hal.h index 769f203b..f664e143 100644 --- a/network/hal.h +++ b/network/hal.h @@ -21,5 +21,7 @@ * */ -int hal_init(void); +#include + +int hal_init(DBusConnection *conn); void hal_cleanup(void); diff --git a/network/main.c b/network/main.c index d0daf429..607285f7 100644 --- a/network/main.c +++ b/network/main.c @@ -37,6 +37,7 @@ #include "logging.h" #include "manager.h" +#include "hal.h" static GMainLoop *main_loop; @@ -66,6 +67,8 @@ int main(int argc, char *argv[]) /* Create event loop */ main_loop = g_main_loop_new(NULL, FALSE); + hal_init(NULL); + if (network_init() == -1) goto fail; @@ -76,6 +79,8 @@ int main(int argc, char *argv[]) network_exit(); + hal_cleanup(); + fail: g_main_loop_unref(main_loop); -- cgit From fc191be1958b3d290e061b6af6f0f25ce27fcf1f Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 19 Mar 2007 20:04:00 +0000 Subject: Work around the missing D-Bus system bus --- network/hal.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'network') diff --git a/network/hal.c b/network/hal.c index 79e2b6e5..658e5f8c 100644 --- a/network/hal.c +++ b/network/hal.c @@ -31,6 +31,7 @@ #include #include "logging.h" +#include "dbus.h" #include "hal.h" @@ -42,7 +43,10 @@ int hal_init(DBusConnection *conn) if (!hal_ctx) return -ENOMEM; + conn = init_dbus(NULL, NULL, NULL); + if (libhal_ctx_set_dbus_connection(hal_ctx, conn) == FALSE) { + error("Failed to connect HAL via system bus"); libhal_ctx_free(hal_ctx); hal_ctx = NULL; return -EIO; -- cgit From faaa78e8988895aecf12f5ef113d3683c7986999 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 19 Mar 2007 20:14:37 +0000 Subject: Add HAL device for testing --- network/hal.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'network') diff --git a/network/hal.c b/network/hal.c index 658e5f8c..a99dcd9e 100644 --- a/network/hal.c +++ b/network/hal.c @@ -25,6 +25,7 @@ #include #endif +#include #include #include @@ -39,6 +40,8 @@ static LibHalContext *hal_ctx = NULL; int hal_init(DBusConnection *conn) { + char str[64], *udi; + hal_ctx = libhal_ctx_new(); if (!hal_ctx) return -ENOMEM; @@ -59,6 +62,14 @@ int hal_init(DBusConnection *conn) return -EIO; } + udi = libhal_new_device(hal_ctx, NULL); + + sprintf(str, "/org/freedesktop/Hal/devices/bluetooth_pan"); + + if (libhal_device_commit_to_gdl(hal_ctx, udi, str, NULL) == FALSE) { + error("Failed to add new HAL device"); + } + return 0; } -- cgit From 6e2ea33ba70a7d6b6ffa614a8fe57fe7662b7c70 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 20 Mar 2007 14:48:00 +0000 Subject: Create a common HAL abstraction layer --- network/Makefile.am | 2 +- network/hal.c | 86 ----------------------------------------------------- network/hal.h | 27 ----------------- 3 files changed, 1 insertion(+), 114 deletions(-) delete mode 100644 network/hal.c delete mode 100644 network/hal.h (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index 686fad9a..65dfde44 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -13,7 +13,7 @@ noinst_PROGRAMS = bluetoothd-service-network bluetoothd_service_network_SOURCES = main.c \ manager.h manager.c error.h error.c \ server.h server.c bridge.h bridge.c \ - hal.h hal.c connection.h connection.c + connection.h connection.c LDADD = $(top_builddir)/common/libhelper.a \ @GLIB_LIBS@ @HAL_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@ diff --git a/network/hal.c b/network/hal.c deleted file mode 100644 index a99dcd9e..00000000 --- a/network/hal.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * - * 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 -#include - -#include -#include - -#include "logging.h" -#include "dbus.h" - -#include "hal.h" - -static LibHalContext *hal_ctx = NULL; - -int hal_init(DBusConnection *conn) -{ - char str[64], *udi; - - hal_ctx = libhal_ctx_new(); - if (!hal_ctx) - return -ENOMEM; - - conn = init_dbus(NULL, NULL, NULL); - - if (libhal_ctx_set_dbus_connection(hal_ctx, conn) == FALSE) { - error("Failed to connect HAL via system bus"); - libhal_ctx_free(hal_ctx); - hal_ctx = NULL; - return -EIO; - } - - if (libhal_ctx_init(hal_ctx, NULL) == FALSE) { - error("Unable to init HAL context"); - libhal_ctx_free(hal_ctx); - hal_ctx = NULL; - return -EIO; - } - - udi = libhal_new_device(hal_ctx, NULL); - - sprintf(str, "/org/freedesktop/Hal/devices/bluetooth_pan"); - - if (libhal_device_commit_to_gdl(hal_ctx, udi, str, NULL) == FALSE) { - error("Failed to add new HAL device"); - } - - return 0; -} - -void hal_cleanup(void) -{ - if (!hal_ctx) - return; - - libhal_ctx_shutdown(hal_ctx, NULL); - - libhal_ctx_free(hal_ctx); - - hal_ctx = NULL; -} diff --git a/network/hal.h b/network/hal.h deleted file mode 100644 index f664e143..00000000 --- a/network/hal.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * - * 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 - * - */ - -#include - -int hal_init(DBusConnection *conn); -void hal_cleanup(void); -- 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/error.c | 14 +++++++++++ network/error.h | 5 +++- network/manager.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- network/server.c | 2 +- 4 files changed, 86 insertions(+), 4 deletions(-) (limited to 'network') diff --git a/network/error.c b/network/error.c index 8c0924d5..50d33bc9 100644 --- a/network/error.c +++ b/network/error.c @@ -38,3 +38,17 @@ DBusHandlerResult err_unknown_connection(DBusConnection *conn, "Unknown connection path")); } +DBusHandlerResult err_generic(DBusConnection *conn, DBusMessage *msg, + const char *name, const char *str) +{ + return send_message_and_unref(conn, + dbus_message_new_error(msg, name, str)); +} + +DBusHandlerResult err_does_not_exist(DBusConnection *conn, DBusMessage *msg, + const char *str) +{ + return send_message_and_unref(conn, + dbus_message_new_error(msg, + NETWORK_ERROR_INTERFACE ".DoesNotExist", str)); +} diff --git a/network/error.h b/network/error.h index 3572bf27..ad7ecfeb 100644 --- a/network/error.h +++ b/network/error.h @@ -25,4 +25,7 @@ DBusHandlerResult err_unknown_connection(DBusConnection *conn, DBusMessage *msg); - +DBusHandlerResult err_generic(DBusConnection *conn, DBusMessage *msg, + const char *name, const char *str); +DBusHandlerResult err_does_not_exist(DBusConnection *conn, DBusMessage *msg, + const char *str); diff --git a/network/manager.c b/network/manager.c index e10a4e33..91e71c37 100644 --- a/network/manager.c +++ b/network/manager.c @@ -32,6 +32,7 @@ #include #include "logging.h" +#include "dbus.h" #define NETWORK_PATH "/org/bluez/network" #define NETWORK_MANAGER_INTERFACE "org.bluez.network.Manager" @@ -39,6 +40,7 @@ #include "error.h" #include "bridge.h" #include "manager.h" +#include "server.h" struct manager { bdaddr_t src; /* Local adapter BT address */ @@ -79,13 +81,73 @@ static DBusHandlerResult list_servers(DBusConnection *conn, static DBusHandlerResult create_server(DBusConnection *conn, DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct manager *mgr = data; + DBusMessage *reply; + DBusError derr; + const char *uuid; + char *path; + + dbus_error_init(&derr); + if (!dbus_message_get_args(msg, &derr, + DBUS_TYPE_STRING, &uuid, + DBUS_TYPE_INVALID)) { + err_generic(conn, msg, derr.name, derr.message); + dbus_error_free(&derr); + return DBUS_HANDLER_RESULT_HANDLED; + } + + path = g_new0(char, 32); + snprintf(path, 32, NETWORK_PATH "/server/%s", uuid); + if (!g_slist_find_custom(mgr->servers, path, (GCompareFunc) strcmp)) { + if (server_register(conn, path) != -1) { + mgr->servers = g_slist_append(mgr->servers, + g_strdup(path)); + } + } + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_message_append_args(reply, DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); + + g_free(path); + return send_message_and_unref(connection, reply); } static DBusHandlerResult remove_server(DBusConnection *conn, DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct manager *mgr = data; + const char *path; + DBusMessage *reply; + DBusError derr; + GSList *l; + + dbus_error_init(&derr); + if (!dbus_message_get_args(msg, &derr, + DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID)) { + err_generic(conn, msg, derr.name, derr.message); + dbus_error_free(&derr); + return DBUS_HANDLER_RESULT_HANDLED; + } + + l = g_slist_find_custom(mgr->servers, path, (GCompareFunc) strcmp); + if (!l) + return err_does_not_exist(conn, msg, "Server doesn't exist"); + + mgr->servers = g_slist_remove(mgr->servers, l->data); + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + if (!dbus_connection_unregister_object_path(conn, path)) + error("Network server path unregister failed"); + + return send_message_and_unref(conn, reply); } static DBusHandlerResult list_connections(DBusConnection *conn, @@ -149,6 +211,9 @@ static void manager_free(struct manager *mgr) if (!mgr) return; + if (mgr->servers) + g_slist_free(mgr->servers); + g_free (mgr); } 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 ad5740f56965f3fc003b704fe41e80fe1e53434d Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 20 Mar 2007 19:59:55 +0000 Subject: Initial code of CreateConnection and RemoveConnection methods. --- network/manager.c | 100 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 79 insertions(+), 21 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 91e71c37..4d17bfc1 100644 --- a/network/manager.c +++ b/network/manager.c @@ -41,20 +41,20 @@ #include "bridge.h" #include "manager.h" #include "server.h" +#include "connection.h" struct manager { bdaddr_t src; /* Local adapter BT address */ GSList *servers; /* Network registered servers paths */ + GSList *connections; /* Network registered connections paths */ }; static DBusConnection *connection = NULL; -static DBusHandlerResult list_servers(DBusConnection *conn, - DBusMessage *msg, void *data) +static DBusHandlerResult list_paths(DBusConnection *conn, DBusMessage *msg, + GSList *list) { - struct manager *mgr = data; DBusMessage *reply; - GSList *l; DBusMessageIter iter; DBusMessageIter array_iter; @@ -66,11 +66,12 @@ static DBusHandlerResult list_servers(DBusConnection *conn, dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &array_iter); - for (l = mgr->servers; l; l = l->next) { - const char *server = l->data; - - dbus_message_iter_append_basic(&array_iter, - DBUS_TYPE_STRING, &server); + if (g_slist_length(list)) { + for (; list; list = list->next) { + dbus_message_iter_append_basic(&array_iter, + DBUS_TYPE_STRING, + &list->data); + } } dbus_message_iter_close_container(&iter, &array_iter); @@ -78,6 +79,14 @@ static DBusHandlerResult list_servers(DBusConnection *conn, return send_message_and_unref(conn, reply); } +static DBusHandlerResult list_servers(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + struct manager *mgr = data; + + return list_paths(conn, msg, mgr->servers); +} + static DBusHandlerResult create_server(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -116,10 +125,9 @@ static DBusHandlerResult create_server(DBusConnection *conn, return send_message_and_unref(connection, reply); } -static DBusHandlerResult remove_server(DBusConnection *conn, - DBusMessage *msg, void *data) +static DBusHandlerResult remove_path(DBusConnection *conn, + DBusMessage *msg, GSList **list) { - struct manager *mgr = data; const char *path; DBusMessage *reply; DBusError derr; @@ -134,11 +142,12 @@ static DBusHandlerResult remove_server(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } - l = g_slist_find_custom(mgr->servers, path, (GCompareFunc) strcmp); + l = g_slist_find_custom(*list, path, (GCompareFunc) strcmp); if (!l) return err_does_not_exist(conn, msg, "Server doesn't exist"); - mgr->servers = g_slist_remove(mgr->servers, l->data); + g_free(l->data); + *list = g_slist_remove(*list, l->data); reply = dbus_message_new_method_return(msg); if (!reply) @@ -150,22 +159,67 @@ static DBusHandlerResult remove_server(DBusConnection *conn, return send_message_and_unref(conn, reply); } +static DBusHandlerResult remove_server(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + struct manager *mgr = data; + + return remove_path(conn, msg, &mgr->servers); +} + static DBusHandlerResult list_connections(DBusConnection *conn, DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct manager *mgr = data; + + return list_paths(conn, msg, mgr->connections); } static DBusHandlerResult create_connection(DBusConnection *conn, DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct manager *mgr = data; + static int uid = 0; + DBusMessage *reply; + DBusError derr; + const char *addr; + const char *uuid; + char *path; + + dbus_error_init(&derr); + if (!dbus_message_get_args(msg, &derr, + DBUS_TYPE_STRING, &addr, + DBUS_TYPE_STRING, &uuid, + DBUS_TYPE_INVALID)) { + err_generic(conn, msg, derr.name, derr.message); + dbus_error_free(&derr); + return DBUS_HANDLER_RESULT_HANDLED; + } + + path = g_new0(char, 32); + snprintf(path, 32, NETWORK_PATH "/connection%d", uid++); + if (connection_register(conn, path) != -1) { + mgr->connections = g_slist_append(mgr->connections, + g_strdup(path)); + } + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_message_append_args(reply, DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); + + g_free(path); + return send_message_and_unref(connection, reply); } -static DBusHandlerResult remove_connections(DBusConnection *conn, +static DBusHandlerResult remove_connection(DBusConnection *conn, DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct manager *mgr = data; + + return remove_path(conn, msg, &mgr->connections); } static DBusHandlerResult manager_message(DBusConnection *conn, @@ -200,8 +254,8 @@ static DBusHandlerResult manager_message(DBusConnection *conn, if (strcmp(member, "CreateConnection") == 0) return create_connection(conn, msg, data); - if (strcmp(member, "RemoveConnections") == 0) - return remove_connections(conn, msg, data); + if (strcmp(member, "RemoveConnection") == 0) + return remove_connection(conn, msg, data); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } @@ -214,6 +268,9 @@ static void manager_free(struct manager *mgr) if (mgr->servers) g_slist_free(mgr->servers); + if (mgr->connections) + g_slist_free(mgr->connections); + g_free (mgr); } @@ -303,7 +360,8 @@ void internal_service(const char *identifier) DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &desc, DBUS_TYPE_INVALID); - reply = dbus_connection_send_with_reply_and_block(connection, msg, -1, NULL); + reply = dbus_connection_send_with_reply_and_block(connection, msg, -1, + NULL); if (!reply) { error("Can't register service"); return; -- cgit From 833ce8edc2b4cde819a2aa7efb8e562958c48acd Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 21 Mar 2007 14:24:15 +0000 Subject: Implement generic HAL device helpers --- network/main.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'network') diff --git a/network/main.c b/network/main.c index 607285f7..d6c3ac0d 100644 --- a/network/main.c +++ b/network/main.c @@ -69,6 +69,8 @@ int main(int argc, char *argv[]) hal_init(NULL); + hal_add_device(NULL); + if (network_init() == -1) goto 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/connection.c | 15 ++++++-- network/connection.h | 3 +- network/error.c | 8 ++++ network/error.h | 3 ++ network/manager.c | 107 ++++++++++++++++++++++++++++++++------------------- network/server.c | 2 +- 6 files changed, 94 insertions(+), 44 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index e6d4d221..c1544b58 100644 --- a/network/connection.c +++ b/network/connection.c @@ -38,7 +38,10 @@ #include "connection.h" struct network_conn { + char *raddr; char *path; + char *uuid; + gboolean up; }; static DBusHandlerResult get_address(DBusConnection *conn, DBusMessage *msg, @@ -135,6 +138,9 @@ static void connection_free(struct network_conn *nc) if (nc->path) g_free(nc->path); + if (nc->uuid) + g_free(nc->uuid); + g_free(nc); } @@ -142,7 +148,7 @@ static void connection_unregister(DBusConnection *conn, void *data) { struct network_conn *nc = data; - info("Unregistered connection path %s", nc->path); + info("Unregistered connection path:%s", nc->path); connection_free(nc); } @@ -153,7 +159,8 @@ static const DBusObjectPathVTable connection_table = { .unregister_function = connection_unregister, }; -int connection_register(DBusConnection *conn, const char *path) +int connection_register(DBusConnection *conn, const char *path, + const char *addr, const char *uuid) { struct network_conn *nc; @@ -170,8 +177,10 @@ int connection_register(DBusConnection *conn, const char *path) } nc->path = g_strdup(path); + nc->raddr = g_strdup(addr); + nc->uuid = g_strdup(uuid); + nc->up = FALSE; info("Registered connection path:%s", path); - return 0; fail: connection_free(nc); diff --git a/network/connection.h b/network/connection.h index b2dc2ab3..0726ec6c 100644 --- a/network/connection.h +++ b/network/connection.h @@ -20,4 +20,5 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ -int connection_register(DBusConnection *conn, const char *path); +int connection_register(DBusConnection *conn, const char *path, + const char *addr, const char *uuid); diff --git a/network/error.c b/network/error.c index 50d33bc9..28bd54ae 100644 --- a/network/error.c +++ b/network/error.c @@ -52,3 +52,11 @@ DBusHandlerResult err_does_not_exist(DBusConnection *conn, DBusMessage *msg, dbus_message_new_error(msg, NETWORK_ERROR_INTERFACE ".DoesNotExist", str)); } + +DBusHandlerResult err_failed(DBusConnection *conn, DBusMessage *msg, + const char *str) +{ + return send_message_and_unref(conn, + dbus_message_new_error(msg, + NETWORK_ERROR_INTERFACE ".Failed", str)); +} diff --git a/network/error.h b/network/error.h index ad7ecfeb..63f6ffde 100644 --- a/network/error.h +++ b/network/error.h @@ -29,3 +29,6 @@ DBusHandlerResult err_generic(DBusConnection *conn, DBusMessage *msg, const char *name, const char *str); DBusHandlerResult err_does_not_exist(DBusConnection *conn, DBusMessage *msg, const char *str); +DBusHandlerResult err_failed(DBusConnection *conn, DBusMessage *msg, + const char *str); + diff --git a/network/manager.c b/network/manager.c index 4d17bfc1..42853811 100644 --- a/network/manager.c +++ b/network/manager.c @@ -66,12 +66,10 @@ static DBusHandlerResult list_paths(DBusConnection *conn, DBusMessage *msg, dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, DBUS_TYPE_STRING_AS_STRING, &array_iter); - if (g_slist_length(list)) { - for (; list; list = list->next) { - dbus_message_iter_append_basic(&array_iter, - DBUS_TYPE_STRING, - &list->data); - } + for (; list; list = list->next) { + dbus_message_iter_append_basic(&array_iter, + DBUS_TYPE_STRING, + &list->data); } dbus_message_iter_close_container(&iter, &array_iter); @@ -87,11 +85,39 @@ static DBusHandlerResult list_servers(DBusConnection *conn, DBusMessage *msg, return list_paths(conn, msg, mgr->servers); } +static DBusHandlerResult create_path(DBusConnection *conn, + DBusMessage *msg, char *path, + const char *sname) +{ + DBusMessage *reply, *signal; + + /* emit signal when it is a new path */ + if (sname) { + signal = dbus_message_new_signal(NETWORK_PATH, + NETWORK_MANAGER_INTERFACE, sname); + + dbus_message_append_args(signal, + DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); + + send_message_and_unref(conn, signal); + } + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_message_append_args(reply, DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); + + g_free(path); + return send_message_and_unref(conn, reply); +} + static DBusHandlerResult create_server(DBusConnection *conn, DBusMessage *msg, void *data) { struct manager *mgr = data; - DBusMessage *reply; DBusError derr; const char *uuid; char *path; @@ -107,29 +133,28 @@ static DBusHandlerResult create_server(DBusConnection *conn, path = g_new0(char, 32); snprintf(path, 32, NETWORK_PATH "/server/%s", uuid); - if (!g_slist_find_custom(mgr->servers, path, (GCompareFunc) strcmp)) { - if (server_register(conn, path) != -1) { - mgr->servers = g_slist_append(mgr->servers, - g_strdup(path)); - } - } - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + /* Path already registered */ + if (g_slist_find_custom(mgr->servers, path, (GCompareFunc) strcmp)) + return create_path(conn, msg, path, NULL); - dbus_message_append_args(reply, DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); + if (server_register(conn, path) == -1) { + err_failed(conn, msg, "D-Bus path registration failed"); + g_free(path); + return DBUS_HANDLER_RESULT_HANDLED; + } - g_free(path); - return send_message_and_unref(connection, reply); + mgr->servers = g_slist_append(mgr->servers, g_strdup(path)); + + return create_path(conn, msg, path, "ServerCreated"); } static DBusHandlerResult remove_path(DBusConnection *conn, - DBusMessage *msg, GSList **list) + DBusMessage *msg, GSList **list, + const char *sname) { const char *path; - DBusMessage *reply; + DBusMessage *reply, *signal; DBusError derr; GSList *l; @@ -144,7 +169,7 @@ static DBusHandlerResult remove_path(DBusConnection *conn, l = g_slist_find_custom(*list, path, (GCompareFunc) strcmp); if (!l) - return err_does_not_exist(conn, msg, "Server doesn't exist"); + return err_does_not_exist(conn, msg, "Path doesn't exist"); g_free(l->data); *list = g_slist_remove(*list, l->data); @@ -154,7 +179,16 @@ static DBusHandlerResult remove_path(DBusConnection *conn, return DBUS_HANDLER_RESULT_NEED_MEMORY; if (!dbus_connection_unregister_object_path(conn, path)) - error("Network server path unregister failed"); + error("Network path unregister failed"); + + signal = dbus_message_new_signal(NETWORK_PATH, + NETWORK_MANAGER_INTERFACE, sname); + + dbus_message_append_args(signal, + DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); + + send_message_and_unref(conn, signal); return send_message_and_unref(conn, reply); } @@ -164,7 +198,7 @@ static DBusHandlerResult remove_server(DBusConnection *conn, { struct manager *mgr = data; - return remove_path(conn, msg, &mgr->servers); + return remove_path(conn, msg, &mgr->servers, "ServerRemoved"); } static DBusHandlerResult list_connections(DBusConnection *conn, @@ -180,7 +214,6 @@ static DBusHandlerResult create_connection(DBusConnection *conn, { struct manager *mgr = data; static int uid = 0; - DBusMessage *reply; DBusError derr; const char *addr; const char *uuid; @@ -198,20 +231,16 @@ static DBusHandlerResult create_connection(DBusConnection *conn, path = g_new0(char, 32); snprintf(path, 32, NETWORK_PATH "/connection%d", uid++); - if (connection_register(conn, path) != -1) { - mgr->connections = g_slist_append(mgr->connections, - g_strdup(path)); - } - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + if (connection_register(conn, path, addr, uuid) == -1) { + err_failed(conn, msg, "D-Bus path registration failed"); + g_free(path); + return DBUS_HANDLER_RESULT_HANDLED; + } - dbus_message_append_args(reply, DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); + mgr->connections = g_slist_append(mgr->connections, g_strdup(path)); - g_free(path); - return send_message_and_unref(connection, reply); + return create_path(conn, msg, path, "ConnectionCreated"); } static DBusHandlerResult remove_connection(DBusConnection *conn, @@ -219,7 +248,7 @@ static DBusHandlerResult remove_connection(DBusConnection *conn, { struct manager *mgr = data; - return remove_path(conn, msg, &mgr->connections); + return remove_path(conn, msg, &mgr->connections, "ConnectionRemoved"); } static DBusHandlerResult manager_message(DBusConnection *conn, @@ -360,7 +389,7 @@ void internal_service(const char *identifier) DBUS_TYPE_STRING, &name, DBUS_TYPE_STRING, &desc, DBUS_TYPE_INVALID); - reply = dbus_connection_send_with_reply_and_block(connection, msg, -1, + reply = dbus_connection_send_with_reply_and_block(connection, msg, -1, NULL); if (!reply) { error("Can't register service"); 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 912bb20c21691117acac343003fd0b4c61366db6 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 21 Mar 2007 18:36:53 +0000 Subject: network: added network API description skeleton --- network/network-api.txt | 106 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 105 insertions(+), 1 deletion(-) (limited to 'network') diff --git a/network/network-api.txt b/network/network-api.txt index f10e676a..c38b3e63 100644 --- a/network/network-api.txt +++ b/network/network-api.txt @@ -7,6 +7,110 @@ Copyright (C) 2006-2007 Marcel Holtmann Network Manager hierarchy ========================= -Service org.bluez.network Interface org.bluez.network.Manager Object path /org/bluez/network + +Methods string CreateServer(string uuid) + + Creates a network server object(GN or NAP). + + Possible errors: TBD + + void RemoveServer(string path) + Removes the network server object for given path. + + Possible errors: TBD + + array{string} ListServers() + + Returns an array of available network devices paths. + Currently only NAP and GN are supported. + + string CreateConnection(string address, string uuid) + + Creates a network connection object(NAP or GN). + + string RemoveConnection(string path) + + Removes a network connection object for a given path. + + Possible errors: TBD + + array{string} ListConnections() + + Returns an array of available network connections paths. + +Signals + + void ServerCreated(string path) + + void ServerRemoved(string path) + + void ConnectionCreated(string path) + + void ConnectionRemoved(string path) + +Network Server hierarchy (experimental) +======================================= + +Interface org.bluez.network.Server +Object path /org/bluez/network/server* + +Methods string GetUUID() + Returns the uuid 128 string representation of the server. + + void Enable() // do this automatically? + void Disable() // do this automatically? + void SetName(string name) + + Sets the name attribute. + + string GetName() + Returns the service name. + + void SetAddressRange(string start, string end) + TBD + + void SetRouting(string interface) + TBD + + void SetSecurity(bool enable) + TBD + + bool GetSecurity() + TBD + +Signals + +Network Connection hierarchy (experimental) +=========================================== + +Interface org.bluez.network.Connection +Object path /org/bluez/network/connection* + +Methods string GetAddress() + Returns the Bluetooth address of the ending point. + + string GetUUID() + Returns the uuid 128 string representation of + the connected service. + + string GetName() + TBD + + string GetDescription() + TBD + + string GetInterface() + TBD + + void Connect() + TBD + + void Disconnect() + TBD + + bool IsConnected() + Returns the connection status. + +Signals -- cgit From 4128274b3b8c47a58f6895e1dbe5b1949887b9e1 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 21 Mar 2007 19:35:35 +0000 Subject: Add functions for creating and removing HAL devices --- network/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'network') diff --git a/network/main.c b/network/main.c index d6c3ac0d..16a173c5 100644 --- a/network/main.c +++ b/network/main.c @@ -69,7 +69,7 @@ int main(int argc, char *argv[]) hal_init(NULL); - hal_add_device(NULL); + hal_create_device(NULL); if (network_init() == -1) goto fail; @@ -81,6 +81,8 @@ int main(int argc, char *argv[]) network_exit(); + hal_remove_device(NULL); + hal_cleanup(); fail: -- cgit From e8b263fa47a9d33ed8fc48f51d44a5ece0cc8e7b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 21 Mar 2007 20:28:55 +0000 Subject: Add file for shared functions --- network/Makefile.am | 2 +- network/common.c | 28 ++++++++++++++++++++++++++++ network/common.h | 22 ++++++++++++++++++++++ 3 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 network/common.c create mode 100644 network/common.h (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index 65dfde44..a9fd2f60 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -13,7 +13,7 @@ noinst_PROGRAMS = bluetoothd-service-network bluetoothd_service_network_SOURCES = main.c \ manager.h manager.c error.h error.c \ server.h server.c bridge.h bridge.c \ - connection.h connection.c + connection.h connection.c common.h common.c LDADD = $(top_builddir)/common/libhelper.a \ @GLIB_LIBS@ @HAL_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@ diff --git a/network/common.c b/network/common.c new file mode 100644 index 00000000..8e5043cc --- /dev/null +++ b/network/common.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 "common.h" diff --git a/network/common.h b/network/common.h new file mode 100644 index 00000000..e87dd676 --- /dev/null +++ b/network/common.h @@ -0,0 +1,22 @@ +/* + * + * 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 + * + */ -- cgit From a1e5adc417797a4896e864851741f02cdad4c3e3 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 21 Mar 2007 21:25:10 +0000 Subject: Install the network service if enabled --- network/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index a9fd2f60..e01bd4b9 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -8,7 +8,7 @@ endif servicedir = $(libdir)/bluetooth -noinst_PROGRAMS = bluetoothd-service-network +service_PROGRAMS = bluetoothd-service-network bluetoothd_service_network_SOURCES = main.c \ manager.h manager.c error.h error.c \ -- 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/manager.c | 2 +- network/server.c | 31 ++++++++++++++++++++++++++----- network/server.h | 2 +- 3 files changed, 28 insertions(+), 7 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 42853811..a73c3147 100644 --- a/network/manager.c +++ b/network/manager.c @@ -138,7 +138,7 @@ static DBusHandlerResult create_server(DBusConnection *conn, if (g_slist_find_custom(mgr->servers, path, (GCompareFunc) strcmp)) return create_path(conn, msg, path, NULL); - if (server_register(conn, path) == -1) { + if (server_register(conn, path, uuid) == -1) { err_failed(conn, msg, "D-Bus path registration failed"); g_free(path); return DBUS_HANDLER_RESULT_HANDLED; 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; diff --git a/network/server.h b/network/server.h index 33f997a9..a3fba6d1 100644 --- a/network/server.h +++ b/network/server.h @@ -20,4 +20,4 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ -int server_register(DBusConnection *conn, const char *path); +int server_register(DBusConnection *conn, const char *path, const char *uuid); -- 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') 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/error.c | 8 ++++++++ network/error.h | 7 ++++--- network/server.c | 28 +++++++++++++++++++++++++--- 3 files changed, 37 insertions(+), 6 deletions(-) (limited to 'network') diff --git a/network/error.c b/network/error.c index 28bd54ae..ec3f9298 100644 --- a/network/error.c +++ b/network/error.c @@ -60,3 +60,11 @@ DBusHandlerResult err_failed(DBusConnection *conn, DBusMessage *msg, dbus_message_new_error(msg, NETWORK_ERROR_INTERFACE ".Failed", str)); } + +DBusHandlerResult err_invalid_args(DBusConnection *conn, + DBusMessage *msg, const char *str) +{ + return send_message_and_unref(conn, + dbus_message_new_error(msg, + NETWORK_ERROR_INTERFACE ".InvalidArguments", str)); +} diff --git a/network/error.h b/network/error.h index 63f6ffde..e28002e7 100644 --- a/network/error.h +++ b/network/error.h @@ -27,8 +27,9 @@ DBusHandlerResult err_unknown_connection(DBusConnection *conn, DBusMessage *msg); DBusHandlerResult err_generic(DBusConnection *conn, DBusMessage *msg, const char *name, const char *str); -DBusHandlerResult err_does_not_exist(DBusConnection *conn, DBusMessage *msg, - const char *str); +DBusHandlerResult err_does_not_exist(DBusConnection *conn, + DBusMessage *msg, const char *str); DBusHandlerResult err_failed(DBusConnection *conn, DBusMessage *msg, const char *str); - +DBusHandlerResult err_invalid_args(DBusConnection *conn, + DBusMessage *msg, const char *str); 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 f844fe4f4284e2961cc4a6ee17cc7ede18a9aaf8 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 22 Mar 2007 17:07:24 +0000 Subject: network: removed err_generic function --- network/error.c | 7 ------- network/error.h | 2 -- network/manager.c | 6 +++--- 3 files changed, 3 insertions(+), 12 deletions(-) (limited to 'network') diff --git a/network/error.c b/network/error.c index ec3f9298..a4b38190 100644 --- a/network/error.c +++ b/network/error.c @@ -38,13 +38,6 @@ DBusHandlerResult err_unknown_connection(DBusConnection *conn, "Unknown connection path")); } -DBusHandlerResult err_generic(DBusConnection *conn, DBusMessage *msg, - const char *name, const char *str) -{ - return send_message_and_unref(conn, - dbus_message_new_error(msg, name, str)); -} - DBusHandlerResult err_does_not_exist(DBusConnection *conn, DBusMessage *msg, const char *str) { diff --git a/network/error.h b/network/error.h index e28002e7..29b73908 100644 --- a/network/error.h +++ b/network/error.h @@ -25,8 +25,6 @@ DBusHandlerResult err_unknown_connection(DBusConnection *conn, DBusMessage *msg); -DBusHandlerResult err_generic(DBusConnection *conn, DBusMessage *msg, - const char *name, const char *str); DBusHandlerResult err_does_not_exist(DBusConnection *conn, DBusMessage *msg, const char *str); DBusHandlerResult err_failed(DBusConnection *conn, DBusMessage *msg, diff --git a/network/manager.c b/network/manager.c index a73c3147..c9a8d4e4 100644 --- a/network/manager.c +++ b/network/manager.c @@ -126,7 +126,7 @@ static DBusHandlerResult create_server(DBusConnection *conn, if (!dbus_message_get_args(msg, &derr, DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID)) { - err_generic(conn, msg, derr.name, derr.message); + err_invalid_args(conn, msg, derr.message); dbus_error_free(&derr); return DBUS_HANDLER_RESULT_HANDLED; } @@ -162,7 +162,7 @@ static DBusHandlerResult remove_path(DBusConnection *conn, if (!dbus_message_get_args(msg, &derr, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID)) { - err_generic(conn, msg, derr.name, derr.message); + err_invalid_args(conn, msg, derr.message); dbus_error_free(&derr); return DBUS_HANDLER_RESULT_HANDLED; } @@ -224,7 +224,7 @@ static DBusHandlerResult create_connection(DBusConnection *conn, DBUS_TYPE_STRING, &addr, DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID)) { - err_generic(conn, msg, derr.name, derr.message); + err_invalid_args(conn, msg, derr.message); dbus_error_free(&derr); return DBUS_HANDLER_RESULT_HANDLED; } -- 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') 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') 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 d1d248d12b0eba700498c47647f9cd438510b242 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 22 Mar 2007 17:36:56 +0000 Subject: Initial code of bnep common. --- network/common.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ network/common.h | 11 +++++ 2 files changed, 157 insertions(+) (limited to 'network') diff --git a/network/common.c b/network/common.c index 8e5043cc..1649eb70 100644 --- a/network/common.c +++ b/network/common.c @@ -25,4 +25,150 @@ #include #endif +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "logging.h" #include "common.h" + +static int ctl; + +/* Compatibility with old ioctls */ +#define OLD_BNEPCONADD 1 +#define OLD_BNEPCONDEL 2 +#define OLD_BNEPGETCONLIST 3 +#define OLD_BNEPGETCONINFO 4 + +static unsigned long bnepconnadd; +static unsigned long bnepconndel; +static unsigned long bnepgetconnlist; +static unsigned long bnepgetconninfo; + +static struct { + char *str; + uint16_t uuid; +} __svc[] = { + { "PANU", BNEP_SVC_PANU }, + { "NAP", BNEP_SVC_NAP }, + { "GN", BNEP_SVC_GN }, + { NULL } +}; + +int bnep_str2svc(char *svc, uint16_t *uuid) +{ + int i; + for (i = 0; __svc[i].str; i++) + if (!strcasecmp(svc, __svc[i].str)) { + *uuid = __svc[i].uuid; + return 0; + } + return -1; +} + +char *bnep_svc2str(uint16_t uuid) +{ + int i; + for (i = 0; __svc[i].str; i++) + if (__svc[i].uuid == uuid) + return __svc[i].str; + return NULL; +} + +int bnep_init(void) +{ + ctl = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_BNEP); + if (ctl < 0) { + error("Failed to open control socket"); + return 1; + } + + /* Temporary ioctl compatibility hack */ + { + struct bnep_connlist_req req; + struct bnep_conninfo ci[1]; + + req.cnum = 1; + req.ci = ci; + + if (!ioctl(ctl, BNEPGETCONNLIST, &req)) { + /* New ioctls */ + bnepconnadd = BNEPCONNADD; + bnepconndel = BNEPCONNDEL; + bnepgetconnlist = BNEPGETCONNLIST; + bnepgetconninfo = BNEPGETCONNINFO; + } else { + /* Old ioctls */ + bnepconnadd = OLD_BNEPCONADD; + bnepconndel = OLD_BNEPCONDEL; + bnepgetconnlist = OLD_BNEPGETCONLIST; + bnepgetconninfo = OLD_BNEPGETCONINFO; + } + } + + return 0; +} + +int bnep_cleanup(void) +{ + close(ctl); + return 0; +} + +int bnep_kill_connection(const char *addr) +{ + struct bnep_conndel_req req; + uint8_t *dst = (void *) strtoba(addr); + + memcpy(req.dst, dst, ETH_ALEN); + req.flags = 0; + if (ioctl(ctl, bnepconndel, &req)) { + error("Failed to kill connection"); + return -1; + } + return 0; +} + +int bnep_kill_all_connections(void) +{ + struct bnep_connlist_req req; + struct bnep_conninfo ci[48]; + int i; + + req.cnum = 48; + req.ci = ci; + if (ioctl(ctl, bnepgetconnlist, &req)) { + error("Failed to get connection list"); + return -1; + } + + for (i=0; i < req.cnum; i++) { + struct bnep_conndel_req req; + memcpy(req.dst, ci[i].dst, ETH_ALEN); + req.flags = 0; + ioctl(ctl, bnepconndel, &req); + } + return 0; +} + +int bnep_connadd(int sk, uint16_t role, char *dev) +{ + struct bnep_connadd_req req; + + strncpy(req.device, dev, 16); + req.device[15] = '\0'; + req.sock = sk; + req.role = role; + if (ioctl(ctl, bnepconnadd, &req)) { + error("Failed to add device %s", dev); + return -1; + } + strncpy(dev, req.device, 16); + return 0; +} diff --git a/network/common.h b/network/common.h index e87dd676..11e0b77b 100644 --- a/network/common.h +++ b/network/common.h @@ -20,3 +20,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ +/* BNEP functions */ +int bnep_init(void); +int bnep_cleanup(void); + +int bnep_str2svc(char *svc, uint16_t *uuid); +char *bnep_svc2str(uint16_t uuid); + +int bnep_kill_connection(const char *addr); +int bnep_kill_all_connections(void); + +int bnep_connadd(int sk, uint16_t role, char *dev); -- 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') 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') 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 e46f647bc95dcedf962ba2741670e45c65e8f34c Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 22 Mar 2007 20:15:59 +0000 Subject: Add err_connection_failed. --- network/error.c | 9 +++++++++ network/error.h | 3 +++ 2 files changed, 12 insertions(+) (limited to 'network') diff --git a/network/error.c b/network/error.c index a4b38190..87829dea 100644 --- a/network/error.c +++ b/network/error.c @@ -54,6 +54,15 @@ DBusHandlerResult err_failed(DBusConnection *conn, DBusMessage *msg, NETWORK_ERROR_INTERFACE ".Failed", str)); } +DBusHandlerResult err_connection_failed(DBusConnection *conn, + DBusMessage *msg, const char *str) +{ + return send_message_and_unref(conn, + dbus_message_new_error(msg, + NETWORK_ERROR_INTERFACE".ConnectionAttemptFailed", + str)); +} + DBusHandlerResult err_invalid_args(DBusConnection *conn, DBusMessage *msg, const char *str) { diff --git a/network/error.h b/network/error.h index 29b73908..28ccdb07 100644 --- a/network/error.h +++ b/network/error.h @@ -29,5 +29,8 @@ DBusHandlerResult err_does_not_exist(DBusConnection *conn, DBusMessage *msg, const char *str); DBusHandlerResult err_failed(DBusConnection *conn, DBusMessage *msg, const char *str); +DBusHandlerResult err_connection_failed(DBusConnection *conn, + DBusMessage *msg, const char *str); + DBusHandlerResult err_invalid_args(DBusConnection *conn, DBusMessage *msg, const char *str); -- cgit From 29809147d7deb7a7326790ded39fc2488f725f44 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 22 Mar 2007 20:26:04 +0000 Subject: Add bnep_init and bnep_cleanup to manager. --- network/manager.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index c9a8d4e4..dde8c908 100644 --- a/network/manager.c +++ b/network/manager.c @@ -42,6 +42,7 @@ #include "manager.h" #include "server.h" #include "connection.h" +#include "common.h" struct manager { bdaddr_t src; /* Local adapter BT address */ @@ -301,6 +302,7 @@ static void manager_free(struct manager *mgr) g_slist_free(mgr->connections); g_free (mgr); + bnep_kill_all_connections(); } static void manager_unregister(DBusConnection *conn, void *data) @@ -414,6 +416,11 @@ int network_init(void) return -1; } + if (bnep_init()) { + error("Can't init bnep module"); + return -1; + } + return network_dbus_init(); } @@ -422,6 +429,7 @@ void network_exit(void) if (bridge_remove("pan0") < 0) error("Can't remove bridge"); + bnep_cleanup(); bridge_cleanup(); network_dbus_exit(); -- cgit From bdb402511c964ba8d65fd4657c638ab3c5fbf438 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 22 Mar 2007 20:30:19 +0000 Subject: Connection code. --- network/connection.c | 297 +++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 278 insertions(+), 19 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index c1544b58..12a563ad 100644 --- a/network/connection.c +++ b/network/connection.c @@ -25,35 +25,175 @@ #include #endif +#include +#include +#include +#include +#include + #include +#include +#include #include +#include + #include "logging.h" #include "dbus.h" #include "error.h" +#include "common.h" -#define NETWORK_CONNECTION_INTERFACE "org.bluez.network.Manager" +#define NETWORK_CONNECTION_INTERFACE "org.bluez.network.Connection" #include "connection.h" struct network_conn { + DBusConnection *conn; char *raddr; char *path; - char *uuid; + char *dev; + uint16_t uuid; gboolean up; }; +struct __service_16 { + uint16_t dst; + uint16_t src; +} __attribute__ ((packed)); + +static gboolean l2cap_io_cb(GIOChannel *chan, GIOCondition cond, gpointer data) +{ + struct network_conn *nc = data; + struct bnep_control_rsp *rsp; + char pkt[BNEP_MTU]; + gsize r; + int sk; + DBusMessage *signal; + + if (cond & G_IO_NVAL) + return FALSE; + + if (cond & (G_IO_HUP | G_IO_ERR)) { + error("Hangup or error on l2cap server socket"); + goto failed; + } + + memset(pkt, 0, BNEP_MTU); + if (g_io_channel_read(chan, pkt, sizeof(pkt) - 1, + &r) != G_IO_ERROR_NONE) { + error("IO Channel read error"); + goto failed; + } + + if (r <= 0) { + error("No packet received on l2cap socket"); + goto failed; + } + + errno = EPROTO; + + if (r < sizeof(*rsp)) { + error("Packet received is not bnep type"); + goto failed; + } + + rsp = (void *) pkt; + if (rsp->type != BNEP_CONTROL) { + error("Packet received is not bnep type"); + goto failed; + } + + if (rsp->ctrl != BNEP_SETUP_CONN_RSP) + return TRUE; + + r = ntohs(rsp->resp); + + if (r != BNEP_SUCCESS) { + error("bnep connection failed"); + goto failed; + } + + sk = g_io_channel_unix_get_fd(chan); + + if (bnep_connadd(sk, BNEP_SVC_PANU, nc->dev)) { + error("bnep0 could not be added"); + goto failed; + } + + nc->up = TRUE; + + signal = dbus_message_new_signal(nc->path, + NETWORK_CONNECTION_INTERFACE, "Connected"); + + send_message_and_unref(nc->conn, signal); + +failed: + g_io_channel_unref(chan); + return FALSE; +} + +int bnep_create_connection(int sk, struct network_conn *nc) +{ + struct bnep_setup_conn_req *req; + struct __service_16 *s; + unsigned char pkt[BNEP_MTU]; + GIOChannel *io; + + io = g_io_channel_unix_new(sk); + g_io_channel_set_close_on_unref(io, TRUE); + + /* Send request */ + req = (void *) pkt; + req->type = BNEP_CONTROL; + req->ctrl = BNEP_SETUP_CONN_REQ; + req->uuid_size = 2; /* 16bit UUID */ + s = (void *) req->service; + s->dst = htons(nc->uuid); + s->src = htons(BNEP_SVC_PANU); + + if (send(sk, pkt, sizeof(*req) + sizeof(*s), 0) != -1) { + g_io_add_watch(io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, + (GIOFunc) l2cap_io_cb, nc); + return 0; + } + + g_io_channel_unref(io); + return -1; +} + static DBusHandlerResult get_address(DBusConnection *conn, DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct network_conn *nc = 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, &nc->raddr, + DBUS_TYPE_INVALID); + + return send_message_and_unref(conn, reply); } static DBusHandlerResult get_uuid(DBusConnection *conn, DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct network_conn *nc = data; + char *svc; + DBusMessage *reply; + + svc = bnep_svc2str(nc->uuid); + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_message_append_args(reply, DBUS_TYPE_STRING, &svc, + DBUS_TYPE_INVALID); + + return send_message_and_unref(conn, reply); } static DBusHandlerResult get_name(DBusConnection *conn, DBusMessage *msg, @@ -62,8 +202,8 @@ static DBusHandlerResult get_name(DBusConnection *conn, DBusMessage *msg, return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -static DBusHandlerResult get_descriptor(DBusConnection *conn, DBusMessage *msg, - void *data) +static DBusHandlerResult get_description(DBusConnection *conn, + DBusMessage *msg, void *data) { return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } @@ -71,25 +211,132 @@ static DBusHandlerResult get_descriptor(DBusConnection *conn, DBusMessage *msg, static DBusHandlerResult get_interface(DBusConnection *conn, DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct network_conn *nc = 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, &nc->raddr, + DBUS_TYPE_INVALID); + + return send_message_and_unref(conn, reply); } -static DBusHandlerResult connect(DBusConnection *conn, DBusMessage *msg, - void *data) +/* Connect and initiate BNEP session */ +static DBusHandlerResult connection_connect(DBusConnection *conn, + DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct network_conn *nc = data; + struct l2cap_options l2o; + struct sockaddr_l2 l2a; + socklen_t olen; + int sk; + DBusError derr; + DBusMessage *reply; + bdaddr_t src_addr = *BDADDR_ANY; + + dbus_error_init(&derr); + if (!dbus_message_get_args(msg, &derr, + DBUS_TYPE_INVALID)) { + err_invalid_args(conn, msg, derr.message); + dbus_error_free(&derr); + return DBUS_HANDLER_RESULT_HANDLED; + } + + info("Connecting to %s", nc->raddr); + + sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); + if (sk < 0) { + error("Cannot create L2CAP socket. %s(%d)", strerror(errno), + errno); + goto fail; + } + set_nonblocking(sk); + + /* Setup L2CAP options according to BNEP spec */ + memset(&l2o, 0, sizeof(l2o)); + olen = sizeof(l2o); + getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen); + l2o.imtu = l2o.omtu = BNEP_MTU; + setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)); + + memset(&l2a, 0, sizeof(l2a)); + l2a.l2_family = AF_BLUETOOTH; + bacpy(&l2a.l2_bdaddr, &src_addr); + + if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a))) { + error("Bind failed. %s(%d)", strerror(errno), errno); + goto fail; + } + + memset(&l2a, 0, sizeof(l2a)); + l2a.l2_family = AF_BLUETOOTH; + str2ba(nc->raddr, &l2a.l2_bdaddr); + l2a.l2_psm = htobs(BNEP_PSM); + + if (!connect(sk, (struct sockaddr *) &l2a, sizeof(l2a)) && + !bnep_create_connection(sk, nc)) { + info("%s connected", nc->dev); + + } else { + error("Connect to %s failed. %s(%d)", nc->raddr, + strerror(errno), errno); + goto fail; + } + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + return send_message_and_unref(conn, reply); +fail: + err_connection_failed(conn, msg, strerror(errno)); + return DBUS_HANDLER_RESULT_HANDLED; + } -static DBusHandlerResult disconnect(DBusConnection *conn, +static DBusHandlerResult connection_disconnect(DBusConnection *conn, DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct network_conn *nc = data; + DBusMessage *reply, *signal; + + if (!nc->up) { + err_failed(conn, msg, "Device not connected"); + return DBUS_HANDLER_RESULT_HANDLED; + } + + if (!bnep_kill_connection(nc->raddr)) { + signal = dbus_message_new_signal(nc->path, + NETWORK_CONNECTION_INTERFACE, "Disconnected"); + + send_message_and_unref(nc->conn, signal); + nc->up = FALSE; + } + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + return send_message_and_unref(conn, reply); } static DBusHandlerResult is_connected(DBusConnection *conn, DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct network_conn *nc = 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, &nc->up, + DBUS_TYPE_INVALID); + + return send_message_and_unref(conn, reply); } static DBusHandlerResult connection_message(DBusConnection *conn, @@ -113,16 +360,16 @@ static DBusHandlerResult connection_message(DBusConnection *conn, return get_name(conn, msg, data); if (strcmp(member, "GetDescription") == 0) - return get_descriptor(conn, msg, data); + return get_description(conn, msg, data); if (strcmp(member, "GetInterface") == 0) return get_interface(conn, msg, data); if (strcmp(member, "Connect") == 0) - return connect(conn, msg, data); + return connection_connect(conn, msg, data); if (strcmp(member, "Disconnect") == 0) - return disconnect(conn, msg, data); + return connection_disconnect(conn, msg, data); if (strcmp(member, "IsConnected") == 0) return is_connected(conn, msg, data); @@ -138,8 +385,14 @@ static void connection_free(struct network_conn *nc) if (nc->path) g_free(nc->path); - if (nc->uuid) - g_free(nc->uuid); + if (nc->up) + bnep_kill_connection(nc->raddr); + + if (nc->raddr) + g_free(nc->raddr); + + if (nc->dev) + g_free(nc->dev); g_free(nc); } @@ -163,6 +416,7 @@ int connection_register(DBusConnection *conn, const char *path, const char *addr, const char *uuid) { struct network_conn *nc; + static int bnep = 0; if (!conn) return -1; @@ -178,8 +432,13 @@ int connection_register(DBusConnection *conn, const char *path, nc->path = g_strdup(path); nc->raddr = g_strdup(addr); - nc->uuid = g_strdup(uuid); + /* FIXME: Check uuid format */ + bnep_str2svc(uuid, &nc->uuid); + /* FIXME: Check for device */ + nc->dev = g_new(char, 16); + snprintf(nc->dev, 16, "bnep%d", bnep++); nc->up = FALSE; + nc->conn = conn; info("Registered connection path:%s", path); return 0; fail: -- cgit From 2e39ac58720cba4fc6e889ec5f18a8ce1d67276c Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 23 Mar 2007 19:10:37 +0000 Subject: network: Fixed string/service id/uuid convertion functions --- network/common.c | 46 +++++++++++++++++++++++++++++++--------------- network/common.h | 4 ++-- network/connection.c | 18 +++++++++--------- network/manager.c | 25 +++++++++++++++++-------- 4 files changed, 59 insertions(+), 34 deletions(-) (limited to 'network') diff --git a/network/common.c b/network/common.c index 1649eb70..1be7bbe4 100644 --- a/network/common.c +++ b/network/common.c @@ -40,6 +40,10 @@ static int ctl; +#define PANU_UUID "00001115-0000-1000-8000-00805f9b34fb" +#define NAP_UUID "00001116-0000-1000-8000-00805f9b34fb" +#define GN_UUID "00001117-0000-1000-8000-00805f9b34fb" + /* Compatibility with old ioctls */ #define OLD_BNEPCONADD 1 #define OLD_BNEPCONDEL 2 @@ -52,32 +56,44 @@ static unsigned long bnepgetconnlist; static unsigned long bnepgetconninfo; static struct { - char *str; - uint16_t uuid; + const char *name; /* Friendly name */ + const char *uuid128; /* UUID 128 */ + uint16_t id; /* Service class identifier */ } __svc[] = { - { "PANU", BNEP_SVC_PANU }, - { "NAP", BNEP_SVC_NAP }, - { "GN", BNEP_SVC_GN }, + { "PANU", PANU_UUID, BNEP_SVC_PANU }, + { "GN", GN_UUID, BNEP_SVC_GN }, + { "NAP", NAP_UUID, BNEP_SVC_NAP }, { NULL } }; -int bnep_str2svc(char *svc, uint16_t *uuid) +uint16_t bnep_service_id(const char *svc) { int i; - for (i = 0; __svc[i].str; i++) - if (!strcasecmp(svc, __svc[i].str)) { - *uuid = __svc[i].uuid; - return 0; + + /* Friendly service name */ + for (i = 0; __svc[i].name; i++) + if (!strcasecmp(svc, __svc[i].name)) { + return __svc[i].id; + } + + /* UUID 128 string */ + for (i = 0; __svc[i].uuid128; i++) + if (!strcasecmp(svc, __svc[i].uuid128)) { + return __svc[i].id; } - return -1; + + /* FIXME: Missing HEX string verification */ + + return 0; } -char *bnep_svc2str(uint16_t uuid) +const char *bnep_uuid(uint16_t id) { int i; - for (i = 0; __svc[i].str; i++) - if (__svc[i].uuid == uuid) - return __svc[i].str; + + for (i = 0; __svc[i].uuid128; i++) + if (__svc[i].id == id) + return __svc[i].uuid128; return NULL; } diff --git a/network/common.h b/network/common.h index 11e0b77b..7dfc920a 100644 --- a/network/common.h +++ b/network/common.h @@ -24,8 +24,8 @@ int bnep_init(void); int bnep_cleanup(void); -int bnep_str2svc(char *svc, uint16_t *uuid); -char *bnep_svc2str(uint16_t uuid); +uint16_t bnep_service_id(const char *svc); +const char *bnep_uuid(uint16_t uuid); int bnep_kill_connection(const char *addr); int bnep_kill_all_connections(void); diff --git a/network/connection.c b/network/connection.c index 12a563ad..97034ad6 100644 --- a/network/connection.c +++ b/network/connection.c @@ -50,10 +50,10 @@ struct network_conn { DBusConnection *conn; - char *raddr; - char *path; - char *dev; - uint16_t uuid; + char *raddr; /* Remote Bluetooth Address */ + char *path; /* D-Bus path */ + char *dev; /* BNEP interface name */ + uint16_t id; /* Service Class Identifier */ gboolean up; }; @@ -149,7 +149,7 @@ int bnep_create_connection(int sk, struct network_conn *nc) req->ctrl = BNEP_SETUP_CONN_REQ; req->uuid_size = 2; /* 16bit UUID */ s = (void *) req->service; - s->dst = htons(nc->uuid); + s->dst = htons(nc->id); s->src = htons(BNEP_SVC_PANU); if (send(sk, pkt, sizeof(*req) + sizeof(*s), 0) != -1) { @@ -182,15 +182,15 @@ static DBusHandlerResult get_uuid(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_conn *nc = data; - char *svc; + const char *uuid; DBusMessage *reply; - svc = bnep_svc2str(nc->uuid); + uuid = bnep_uuid(nc->id); reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; - dbus_message_append_args(reply, DBUS_TYPE_STRING, &svc, + dbus_message_append_args(reply, DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID); return send_message_and_unref(conn, reply); @@ -433,7 +433,7 @@ int connection_register(DBusConnection *conn, const char *path, nc->path = g_strdup(path); nc->raddr = g_strdup(addr); /* FIXME: Check uuid format */ - bnep_str2svc(uuid, &nc->uuid); + nc->id = bnep_service_id(uuid); /* FIXME: Check for device */ nc->dev = g_new(char, 16); snprintf(nc->dev, 16, "bnep%d", bnep++); diff --git a/network/manager.c b/network/manager.c index dde8c908..ff4d05d4 100644 --- a/network/manager.c +++ b/network/manager.c @@ -28,6 +28,7 @@ #include #include #include +#include #include @@ -120,26 +121,32 @@ static DBusHandlerResult create_server(DBusConnection *conn, { struct manager *mgr = data; DBusError derr; - const char *uuid; + const char *str; char *path; + uint16_t id; dbus_error_init(&derr); if (!dbus_message_get_args(msg, &derr, - DBUS_TYPE_STRING, &uuid, + DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID)) { err_invalid_args(conn, msg, derr.message); dbus_error_free(&derr); return DBUS_HANDLER_RESULT_HANDLED; } + id = bnep_service_id(str); + if ((id != BNEP_SVC_GN) && (id != BNEP_SVC_NAP)) + return err_invalid_args(conn, msg, "Not supported"); + path = g_new0(char, 32); - snprintf(path, 32, NETWORK_PATH "/server/%s", uuid); + snprintf(path, 32, NETWORK_PATH "/server/%X", id); /* Path already registered */ if (g_slist_find_custom(mgr->servers, path, (GCompareFunc) strcmp)) - return create_path(conn, msg, path, NULL); + return create_path(conn, msg, path, NULL); /* Return already exist error */ - if (server_register(conn, path, uuid) == -1) { + /* FIXME: define which type should be used -- string/uuid str/uui128 */ + if (server_register(conn, path, str) == -1) { err_failed(conn, msg, "D-Bus path registration failed"); g_free(path); return DBUS_HANDLER_RESULT_HANDLED; @@ -217,23 +224,25 @@ static DBusHandlerResult create_connection(DBusConnection *conn, static int uid = 0; DBusError derr; const char *addr; - const char *uuid; + const char *str; char *path; dbus_error_init(&derr); if (!dbus_message_get_args(msg, &derr, DBUS_TYPE_STRING, &addr, - DBUS_TYPE_STRING, &uuid, + DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID)) { err_invalid_args(conn, msg, derr.message); dbus_error_free(&derr); return DBUS_HANDLER_RESULT_HANDLED; } + /* FIXME: Check for supported/implemented client connection */ + path = g_new0(char, 32); snprintf(path, 32, NETWORK_PATH "/connection%d", uid++); - if (connection_register(conn, path, addr, uuid) == -1) { + if (connection_register(conn, path, addr, str) == -1) { err_failed(conn, msg, "D-Bus path registration failed"); g_free(path); return DBUS_HANDLER_RESULT_HANDLED; -- cgit From 696c7534eca66f0dd64de6aba2ab26e8a4b66eea Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 23 Mar 2007 20:33:54 +0000 Subject: network: Added hexadecimal verification for Manager.CreateServer --- network/common.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'network') diff --git a/network/common.c b/network/common.c index 1be7bbe4..7fbfee91 100644 --- a/network/common.c +++ b/network/common.c @@ -69,6 +69,7 @@ static struct { uint16_t bnep_service_id(const char *svc) { int i; + uint16_t id; /* Friendly service name */ for (i = 0; __svc[i].name; i++) @@ -82,9 +83,12 @@ uint16_t bnep_service_id(const char *svc) return __svc[i].id; } - /* FIXME: Missing HEX string verification */ + /* Try convert to HEX */ + id = strtol(svc, NULL, 16); + if ((id < BNEP_SVC_PANU) || (id > BNEP_SVC_GN)) + return 0; - return 0; + return id; } const char *bnep_uuid(uint16_t id) -- 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/common.c | 16 +++++++++++++--- network/common.h | 3 ++- network/manager.c | 5 ++--- network/server.c | 16 ++++++++-------- network/server.h | 2 +- 5 files changed, 26 insertions(+), 16 deletions(-) (limited to 'network') diff --git a/network/common.c b/network/common.c index 7fbfee91..ec10cc34 100644 --- a/network/common.c +++ b/network/common.c @@ -60,9 +60,9 @@ static struct { const char *uuid128; /* UUID 128 */ uint16_t id; /* Service class identifier */ } __svc[] = { - { "PANU", PANU_UUID, BNEP_SVC_PANU }, - { "GN", GN_UUID, BNEP_SVC_GN }, - { "NAP", NAP_UUID, BNEP_SVC_NAP }, + { "panu", PANU_UUID, BNEP_SVC_PANU }, + { "gn", GN_UUID, BNEP_SVC_GN }, + { "nap", NAP_UUID, BNEP_SVC_NAP }, { NULL } }; @@ -101,6 +101,16 @@ const char *bnep_uuid(uint16_t id) return NULL; } +const char *bnep_name(uint16_t id) +{ + int i; + + for (i = 0; __svc[i].name; i++) + if (__svc[i].id == id) + return __svc[i].name; + return NULL; +} + int bnep_init(void) { ctl = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_BNEP); diff --git a/network/common.h b/network/common.h index 7dfc920a..36bb66b2 100644 --- a/network/common.h +++ b/network/common.h @@ -25,7 +25,8 @@ int bnep_init(void); int bnep_cleanup(void); uint16_t bnep_service_id(const char *svc); -const char *bnep_uuid(uint16_t uuid); +const char *bnep_uuid(uint16_t id); +const char *bnep_name(uint16_t id); int bnep_kill_connection(const char *addr); int bnep_kill_all_connections(void); diff --git a/network/manager.c b/network/manager.c index ff4d05d4..6740f100 100644 --- a/network/manager.c +++ b/network/manager.c @@ -139,14 +139,13 @@ static DBusHandlerResult create_server(DBusConnection *conn, return err_invalid_args(conn, msg, "Not supported"); path = g_new0(char, 32); - snprintf(path, 32, NETWORK_PATH "/server/%X", id); + snprintf(path, 32, NETWORK_PATH "/server/%s", bnep_name(id)); /* Path already registered */ if (g_slist_find_custom(mgr->servers, path, (GCompareFunc) strcmp)) return create_path(conn, msg, path, NULL); /* Return already exist error */ - /* FIXME: define which type should be used -- string/uuid str/uui128 */ - if (server_register(conn, path, str) == -1) { + if (server_register(conn, path, id) == -1) { err_failed(conn, msg, "D-Bus path registration failed"); g_free(path); return DBUS_HANDLER_RESULT_HANDLED; 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; diff --git a/network/server.h b/network/server.h index a3fba6d1..bb15e4d7 100644 --- a/network/server.h +++ b/network/server.h @@ -20,4 +20,4 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ -int server_register(DBusConnection *conn, const char *path, const char *uuid); +int server_register(DBusConnection *conn, const char *path, uint16_t id); -- cgit From d98a405d8fc5e9b3e5919b63c7498e6b11989663 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 23 Mar 2007 21:15:40 +0000 Subject: network: Added invalid service class verification for Manager.CreateConnection --- network/connection.c | 5 ++--- network/connection.h | 2 +- network/manager.c | 7 +++++-- 3 files changed, 8 insertions(+), 6 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 97034ad6..e47369cc 100644 --- a/network/connection.c +++ b/network/connection.c @@ -413,7 +413,7 @@ static const DBusObjectPathVTable connection_table = { }; int connection_register(DBusConnection *conn, const char *path, - const char *addr, const char *uuid) + const char *addr, uint16_t id) { struct network_conn *nc; static int bnep = 0; @@ -432,8 +432,7 @@ int connection_register(DBusConnection *conn, const char *path, nc->path = g_strdup(path); nc->raddr = g_strdup(addr); - /* FIXME: Check uuid format */ - nc->id = bnep_service_id(uuid); + nc->id = id; /* FIXME: Check for device */ nc->dev = g_new(char, 16); snprintf(nc->dev, 16, "bnep%d", bnep++); diff --git a/network/connection.h b/network/connection.h index 0726ec6c..70966b2c 100644 --- a/network/connection.h +++ b/network/connection.h @@ -21,4 +21,4 @@ * */ int connection_register(DBusConnection *conn, const char *path, - const char *addr, const char *uuid); + const char *addr, uint16_t id); diff --git a/network/manager.c b/network/manager.c index 6740f100..52e6bffa 100644 --- a/network/manager.c +++ b/network/manager.c @@ -225,6 +225,7 @@ static DBusHandlerResult create_connection(DBusConnection *conn, const char *addr; const char *str; char *path; + uint16_t id; dbus_error_init(&derr); if (!dbus_message_get_args(msg, &derr, @@ -236,12 +237,14 @@ static DBusHandlerResult create_connection(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } - /* FIXME: Check for supported/implemented client connection */ + id = bnep_service_id(str); + if ((id != BNEP_SVC_GN) && (id != BNEP_SVC_NAP)) + return err_invalid_args(conn, msg, "Not supported"); path = g_new0(char, 32); snprintf(path, 32, NETWORK_PATH "/connection%d", uid++); - if (connection_register(conn, path, addr, str) == -1) { + if (connection_register(conn, path, addr, id) == -1) { err_failed(conn, msg, "D-Bus path registration failed"); g_free(path); return DBUS_HANDLER_RESULT_HANDLED; -- cgit From 4ce3d5461ad7640782cd032a547f3aec5a2265ad Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 23 Mar 2007 21:23:04 +0000 Subject: Buf fixes. --- network/connection.c | 55 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 21 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index e47369cc..ea2c269c 100644 --- a/network/connection.c +++ b/network/connection.c @@ -50,7 +50,8 @@ struct network_conn { DBusConnection *conn; - char *raddr; /* Remote Bluetooth Address */ + bdaddr_t src; + bdaddr_t dst; char *path; /* D-Bus path */ char *dev; /* BNEP interface name */ uint16_t id; /* Service Class Identifier */ @@ -62,7 +63,8 @@ struct __service_16 { uint16_t src; } __attribute__ ((packed)); -static gboolean l2cap_io_cb(GIOChannel *chan, GIOCondition cond, gpointer data) +static gboolean l2cap_io_cb(GIOChannel *chan, GIOCondition cond, + gpointer data) { struct network_conn *nc = data; struct bnep_control_rsp *rsp; @@ -167,12 +169,14 @@ static DBusHandlerResult get_address(DBusConnection *conn, DBusMessage *msg, { struct network_conn *nc = data; DBusMessage *reply; + char raddr[18]; + ba2str(&nc->dst, raddr); reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; - dbus_message_append_args(reply, DBUS_TYPE_STRING, &nc->raddr, + dbus_message_append_args(reply, DBUS_TYPE_STRING, raddr, DBUS_TYPE_INVALID); return send_message_and_unref(conn, reply); @@ -218,7 +222,7 @@ static DBusHandlerResult get_interface(DBusConnection *conn, DBusMessage *msg, if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; - dbus_message_append_args(reply, DBUS_TYPE_STRING, &nc->raddr, + dbus_message_append_args(reply, DBUS_TYPE_STRING, &nc->dev, DBUS_TYPE_INVALID); return send_message_and_unref(conn, reply); @@ -235,7 +239,7 @@ static DBusHandlerResult connection_connect(DBusConnection *conn, int sk; DBusError derr; DBusMessage *reply; - bdaddr_t src_addr = *BDADDR_ANY; + char addr[18]; dbus_error_init(&derr); if (!dbus_message_get_args(msg, &derr, @@ -245,7 +249,8 @@ static DBusHandlerResult connection_connect(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } - info("Connecting to %s", nc->raddr); + ba2str(&nc->dst, addr); + info("Connecting to %s", addr); sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); if (sk < 0) { @@ -253,7 +258,6 @@ static DBusHandlerResult connection_connect(DBusConnection *conn, errno); goto fail; } - set_nonblocking(sk); /* Setup L2CAP options according to BNEP spec */ memset(&l2o, 0, sizeof(l2o)); @@ -264,7 +268,7 @@ static DBusHandlerResult connection_connect(DBusConnection *conn, memset(&l2a, 0, sizeof(l2a)); l2a.l2_family = AF_BLUETOOTH; - bacpy(&l2a.l2_bdaddr, &src_addr); + bacpy(&l2a.l2_bdaddr, &nc->src); if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a))) { error("Bind failed. %s(%d)", strerror(errno), errno); @@ -273,19 +277,23 @@ static DBusHandlerResult connection_connect(DBusConnection *conn, memset(&l2a, 0, sizeof(l2a)); l2a.l2_family = AF_BLUETOOTH; - str2ba(nc->raddr, &l2a.l2_bdaddr); + bacpy(&l2a.l2_bdaddr, &nc->dst); l2a.l2_psm = htobs(BNEP_PSM); - if (!connect(sk, (struct sockaddr *) &l2a, sizeof(l2a)) && - !bnep_create_connection(sk, nc)) { - info("%s connected", nc->dev); + /* FIXME: connection must be non-blocking */ + if (connect(sk, (struct sockaddr *) &l2a, sizeof(l2a))) { + error("Connect failed. %s(%d)", strerror(errno), errno); + goto fail; + } - } else { - error("Connect to %s failed. %s(%d)", nc->raddr, + if (bnep_create_connection(sk, nc)) { + error("Connection to %s failed. %s(%d)", addr, strerror(errno), errno); goto fail; } + info("%s connected", nc->dev); + reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; @@ -302,17 +310,20 @@ static DBusHandlerResult connection_disconnect(DBusConnection *conn, { struct network_conn *nc = data; DBusMessage *reply, *signal; + char addr[18]; if (!nc->up) { err_failed(conn, msg, "Device not connected"); return DBUS_HANDLER_RESULT_HANDLED; } - if (!bnep_kill_connection(nc->raddr)) { + ba2str(&nc->dst, addr); + if (!bnep_kill_connection(addr)) { signal = dbus_message_new_signal(nc->path, NETWORK_CONNECTION_INTERFACE, "Disconnected"); send_message_and_unref(nc->conn, signal); + info("%s disconnected", nc->dev); nc->up = FALSE; } @@ -379,17 +390,18 @@ static DBusHandlerResult connection_message(DBusConnection *conn, static void connection_free(struct network_conn *nc) { + char addr[18]; + if (!nc) return; if (nc->path) g_free(nc->path); - if (nc->up) - bnep_kill_connection(nc->raddr); - - if (nc->raddr) - g_free(nc->raddr); + if (nc->up) { + ba2str(&nc->dst, addr); + bnep_kill_connection(addr); + } if (nc->dev) g_free(nc->dev); @@ -431,7 +443,8 @@ int connection_register(DBusConnection *conn, const char *path, } nc->path = g_strdup(path); - nc->raddr = g_strdup(addr); + bacpy(&nc->src, BDADDR_ANY); + str2ba(addr, &nc->dst); nc->id = id; /* FIXME: Check for device */ nc->dev = g_new(char, 16); -- cgit From 9bea84c70ceca8efd7f1137c5aa3425e77c196cf Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 26 Mar 2007 13:35:30 +0000 Subject: Fix service exit. --- network/manager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 52e6bffa..42542c9a 100644 --- a/network/manager.c +++ b/network/manager.c @@ -437,11 +437,11 @@ int network_init(void) void network_exit(void) { + network_dbus_exit(); + if (bridge_remove("pan0") < 0) error("Can't remove bridge"); bnep_cleanup(); bridge_cleanup(); - - network_dbus_exit(); } -- cgit From 82cef341d2adb711fc637c6b04d10862ef4120ce Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 26 Mar 2007 13:39:46 +0000 Subject: Fixes to use non-bloking socket on connect. --- network/connection.c | 162 +++++++++++++++++++++++++++++++++++---------------- 1 file changed, 113 insertions(+), 49 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index ea2c269c..e83dfe81 100644 --- a/network/connection.c +++ b/network/connection.c @@ -63,7 +63,7 @@ struct __service_16 { uint16_t src; } __attribute__ ((packed)); -static gboolean l2cap_io_cb(GIOChannel *chan, GIOCondition cond, +static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, gpointer data) { struct network_conn *nc = data; @@ -119,7 +119,7 @@ static gboolean l2cap_io_cb(GIOChannel *chan, GIOCondition cond, sk = g_io_channel_unix_get_fd(chan); if (bnep_connadd(sk, BNEP_SVC_PANU, nc->dev)) { - error("bnep0 could not be added"); + error("%s could not be added", nc->dev); goto failed; } @@ -129,21 +129,22 @@ static gboolean l2cap_io_cb(GIOChannel *chan, GIOCondition cond, NETWORK_CONNECTION_INTERFACE, "Connected"); send_message_and_unref(nc->conn, signal); - + info("%s connected", nc->dev); failed: + signal = dbus_message_new_signal(nc->path, + NETWORK_CONNECTION_INTERFACE, "Disconnected"); + + send_message_and_unref(nc->conn, signal); g_io_channel_unref(chan); return FALSE; } -int bnep_create_connection(int sk, struct network_conn *nc) +int bnep_connect(GIOChannel *io, struct network_conn *nc) { struct bnep_setup_conn_req *req; struct __service_16 *s; unsigned char pkt[BNEP_MTU]; - GIOChannel *io; - - io = g_io_channel_unix_new(sk); - g_io_channel_set_close_on_unref(io, TRUE); + int sk; /* Send request */ req = (void *) pkt; @@ -154,9 +155,10 @@ int bnep_create_connection(int sk, struct network_conn *nc) s->dst = htons(nc->id); s->src = htons(BNEP_SVC_PANU); + sk = g_io_channel_unix_get_fd(io); if (send(sk, pkt, sizeof(*req) + sizeof(*s), 0) != -1) { g_io_add_watch(io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, - (GIOFunc) l2cap_io_cb, nc); + (GIOFunc) bnep_connect_cb, nc); return 0; } @@ -164,6 +166,102 @@ int bnep_create_connection(int sk, struct network_conn *nc) return -1; } +static gboolean l2cap_connect_cb(GIOChannel *chan, + GIOCondition cond, gpointer data) +{ + struct network_conn *nc = data; + DBusMessage *signal; + socklen_t len; + int sk, ret; + + if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) + goto failed; + + sk = g_io_channel_unix_get_fd(chan); + + len = sizeof(ret); + if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) { + error("getsockopt(SO_ERROR): %s (%d)", strerror(errno), errno); + goto failed; + } + + if (ret != 0) { + error("connect(): %s (%d)", strerror(errno), errno); + goto failed; + } + + if (bnep_connect(chan, nc)) { + error("connect(): %s (%d)", strerror(errno), errno); + signal = dbus_message_new_signal(nc->path, + NETWORK_CONNECTION_INTERFACE, "Disconnected"); + send_message_and_unref(nc->conn, signal); + goto failed; + } + + return FALSE; +failed: + g_io_channel_unref(chan); + return FALSE; +} + +static int l2cap_connect(int sk, struct network_conn *nc) +{ + struct l2cap_options l2o; + struct sockaddr_l2 l2a; + socklen_t olen; + char addr[18]; + GIOChannel *io; + + ba2str(&nc->dst, addr); + info("Connecting to %s", addr); + + /* Setup L2CAP options according to BNEP spec */ + memset(&l2o, 0, sizeof(l2o)); + olen = sizeof(l2o); + getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen); + l2o.imtu = l2o.omtu = BNEP_MTU; + setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)); + + memset(&l2a, 0, sizeof(l2a)); + l2a.l2_family = AF_BLUETOOTH; + bacpy(&l2a.l2_bdaddr, &nc->src); + + if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a))) { + error("Bind failed. %s(%d)", strerror(errno), errno); + return -1; + } + + memset(&l2a, 0, sizeof(l2a)); + l2a.l2_family = AF_BLUETOOTH; + bacpy(&l2a.l2_bdaddr, &nc->dst); + l2a.l2_psm = htobs(BNEP_PSM); + + if (set_nonblocking(sk) < 0) { + error("Set non blocking: %s (%d)", strerror(errno), errno); + return -1; + } + + io = g_io_channel_unix_new(sk); + g_io_channel_set_close_on_unref(io, FALSE); + + if (connect(sk, (struct sockaddr *) &l2a, sizeof(l2a))) { + if (!(errno == EAGAIN || errno == EINPROGRESS)) { + error("Connect failed. %s(%d)", strerror(errno), + errno); + g_io_channel_unref(io); + return -1; + } + g_io_add_watch(io, G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL, + (GIOFunc) l2cap_connect_cb, nc); + + } else { + l2cap_connect_cb(io, G_IO_OUT, nc); + g_io_channel_unref(io); + } + + return 0; +} + static DBusHandlerResult get_address(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -233,13 +331,9 @@ static DBusHandlerResult connection_connect(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_conn *nc = data; - struct l2cap_options l2o; - struct sockaddr_l2 l2a; - socklen_t olen; int sk; DBusError derr; - DBusMessage *reply; - char addr[18]; + DBusMessage *reply, *signal; dbus_error_init(&derr); if (!dbus_message_get_args(msg, &derr, @@ -249,9 +343,6 @@ static DBusHandlerResult connection_connect(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } - ba2str(&nc->dst, addr); - info("Connecting to %s", addr); - sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); if (sk < 0) { error("Cannot create L2CAP socket. %s(%d)", strerror(errno), @@ -259,41 +350,12 @@ static DBusHandlerResult connection_connect(DBusConnection *conn, goto fail; } - /* Setup L2CAP options according to BNEP spec */ - memset(&l2o, 0, sizeof(l2o)); - olen = sizeof(l2o); - getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen); - l2o.imtu = l2o.omtu = BNEP_MTU; - setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)); - - memset(&l2a, 0, sizeof(l2a)); - l2a.l2_family = AF_BLUETOOTH; - bacpy(&l2a.l2_bdaddr, &nc->src); - - if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a))) { - error("Bind failed. %s(%d)", strerror(errno), errno); - goto fail; - } - - memset(&l2a, 0, sizeof(l2a)); - l2a.l2_family = AF_BLUETOOTH; - bacpy(&l2a.l2_bdaddr, &nc->dst); - l2a.l2_psm = htobs(BNEP_PSM); - - /* FIXME: connection must be non-blocking */ - if (connect(sk, (struct sockaddr *) &l2a, sizeof(l2a))) { + if(l2cap_connect(sk, nc)) { error("Connect failed. %s(%d)", strerror(errno), errno); goto fail; } - if (bnep_create_connection(sk, nc)) { - error("Connection to %s failed. %s(%d)", addr, - strerror(errno), errno); - goto fail; - } - - info("%s connected", nc->dev); - + /* FIXME: Do not replay until connection be connected */ reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; @@ -301,8 +363,10 @@ static DBusHandlerResult connection_connect(DBusConnection *conn, return send_message_and_unref(conn, reply); fail: err_connection_failed(conn, msg, strerror(errno)); + signal = dbus_message_new_signal(nc->path, + NETWORK_CONNECTION_INTERFACE, "Disconnected"); + send_message_and_unref(nc->conn, signal); return DBUS_HANDLER_RESULT_HANDLED; - } static DBusHandlerResult connection_disconnect(DBusConnection *conn, -- 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') 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 479dbf10dca70f2d9917729e41d7b0055f5070f7 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 26 Mar 2007 18:35:08 +0000 Subject: Fix connect. --- network/connection.c | 77 ++++++++++++++++++++++++++-------------------------- 1 file changed, 38 insertions(+), 39 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index e83dfe81..af3d4090 100644 --- a/network/connection.c +++ b/network/connection.c @@ -45,17 +45,18 @@ #include "common.h" #define NETWORK_CONNECTION_INTERFACE "org.bluez.network.Connection" - #include "connection.h" struct network_conn { DBusConnection *conn; + DBusMessage *msg; bdaddr_t src; bdaddr_t dst; char *path; /* D-Bus path */ char *dev; /* BNEP interface name */ uint16_t id; /* Service Class Identifier */ gboolean up; + int sk; }; struct __service_16 { @@ -71,7 +72,7 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, char pkt[BNEP_MTU]; gsize r; int sk; - DBusMessage *signal; + DBusMessage *reply, *signal; if (cond & G_IO_NVAL) return FALSE; @@ -112,7 +113,7 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, r = ntohs(rsp->resp); if (r != BNEP_SUCCESS) { - error("bnep connection failed"); + error("bnep failed"); goto failed; } @@ -123,28 +124,33 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, goto failed; } - nc->up = TRUE; - signal = dbus_message_new_signal(nc->path, NETWORK_CONNECTION_INTERFACE, "Connected"); send_message_and_unref(nc->conn, signal); + + reply = dbus_message_new_method_return(nc->msg); + + send_message_and_unref(nc->conn, reply); + + nc->up = TRUE; + info("%s connected", nc->dev); + g_io_channel_unref(chan); + return FALSE; failed: - signal = dbus_message_new_signal(nc->path, - NETWORK_CONNECTION_INTERFACE, "Disconnected"); - - send_message_and_unref(nc->conn, signal); + err_connection_failed(nc->conn, nc->msg, "bnep failed"); + g_io_channel_close(chan); g_io_channel_unref(chan); return FALSE; } -int bnep_connect(GIOChannel *io, struct network_conn *nc) +static int bnep_connect(struct network_conn *nc) { struct bnep_setup_conn_req *req; struct __service_16 *s; unsigned char pkt[BNEP_MTU]; - int sk; + GIOChannel *io; /* Send request */ req = (void *) pkt; @@ -155,8 +161,9 @@ int bnep_connect(GIOChannel *io, struct network_conn *nc) s->dst = htons(nc->id); s->src = htons(BNEP_SVC_PANU); - sk = g_io_channel_unix_get_fd(io); - if (send(sk, pkt, sizeof(*req) + sizeof(*s), 0) != -1) { + io = g_io_channel_unix_new(nc->sk); + g_io_channel_set_close_on_unref(io, FALSE); + if (send(nc->sk, pkt, sizeof(*req) + sizeof(*s), 0) != -1) { g_io_add_watch(io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, (GIOFunc) bnep_connect_cb, nc); return 0; @@ -170,7 +177,6 @@ static gboolean l2cap_connect_cb(GIOChannel *chan, GIOCondition cond, gpointer data) { struct network_conn *nc = data; - DBusMessage *signal; socklen_t len; int sk, ret; @@ -190,21 +196,21 @@ static gboolean l2cap_connect_cb(GIOChannel *chan, goto failed; } - if (bnep_connect(chan, nc)) { + if (bnep_connect(nc)) { error("connect(): %s (%d)", strerror(errno), errno); - signal = dbus_message_new_signal(nc->path, - NETWORK_CONNECTION_INTERFACE, "Disconnected"); - send_message_and_unref(nc->conn, signal); goto failed; } + g_io_channel_unref(chan); return FALSE; failed: + err_connection_failed(nc->conn, nc->msg, strerror(errno)); + g_io_channel_close(chan); g_io_channel_unref(chan); return FALSE; } -static int l2cap_connect(int sk, struct network_conn *nc) +static int l2cap_connect(struct network_conn *nc) { struct l2cap_options l2o; struct sockaddr_l2 l2a; @@ -218,15 +224,15 @@ static int l2cap_connect(int sk, struct network_conn *nc) /* Setup L2CAP options according to BNEP spec */ memset(&l2o, 0, sizeof(l2o)); olen = sizeof(l2o); - getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen); + getsockopt(nc->sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen); l2o.imtu = l2o.omtu = BNEP_MTU; - setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)); + setsockopt(nc->sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)); memset(&l2a, 0, sizeof(l2a)); l2a.l2_family = AF_BLUETOOTH; bacpy(&l2a.l2_bdaddr, &nc->src); - if (bind(sk, (struct sockaddr *) &l2a, sizeof(l2a))) { + if (bind(nc->sk, (struct sockaddr *) &l2a, sizeof(l2a))) { error("Bind failed. %s(%d)", strerror(errno), errno); return -1; } @@ -236,18 +242,19 @@ static int l2cap_connect(int sk, struct network_conn *nc) bacpy(&l2a.l2_bdaddr, &nc->dst); l2a.l2_psm = htobs(BNEP_PSM); - if (set_nonblocking(sk) < 0) { + if (set_nonblocking(nc->sk) < 0) { error("Set non blocking: %s (%d)", strerror(errno), errno); return -1; } - io = g_io_channel_unix_new(sk); + io = g_io_channel_unix_new(nc->sk); g_io_channel_set_close_on_unref(io, FALSE); - if (connect(sk, (struct sockaddr *) &l2a, sizeof(l2a))) { + if (connect(nc->sk, (struct sockaddr *) &l2a, sizeof(l2a))) { if (!(errno == EAGAIN || errno == EINPROGRESS)) { error("Connect failed. %s(%d)", strerror(errno), errno); + g_io_channel_close(io); g_io_channel_unref(io); return -1; } @@ -256,7 +263,6 @@ static int l2cap_connect(int sk, struct network_conn *nc) } else { l2cap_connect_cb(io, G_IO_OUT, nc); - g_io_channel_unref(io); } return 0; @@ -333,7 +339,6 @@ static DBusHandlerResult connection_connect(DBusConnection *conn, struct network_conn *nc = data; int sk; DBusError derr; - DBusMessage *reply, *signal; dbus_error_init(&derr); if (!dbus_message_get_args(msg, &derr, @@ -343,29 +348,22 @@ static DBusHandlerResult connection_connect(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } - sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); - if (sk < 0) { + nc->sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); + if (nc->sk < 0) { error("Cannot create L2CAP socket. %s(%d)", strerror(errno), errno); goto fail; } - if(l2cap_connect(sk, nc)) { + if(l2cap_connect(nc)) { error("Connect failed. %s(%d)", strerror(errno), errno); goto fail; } - /* FIXME: Do not replay until connection be connected */ - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - return send_message_and_unref(conn, reply); + nc->msg = dbus_message_ref(msg); + return DBUS_HANDLER_RESULT_HANDLED; fail: err_connection_failed(conn, msg, strerror(errno)); - signal = dbus_message_new_signal(nc->path, - NETWORK_CONNECTION_INTERFACE, "Disconnected"); - send_message_and_unref(nc->conn, signal); return DBUS_HANDLER_RESULT_HANDLED; } @@ -381,6 +379,7 @@ static DBusHandlerResult connection_disconnect(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } + close(nc->sk); ba2str(&nc->dst, addr); if (!bnep_kill_connection(addr)) { signal = dbus_message_new_signal(nc->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/manager.c | 2 +- network/server.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 125 insertions(+), 3 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 42542c9a..83cbaa14 100644 --- a/network/manager.c +++ b/network/manager.c @@ -145,7 +145,7 @@ static DBusHandlerResult create_server(DBusConnection *conn, if (g_slist_find_custom(mgr->servers, path, (GCompareFunc) strcmp)) return create_path(conn, msg, path, NULL); /* Return already exist error */ - if (server_register(conn, path, id) == -1) { + if (server_register(conn, path, id) < 0) { err_failed(conn, msg, "D-Bus path registration failed"); g_free(path); return DBUS_HANDLER_RESULT_HANDLED; 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 1e3f6fcf0d53335e6fd8456c11357c5b13d51006 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 26 Mar 2007 19:11:57 +0000 Subject: network: removed memory leak(servers/connections list) --- network/manager.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 83cbaa14..915f1a4b 100644 --- a/network/manager.c +++ b/network/manager.c @@ -306,11 +306,15 @@ static void manager_free(struct manager *mgr) if (!mgr) return; - if (mgr->servers) + if (mgr->servers) { + g_slist_foreach(mgr->servers, (GFunc)g_free, NULL); g_slist_free(mgr->servers); + } - if (mgr->connections) + if (mgr->connections) { + g_slist_foreach(mgr->connections, (GFunc)g_free, NULL); g_slist_free(mgr->connections); + } g_free (mgr); bnep_kill_all_connections(); -- cgit From 85a868434ea4de849a15673aa4f132f10d2ab94c Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 26 Mar 2007 19:20:49 +0000 Subject: Add connection watchdog. --- network/connection.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index af3d4090..8f83c68e 100644 --- a/network/connection.c +++ b/network/connection.c @@ -64,6 +64,20 @@ struct __service_16 { uint16_t src; } __attribute__ ((packed)); +static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond, + gpointer data) +{ + struct network_conn *nc = data; + DBusMessage *signal; + + signal = dbus_message_new_signal(nc->path, + NETWORK_CONNECTION_INTERFACE, "Disconnected"); + + send_message_and_unref(nc->conn, signal); + info("%s disconnected", nc->dev); + return (nc->up = FALSE); +} + static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, gpointer data) { @@ -136,7 +150,9 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, nc->up = TRUE; info("%s connected", nc->dev); - g_io_channel_unref(chan); + /* Start watchdog */ + g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL, + (GIOFunc) bnep_watchdog_cb, nc); return FALSE; failed: err_connection_failed(nc->conn, nc->msg, "bnep failed"); @@ -337,7 +353,6 @@ static DBusHandlerResult connection_connect(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_conn *nc = data; - int sk; DBusError derr; dbus_error_init(&derr); @@ -381,14 +396,7 @@ static DBusHandlerResult connection_disconnect(DBusConnection *conn, close(nc->sk); ba2str(&nc->dst, addr); - if (!bnep_kill_connection(addr)) { - signal = dbus_message_new_signal(nc->path, - NETWORK_CONNECTION_INTERFACE, "Disconnected"); - - send_message_and_unref(nc->conn, signal); - info("%s disconnected", nc->dev); - nc->up = FALSE; - } + bnep_kill_connection(addr); reply = dbus_message_new_method_return(msg); if (!reply) -- cgit From edfeafb77880e222832f47f99d668c5a445a24ba Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 26 Mar 2007 20:03:25 +0000 Subject: Remove warning. --- network/connection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 8f83c68e..4496f110 100644 --- a/network/connection.c +++ b/network/connection.c @@ -386,7 +386,7 @@ static DBusHandlerResult connection_disconnect(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_conn *nc = data; - DBusMessage *reply, *signal; + DBusMessage *reply; char addr[18]; if (!nc->up) { -- 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') 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 3ee5b90642bb7c8d2e88904600edac9d0d33efb4 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Mar 2007 10:21:45 +0000 Subject: Improve D-Bus system bus integration --- network/common.h | 2 +- network/connection.h | 3 ++- network/main.c | 22 +++++++++++++++------ network/manager.c | 55 ++++++++++++++-------------------------------------- network/manager.h | 3 +-- network/server.h | 1 + 6 files changed, 36 insertions(+), 50 deletions(-) (limited to 'network') diff --git a/network/common.h b/network/common.h index 36bb66b2..820a2b3a 100644 --- a/network/common.h +++ b/network/common.h @@ -20,7 +20,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ -/* BNEP functions */ + int bnep_init(void); int bnep_cleanup(void); diff --git a/network/connection.h b/network/connection.h index 70966b2c..08861a72 100644 --- a/network/connection.h +++ b/network/connection.h @@ -20,5 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ + int connection_register(DBusConnection *conn, const char *path, - const char *addr, uint16_t id); + const char *addr, uint16_t id); diff --git a/network/main.c b/network/main.c index 16a173c5..74675184 100644 --- a/network/main.c +++ b/network/main.c @@ -48,6 +48,7 @@ static void sig_term(int sig) int main(int argc, char *argv[]) { + DBusConnection *conn; struct sigaction sa; start_logging("network", "Bluetooth Network daemon"); @@ -64,18 +65,26 @@ int main(int argc, char *argv[]) enable_debug(); - /* Create event loop */ main_loop = g_main_loop_new(NULL, FALSE); - hal_init(NULL); + conn = dbus_bus_system_setup_with_main_loop(NULL, NULL, NULL); + if (!conn) { + g_main_loop_unref(main_loop); + exit(1); + } + + hal_init(conn); hal_create_device(NULL); - if (network_init() == -1) - goto fail; + if (network_init(conn) < 0) { + dbus_connection_unref(conn); + g_main_loop_unref(main_loop); + exit(1); + } if (argc > 1 && !strcmp(argv[1], "-s")) - internal_service("network"); + register_external_service(conn, "network", "Network service", ""); g_main_loop_run(main_loop); @@ -85,7 +94,8 @@ int main(int argc, char *argv[]) hal_cleanup(); -fail: + dbus_connection_unref(conn); + g_main_loop_unref(main_loop); info("Exit"); diff --git a/network/manager.c b/network/manager.c index 915f1a4b..60471429 100644 --- a/network/manager.c +++ b/network/manager.c @@ -341,17 +341,13 @@ int network_dbus_init(void) bdaddr_t src; int dev_id; - connection = init_dbus(NULL, NULL, NULL); - if (!connection) - return -1; - dbus_connection_set_exit_on_disconnect(connection, TRUE); mgr = g_new0(struct manager, 1); /* Fallback to catch invalid network path */ - if (!dbus_connection_register_fallback(connection, NETWORK_PATH, - &manager_table, mgr)) { + if (dbus_connection_register_fallback(connection, NETWORK_PATH, + &manager_table, mgr) == FALSE) { error("D-Bus failed to register %s path", NETWORK_PATH); goto fail; } @@ -384,43 +380,12 @@ fail: void network_dbus_exit(void) { dbus_connection_unregister_object_path(connection, NETWORK_PATH); - - dbus_connection_unref(connection); } -void internal_service(const char *identifier) +int network_init(DBusConnection *conn) { - DBusMessage *msg, *reply; - const char *name = "Network service", *desc = ""; - - info("Registering service"); + int err; - msg = dbus_message_new_method_call("org.bluez", "/org/bluez", - "org.bluez.Database", "RegisterService"); - if (!msg) { - error("Can't create service register method"); - return; - } - - dbus_message_append_args(msg, DBUS_TYPE_STRING, &identifier, - DBUS_TYPE_STRING, &name, - DBUS_TYPE_STRING, &desc, DBUS_TYPE_INVALID); - - reply = dbus_connection_send_with_reply_and_block(connection, msg, -1, - NULL); - if (!reply) { - error("Can't register service"); - return; - } - - dbus_message_unref(msg); - dbus_message_unref(reply); - - dbus_connection_flush(connection); -} - -int network_init(void) -{ if (bridge_init() < 0) { error("Can't init bridge module"); return -1; @@ -436,13 +401,23 @@ int network_init(void) return -1; } - return network_dbus_init(); + connection = dbus_connection_ref(conn); + + err = network_dbus_init(); + if (err < 0) + dbus_connection_unref(connection); + + return err; } void network_exit(void) { network_dbus_exit(); + dbus_connection_unref(connection); + + connection = NULL; + if (bridge_remove("pan0") < 0) error("Can't remove bridge"); diff --git a/network/manager.h b/network/manager.h index 81467c1a..d37ca3cd 100644 --- a/network/manager.h +++ b/network/manager.h @@ -21,6 +21,5 @@ * */ -int network_init(void); +int network_init(DBusConnection *conn); void network_exit(void); -void internal_service(const char *identifier); diff --git a/network/server.h b/network/server.h index bb15e4d7..27b38ba6 100644 --- a/network/server.h +++ b/network/server.h @@ -20,4 +20,5 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ + int server_register(DBusConnection *conn, const char *path, uint16_t id); -- cgit From 71aaf58c77b00f192a2903a4e43b35a88869782b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 Mar 2007 10:38:17 +0000 Subject: The service must start even without any adapters attached --- network/manager.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 60471429..a8b9974f 100644 --- a/network/manager.c +++ b/network/manager.c @@ -339,7 +339,9 @@ int network_dbus_init(void) { struct manager *mgr; bdaddr_t src; +#if 0 int dev_id; +#endif dbus_connection_set_exit_on_disconnect(connection, TRUE); @@ -356,6 +358,7 @@ int network_dbus_init(void) /* Set the default adapter */ bacpy(&src, BDADDR_ANY); +#if 0 dev_id = hci_get_route(&src); if (dev_id < 0) { error("Bluetooth device not available"); @@ -366,6 +369,7 @@ int network_dbus_init(void) error("Can't get local adapter device info"); goto fail; } +#endif bacpy(&mgr->src, &src); -- cgit From 580d52c4b07c5e44b17e7d0189e7d84f4a7667fb Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 27 Mar 2007 21:30:35 +0000 Subject: Add err_not_supported. --- network/error.c | 8 ++++++++ network/error.h | 1 + 2 files changed, 9 insertions(+) (limited to 'network') diff --git a/network/error.c b/network/error.c index 87829dea..684bda2a 100644 --- a/network/error.c +++ b/network/error.c @@ -70,3 +70,11 @@ DBusHandlerResult err_invalid_args(DBusConnection *conn, dbus_message_new_error(msg, NETWORK_ERROR_INTERFACE ".InvalidArguments", str)); } + +DBusHandlerResult err_not_supported(DBusConnection *conn, DBusMessage *msg) +{ + return send_message_and_unref(conn, + dbus_message_new_error(msg, + NETWORK_ERROR_INTERFACE ".NotSupported", + "The service is not supported by the remote device")); +} diff --git a/network/error.h b/network/error.h index 28ccdb07..44e7690a 100644 --- a/network/error.h +++ b/network/error.h @@ -34,3 +34,4 @@ DBusHandlerResult err_connection_failed(DBusConnection *conn, DBusHandlerResult err_invalid_args(DBusConnection *conn, DBusMessage *msg, const char *str); +DBusHandlerResult err_not_supported(DBusConnection *conn, DBusMessage *msg); -- 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') 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 fab1c990ee59d3f41331f6c612ba302c2543710b Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 27 Mar 2007 21:58:58 +0000 Subject: Add code to check server capabilities. --- network/manager.c | 322 ++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 251 insertions(+), 71 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index a8b9974f..58c335bb 100644 --- a/network/manager.c +++ b/network/manager.c @@ -51,40 +51,28 @@ struct manager { GSList *connections; /* Network registered connections paths */ }; +struct pending_reply { + DBusConnection *conn; + DBusMessage *msg; + struct manager *mgr; + uint16_t id; + char *addr; + char *path; + char *adapter_path; +}; + static DBusConnection *connection = NULL; -static DBusHandlerResult list_paths(DBusConnection *conn, DBusMessage *msg, - GSList *list) +static void pending_reply_free(struct pending_reply *pr) { - DBusMessage *reply; - DBusMessageIter iter; - DBusMessageIter array_iter; - - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + if (pr->addr) + g_free(pr->addr); - dbus_message_iter_init_append(reply, &iter); - dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, - DBUS_TYPE_STRING_AS_STRING, &array_iter); + if (pr->path) + g_free(pr->path); - for (; list; list = list->next) { - dbus_message_iter_append_basic(&array_iter, - DBUS_TYPE_STRING, - &list->data); - } - - dbus_message_iter_close_container(&iter, &array_iter); - - return send_message_and_unref(conn, reply); -} - -static DBusHandlerResult list_servers(DBusConnection *conn, DBusMessage *msg, - void *data) -{ - struct manager *mgr = data; - - return list_paths(conn, msg, mgr->servers); + if (pr->adapter_path) + g_free(pr->adapter_path); } static DBusHandlerResult create_path(DBusConnection *conn, @@ -116,44 +104,29 @@ static DBusHandlerResult create_path(DBusConnection *conn, return send_message_and_unref(conn, reply); } -static DBusHandlerResult create_server(DBusConnection *conn, - DBusMessage *msg, void *data) +static DBusHandlerResult list_paths(DBusConnection *conn, DBusMessage *msg, + GSList *list) { - struct manager *mgr = data; - DBusError derr; - const char *str; - char *path; - uint16_t id; - - dbus_error_init(&derr); - if (!dbus_message_get_args(msg, &derr, - DBUS_TYPE_STRING, &str, - DBUS_TYPE_INVALID)) { - err_invalid_args(conn, msg, derr.message); - dbus_error_free(&derr); - return DBUS_HANDLER_RESULT_HANDLED; - } - - id = bnep_service_id(str); - if ((id != BNEP_SVC_GN) && (id != BNEP_SVC_NAP)) - return err_invalid_args(conn, msg, "Not supported"); + DBusMessage *reply; + DBusMessageIter iter; + DBusMessageIter array_iter; - path = g_new0(char, 32); - snprintf(path, 32, NETWORK_PATH "/server/%s", bnep_name(id)); + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; - /* Path already registered */ - if (g_slist_find_custom(mgr->servers, path, (GCompareFunc) strcmp)) - return create_path(conn, msg, path, NULL); /* Return already exist error */ + dbus_message_iter_init_append(reply, &iter); + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, + DBUS_TYPE_STRING_AS_STRING, &array_iter); - if (server_register(conn, path, id) < 0) { - err_failed(conn, msg, "D-Bus path registration failed"); - g_free(path); - return DBUS_HANDLER_RESULT_HANDLED; + for (; list; list = list->next) { + dbus_message_iter_append_basic(&array_iter, + DBUS_TYPE_STRING, + &list->data); } + dbus_message_iter_close_container(&iter, &array_iter); - mgr->servers = g_slist_append(mgr->servers, g_strdup(path)); - - return create_path(conn, msg, path, "ServerCreated"); + return send_message_and_unref(conn, reply); } static DBusHandlerResult remove_path(DBusConnection *conn, @@ -200,6 +173,206 @@ static DBusHandlerResult remove_path(DBusConnection *conn, return send_message_and_unref(conn, reply); } +static void pan_record_reply(DBusPendingCall *call, void *data) +{ + struct pending_reply *pr = data; + DBusMessage *reply = dbus_pending_call_steal_reply(call); + DBusError derr; + int len; + uint8_t *rec_bin; + + dbus_error_init(&derr); + if (dbus_set_error_from_message(&derr, reply)) { + if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) + err_connection_failed(pr->conn, pr->msg, derr.message); + else + err_not_supported(pr->conn, pr->msg); + + error("GetRemoteServiceRecord failed: %s(%s)", derr.name, + derr.message); + goto fail; + } + + if (!dbus_message_get_args(reply, &derr, + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &rec_bin, &len, + DBUS_TYPE_INVALID)) { + err_not_supported(pr->conn, pr->msg); + error("%s: %s", derr.name, derr.message); + goto fail; + } + + if (len == 0) { + err_not_supported(pr->conn, pr->msg); + error("Invalid PAN service record length"); + goto fail; + } + + + if (connection_register(pr->conn, pr->path, pr->addr, pr->id) == -1) { + err_failed(pr->conn, pr->msg, "D-Bus path registration failed"); + goto fail; + } + + pr->mgr->connections = g_slist_append(pr->mgr->connections, + g_strdup(pr->path)); + + create_path(pr->conn, pr->msg, g_strdup (pr->path), "ConnectionCreated"); +fail: + dbus_error_free(&derr); + pending_reply_free(pr); + dbus_message_unref(reply); + dbus_pending_call_unref(call); +} + +static int get_record(struct pending_reply *pr, uint32_t handle, + DBusPendingCallNotifyFunction cb) +{ + DBusMessage *msg; + DBusPendingCall *pending; + + msg = dbus_message_new_method_call("org.bluez", pr->adapter_path, + "org.bluez.Adapter", "GetRemoteServiceRecord"); + if (!msg) + return -1; + + dbus_message_append_args(msg, + DBUS_TYPE_STRING, &pr->addr, + DBUS_TYPE_UINT32, &handle, + DBUS_TYPE_INVALID); + + if (dbus_connection_send_with_reply(pr->conn, msg, &pending, -1) == FALSE) { + error("Can't send D-Bus message."); + return -1; + } + + dbus_pending_call_set_notify(pending, cb, pr, NULL); + dbus_message_unref(msg); + + return 0; +} + +static void pan_handle_reply(DBusPendingCall *call, void *data) +{ + struct pending_reply *pr = data; + DBusMessage *reply = dbus_pending_call_steal_reply(call); + DBusError derr; + uint32_t *phandle; + int len; + + dbus_error_init(&derr); + if (dbus_set_error_from_message(&derr, reply)) { + if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) + err_connection_failed(pr->conn, pr->msg, derr.message); + else + err_not_supported(pr->conn, pr->msg); + + error("GetRemoteServiceHandles: %s(%s)", derr.name, derr.message); + goto fail; + } + + if (!dbus_message_get_args(reply, &derr, + DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &phandle, &len, + DBUS_TYPE_INVALID)) { + err_not_supported(pr->conn, pr->msg); + error("%s: %s", derr.name, derr.message); + goto fail; + } + + if (!len) { + err_not_supported(pr->conn, pr->msg); + goto fail; + } + + if (get_record(pr, *phandle, pan_record_reply) < 0) { + err_not_supported(pr->conn, pr->msg); + goto fail; + } + + dbus_message_unref(reply); + dbus_pending_call_unref(call); + return; +fail: + dbus_error_free(&derr); + pending_reply_free(pr); +} + +static int get_handles(struct pending_reply *pr, DBusPendingCallNotifyFunction cb) +{ + DBusMessage *msg; + DBusPendingCall *pending; + const char *uuid; + + msg = dbus_message_new_method_call("org.bluez", pr->adapter_path, + "org.bluez.Adapter", "GetRemoteServiceHandles"); + if (!msg) + return -1; + + uuid = bnep_uuid(pr->id); + dbus_message_append_args(msg, + DBUS_TYPE_STRING, &pr->addr, + DBUS_TYPE_STRING, &uuid, + DBUS_TYPE_INVALID); + + if (dbus_connection_send_with_reply(pr->conn, msg, &pending, -1) == FALSE) { + error("Can't send D-Bus message."); + return -1; + } + + dbus_pending_call_set_notify(pending, cb, pr, NULL); + dbus_message_unref(msg); + + return 0; +} + +static DBusHandlerResult list_servers(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + struct manager *mgr = data; + + return list_paths(conn, msg, mgr->servers); +} + +static DBusHandlerResult create_server(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + struct manager *mgr = data; + DBusError derr; + const char *str; + char *path; + int id; + + dbus_error_init(&derr); + if (!dbus_message_get_args(msg, &derr, + DBUS_TYPE_STRING, &str, + DBUS_TYPE_INVALID)) { + err_invalid_args(conn, msg, derr.message); + dbus_error_free(&derr); + return DBUS_HANDLER_RESULT_HANDLED; + } + + id = bnep_service_id(str); + if ((id != BNEP_SVC_GN) && (id != BNEP_SVC_NAP)) + return err_invalid_args(conn, msg, "Not supported"); + + path = g_new0(char, 32); + snprintf(path, 32, NETWORK_PATH "/server/%X", id); + + /* Path already registered */ + if (g_slist_find_custom(mgr->servers, path, (GCompareFunc) strcmp)) + return create_path(conn, msg, path, NULL); /* Return already exist error */ + + /* FIXME: define which type should be used -- string/uuid str/uui128 */ + if (server_register(conn, path, id) == -1) { + err_failed(conn, msg, "D-Bus path registration failed"); + g_free(path); + return DBUS_HANDLER_RESULT_HANDLED; + } + + mgr->servers = g_slist_append(mgr->servers, g_strdup(path)); + + return create_path(conn, msg, path, "ServerCreated"); +} + static DBusHandlerResult remove_server(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -220,11 +393,12 @@ static DBusHandlerResult create_connection(DBusConnection *conn, DBusMessage *msg, void *data) { struct manager *mgr = data; + struct pending_reply *pr; static int uid = 0; DBusError derr; + char src_addr[18]; const char *addr; const char *str; - char *path; uint16_t id; dbus_error_init(&derr); @@ -241,18 +415,24 @@ static DBusHandlerResult create_connection(DBusConnection *conn, if ((id != BNEP_SVC_GN) && (id != BNEP_SVC_NAP)) return err_invalid_args(conn, msg, "Not supported"); - path = g_new0(char, 32); - snprintf(path, 32, NETWORK_PATH "/connection%d", uid++); - - if (connection_register(conn, path, addr, id) == -1) { + pr = g_new(struct pending_reply, 1); + pr->conn = conn; + pr->msg = dbus_message_ref(msg); + pr->mgr = mgr; + pr->addr = g_strdup(addr); + pr->id = id; + pr->path = g_new0(char, 48); + snprintf(pr->path, 48, NETWORK_PATH "/connection%d", uid++); + ba2str(&mgr->src, src_addr); + pr->adapter_path = g_new0(char, 32); + snprintf(pr->adapter_path , 32, "/org/bluez/hci%d", hci_devid(src_addr)); + + if (get_handles(pr, pan_handle_reply) < 0) { err_failed(conn, msg, "D-Bus path registration failed"); - g_free(path); - return DBUS_HANDLER_RESULT_HANDLED; + pending_reply_free(pr); } - mgr->connections = g_slist_append(mgr->connections, g_strdup(path)); - - return create_path(conn, msg, path, "ConnectionCreated"); + return DBUS_HANDLER_RESULT_HANDLED; } static DBusHandlerResult remove_connection(DBusConnection *conn, -- cgit From e7b6b11e91bb59eccf844abe4bb47b015b0c3cdf Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 27 Mar 2007 22:11:29 +0000 Subject: Get rid of old ioctl compability hack. --- network/common.c | 51 +++++++++------------------------------------------ network/common.h | 2 +- network/connection.c | 12 +++--------- 3 files changed, 13 insertions(+), 52 deletions(-) (limited to 'network') diff --git a/network/common.c b/network/common.c index ec10cc34..593ea83c 100644 --- a/network/common.c +++ b/network/common.c @@ -44,17 +44,6 @@ static int ctl; #define NAP_UUID "00001116-0000-1000-8000-00805f9b34fb" #define GN_UUID "00001117-0000-1000-8000-00805f9b34fb" -/* Compatibility with old ioctls */ -#define OLD_BNEPCONADD 1 -#define OLD_BNEPCONDEL 2 -#define OLD_BNEPGETCONLIST 3 -#define OLD_BNEPGETCONINFO 4 - -static unsigned long bnepconnadd; -static unsigned long bnepconndel; -static unsigned long bnepgetconnlist; -static unsigned long bnepgetconninfo; - static struct { const char *name; /* Friendly name */ const char *uuid128; /* UUID 128 */ @@ -114,32 +103,10 @@ const char *bnep_name(uint16_t id) int bnep_init(void) { ctl = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_BNEP); + if (ctl < 0) { error("Failed to open control socket"); - return 1; - } - - /* Temporary ioctl compatibility hack */ - { - struct bnep_connlist_req req; - struct bnep_conninfo ci[1]; - - req.cnum = 1; - req.ci = ci; - - if (!ioctl(ctl, BNEPGETCONNLIST, &req)) { - /* New ioctls */ - bnepconnadd = BNEPCONNADD; - bnepconndel = BNEPCONNDEL; - bnepgetconnlist = BNEPGETCONNLIST; - bnepgetconninfo = BNEPGETCONNINFO; - } else { - /* Old ioctls */ - bnepconnadd = OLD_BNEPCONADD; - bnepconndel = OLD_BNEPCONDEL; - bnepgetconnlist = OLD_BNEPGETCONLIST; - bnepgetconninfo = OLD_BNEPGETCONINFO; - } + return -1; } return 0; @@ -151,14 +118,13 @@ int bnep_cleanup(void) return 0; } -int bnep_kill_connection(const char *addr) +int bnep_kill_connection(bdaddr_t *dst) { struct bnep_conndel_req req; - uint8_t *dst = (void *) strtoba(addr); - memcpy(req.dst, dst, ETH_ALEN); + baswap((bdaddr_t *)&req.dst, dst); req.flags = 0; - if (ioctl(ctl, bnepconndel, &req)) { + if (ioctl(ctl, BNEPCONNDEL, &req)) { error("Failed to kill connection"); return -1; } @@ -173,7 +139,7 @@ int bnep_kill_all_connections(void) req.cnum = 48; req.ci = ci; - if (ioctl(ctl, bnepgetconnlist, &req)) { + if (ioctl(ctl, BNEPGETCONNLIST, &req)) { error("Failed to get connection list"); return -1; } @@ -182,7 +148,8 @@ int bnep_kill_all_connections(void) struct bnep_conndel_req req; memcpy(req.dst, ci[i].dst, ETH_ALEN); req.flags = 0; - ioctl(ctl, bnepconndel, &req); + if (ioctl(ctl, BNEPCONNDEL, &req)) + error("Failed to kill connection"); } return 0; } @@ -195,7 +162,7 @@ int bnep_connadd(int sk, uint16_t role, char *dev) req.device[15] = '\0'; req.sock = sk; req.role = role; - if (ioctl(ctl, bnepconnadd, &req)) { + if (ioctl(ctl, BNEPCONNADD, &req)) { error("Failed to add device %s", dev); return -1; } diff --git a/network/common.h b/network/common.h index 820a2b3a..b3941e4f 100644 --- a/network/common.h +++ b/network/common.h @@ -28,7 +28,7 @@ uint16_t bnep_service_id(const char *svc); const char *bnep_uuid(uint16_t id); const char *bnep_name(uint16_t id); -int bnep_kill_connection(const char *addr); +int bnep_kill_connection(bdaddr_t *dst); int bnep_kill_all_connections(void); int bnep_connadd(int sk, uint16_t role, char *dev); diff --git a/network/connection.c b/network/connection.c index 4496f110..ff3f5aab 100644 --- a/network/connection.c +++ b/network/connection.c @@ -387,7 +387,6 @@ static DBusHandlerResult connection_disconnect(DBusConnection *conn, { struct network_conn *nc = data; DBusMessage *reply; - char addr[18]; if (!nc->up) { err_failed(conn, msg, "Device not connected"); @@ -395,8 +394,7 @@ static DBusHandlerResult connection_disconnect(DBusConnection *conn, } close(nc->sk); - ba2str(&nc->dst, addr); - bnep_kill_connection(addr); + bnep_kill_connection(&nc->dst); reply = dbus_message_new_method_return(msg); if (!reply) @@ -461,18 +459,14 @@ static DBusHandlerResult connection_message(DBusConnection *conn, static void connection_free(struct network_conn *nc) { - char addr[18]; - if (!nc) return; if (nc->path) g_free(nc->path); - if (nc->up) { - ba2str(&nc->dst, addr); - bnep_kill_connection(addr); - } + if (nc->up) + bnep_kill_connection(&nc->dst); if (nc->dev) g_free(nc->dev); -- 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') 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') 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') 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 fdacbf3a77476dc525425ee060bbf5809383b885 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 28 Mar 2007 15:24:22 +0000 Subject: network: Added more debug error information for ioctl BNEPCONNADD call --- network/common.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'network') diff --git a/network/common.c b/network/common.c index 593ea83c..c486ad7f 100644 --- a/network/common.c +++ b/network/common.c @@ -163,8 +163,10 @@ int bnep_connadd(int sk, uint16_t role, char *dev) req.sock = sk; req.role = role; if (ioctl(ctl, BNEPCONNADD, &req)) { - error("Failed to add device %s", dev); - return -1; + int err = errno; + error("Failed to add device %s: %s(%d)", + dev, strerror(err), err); + return -err; } strncpy(dev, req.device, 16); return 0; -- 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') 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 1e711201f649f10fee1a8365976d42b98e7373f9 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 28 Mar 2007 15:51:54 +0000 Subject: Add connection state to prevent concurrent connections --- network/connection.c | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index ff3f5aab..1ed9e433 100644 --- a/network/connection.c +++ b/network/connection.c @@ -47,6 +47,12 @@ #define NETWORK_CONNECTION_INTERFACE "org.bluez.network.Connection" #include "connection.h" +typedef enum { + CONNECTED, + CONNECTING, + DISCONNECTED +} conn_state; + struct network_conn { DBusConnection *conn; DBusMessage *msg; @@ -55,7 +61,7 @@ struct network_conn { char *path; /* D-Bus path */ char *dev; /* BNEP interface name */ uint16_t id; /* Service Class Identifier */ - gboolean up; + conn_state state; int sk; }; @@ -75,7 +81,7 @@ static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond, send_message_and_unref(nc->conn, signal); info("%s disconnected", nc->dev); - return (nc->up = FALSE); + return (!nc->state); } static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, @@ -147,7 +153,7 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, send_message_and_unref(nc->conn, reply); - nc->up = TRUE; + nc->state = CONNECTED; info("%s connected", nc->dev); /* Start watchdog */ @@ -155,6 +161,7 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, (GIOFunc) bnep_watchdog_cb, nc); return FALSE; failed: + nc->state = DISCONNECTED; err_connection_failed(nc->conn, nc->msg, "bnep failed"); g_io_channel_close(chan); g_io_channel_unref(chan); @@ -220,6 +227,7 @@ static gboolean l2cap_connect_cb(GIOChannel *chan, g_io_channel_unref(chan); return FALSE; failed: + nc->state = DISCONNECTED; err_connection_failed(nc->conn, nc->msg, strerror(errno)); g_io_channel_close(chan); g_io_channel_unref(chan); @@ -290,13 +298,14 @@ static DBusHandlerResult get_address(DBusConnection *conn, DBusMessage *msg, struct network_conn *nc = data; DBusMessage *reply; char raddr[18]; + const char *paddr = raddr; ba2str(&nc->dst, raddr); reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; - dbus_message_append_args(reply, DBUS_TYPE_STRING, raddr, + dbus_message_append_args(reply, DBUS_TYPE_STRING, &paddr, DBUS_TYPE_INVALID); return send_message_and_unref(conn, reply); @@ -338,6 +347,11 @@ static DBusHandlerResult get_interface(DBusConnection *conn, DBusMessage *msg, struct network_conn *nc = data; DBusMessage *reply; + if (nc->state != CONNECTED) { + err_failed(conn, msg, "Device not connected"); + return DBUS_HANDLER_RESULT_HANDLED; + } + reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; @@ -355,6 +369,11 @@ static DBusHandlerResult connection_connect(DBusConnection *conn, struct network_conn *nc = data; DBusError derr; + if (nc->state != DISCONNECTED) { + err_failed(conn, msg, "Device already connected"); + return DBUS_HANDLER_RESULT_HANDLED; + } + dbus_error_init(&derr); if (!dbus_message_get_args(msg, &derr, DBUS_TYPE_INVALID)) { @@ -364,6 +383,7 @@ static DBusHandlerResult connection_connect(DBusConnection *conn, } nc->sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); + nc->state = CONNECTING; if (nc->sk < 0) { error("Cannot create L2CAP socket. %s(%d)", strerror(errno), errno); @@ -378,6 +398,7 @@ static DBusHandlerResult connection_connect(DBusConnection *conn, nc->msg = dbus_message_ref(msg); return DBUS_HANDLER_RESULT_HANDLED; fail: + nc->state = DISCONNECTED; err_connection_failed(conn, msg, strerror(errno)); return DBUS_HANDLER_RESULT_HANDLED; } @@ -388,7 +409,7 @@ static DBusHandlerResult connection_disconnect(DBusConnection *conn, struct network_conn *nc = data; DBusMessage *reply; - if (!nc->up) { + if (nc->state != CONNECTED) { err_failed(conn, msg, "Device not connected"); return DBUS_HANDLER_RESULT_HANDLED; } @@ -408,12 +429,14 @@ static DBusHandlerResult is_connected(DBusConnection *conn, DBusMessage *msg, { struct network_conn *nc = data; DBusMessage *reply; + gboolean up; reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; - dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &nc->up, + up = (nc->state == CONNECTED); + dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &up, DBUS_TYPE_INVALID); return send_message_and_unref(conn, reply); @@ -465,7 +488,7 @@ static void connection_free(struct network_conn *nc) if (nc->path) g_free(nc->path); - if (nc->up) + if (nc->state == CONNECTED) bnep_kill_connection(&nc->dst); if (nc->dev) @@ -493,7 +516,6 @@ int connection_register(DBusConnection *conn, const char *path, const char *addr, uint16_t id) { struct network_conn *nc; - static int bnep = 0; if (!conn) return -1; @@ -512,9 +534,8 @@ int connection_register(DBusConnection *conn, const char *path, str2ba(addr, &nc->dst); nc->id = id; /* FIXME: Check for device */ - nc->dev = g_new(char, 16); - snprintf(nc->dev, 16, "bnep%d", bnep++); - nc->up = FALSE; + nc->dev = g_strdup("bnep%d"); + nc->state = DISCONNECTED; nc->conn = conn; info("Registered connection path:%s", path); return 0; -- 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') 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') 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') 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 ead055c1bc5bf032488d2b71838596a3e355a707 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 29 Mar 2007 13:33:27 +0000 Subject: Lower number of possible interfaces from 48 to 7 and other minor fixes. --- network/common.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'network') diff --git a/network/common.c b/network/common.c index c486ad7f..d9f60374 100644 --- a/network/common.c +++ b/network/common.c @@ -105,8 +105,10 @@ int bnep_init(void) ctl = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_BNEP); if (ctl < 0) { - error("Failed to open control socket"); - return -1; + int err = errno; + error("Failed to open control socket: %s (%d)", + strerror(err), err); + return -err; } return 0; @@ -125,8 +127,10 @@ int bnep_kill_connection(bdaddr_t *dst) baswap((bdaddr_t *)&req.dst, dst); req.flags = 0; if (ioctl(ctl, BNEPCONNDEL, &req)) { - error("Failed to kill connection"); - return -1; + int err = errno; + error("Failed to kill connection: %s (%d)", + strerror(err), err); + return -err; } return 0; } @@ -134,22 +138,24 @@ int bnep_kill_connection(bdaddr_t *dst) int bnep_kill_all_connections(void) { struct bnep_connlist_req req; - struct bnep_conninfo ci[48]; + struct bnep_conninfo ci[7]; int i; - req.cnum = 48; + memset(&req, 0, sizeof(req)); + req.cnum = 7; req.ci = ci; if (ioctl(ctl, BNEPGETCONNLIST, &req)) { - error("Failed to get connection list"); - return -1; + int err = errno; + error("Failed to get connection list: %s (%d)", + strerror(err), err); + return -err; } for (i=0; i < req.cnum; i++) { struct bnep_conndel_req req; memcpy(req.dst, ci[i].dst, ETH_ALEN); req.flags = 0; - if (ioctl(ctl, BNEPCONNDEL, &req)) - error("Failed to kill connection"); + ioctl(ctl, BNEPCONNDEL, &req); } return 0; } -- cgit From fe648edb4d67bb603509f392d3c82ebfe8334921 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 29 Mar 2007 14:01:25 +0000 Subject: Add code to extract record attributes. --- network/connection.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++---- network/connection.h | 3 ++- network/manager.c | 10 ++++++-- 3 files changed, 76 insertions(+), 8 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 1ed9e433..7b944c6c 100644 --- a/network/connection.c +++ b/network/connection.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include @@ -60,6 +62,8 @@ struct network_conn { bdaddr_t dst; char *path; /* D-Bus path */ char *dev; /* BNEP interface name */ + char *name; + char *desc; uint16_t id; /* Service Class Identifier */ conn_state state; int sk; @@ -81,7 +85,10 @@ static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond, send_message_and_unref(nc->conn, signal); info("%s disconnected", nc->dev); - return (!nc->state); + nc->state = DISCONNECTED; + g_io_channel_close(chan); + g_io_channel_unref(chan); + return FALSE; } static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, @@ -332,13 +339,44 @@ static DBusHandlerResult get_uuid(DBusConnection *conn, DBusMessage *msg, static DBusHandlerResult get_name(DBusConnection *conn, DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct network_conn *nc = data; + DBusMessage *reply; + + if (!nc->name) { + err_failed(conn, msg, "Cannot find service name"); + return DBUS_HANDLER_RESULT_HANDLED; + } + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_message_append_args(reply, DBUS_TYPE_STRING, &nc->name, + DBUS_TYPE_INVALID); + + return send_message_and_unref(conn, reply); + } static DBusHandlerResult get_description(DBusConnection *conn, DBusMessage *msg, void *data) { - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + struct network_conn *nc = data; + DBusMessage *reply; + + if (!nc->desc) { + err_failed(conn, msg, "Cannot find service description"); + return DBUS_HANDLER_RESULT_HANDLED; + } + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_message_append_args(reply, DBUS_TYPE_STRING, &nc->desc, + DBUS_TYPE_INVALID); + + return send_message_and_unref(conn, reply); } static DBusHandlerResult get_interface(DBusConnection *conn, DBusMessage *msg, @@ -494,6 +532,12 @@ static void connection_free(struct network_conn *nc) if (nc->dev) g_free(nc->dev); + if (nc->name) + g_free(nc->name); + + if (nc->desc) + g_free(nc->desc); + g_free(nc); } @@ -513,9 +557,10 @@ static const DBusObjectPathVTable connection_table = { }; int connection_register(DBusConnection *conn, const char *path, - const char *addr, uint16_t id) + const char *addr, uint16_t id, const sdp_record_t *rec) { struct network_conn *nc; + sdp_data_t *d; if (!conn) return -1; @@ -533,7 +578,23 @@ int connection_register(DBusConnection *conn, const char *path, bacpy(&nc->src, BDADDR_ANY); str2ba(addr, &nc->dst); nc->id = id; - /* FIXME: Check for device */ + + /* Extract service name from record */ + d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY); + if (d) { + nc->name = g_new0(char, d->unitSize); + snprintf(nc->name, d->unitSize, "%.*s", d->unitSize, + d->val.str); + } + + /* Extract service description from record */ + d = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY); + if (d) { + nc->desc = g_new0(char, d->unitSize); + snprintf(nc->desc, d->unitSize, "%.*s", d->unitSize, + d->val.str); + } + nc->dev = g_strdup("bnep%d"); nc->state = DISCONNECTED; nc->conn = conn; diff --git a/network/connection.h b/network/connection.h index 08861a72..08f36e1c 100644 --- a/network/connection.h +++ b/network/connection.h @@ -22,4 +22,5 @@ */ int connection_register(DBusConnection *conn, const char *path, - const char *addr, uint16_t id); + const char *addr, uint16_t id, + const sdp_record_t *rec); diff --git a/network/manager.c b/network/manager.c index 58c335bb..2f745c1c 100644 --- a/network/manager.c +++ b/network/manager.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include @@ -178,8 +180,9 @@ static void pan_record_reply(DBusPendingCall *call, void *data) struct pending_reply *pr = data; DBusMessage *reply = dbus_pending_call_steal_reply(call); DBusError derr; - int len; + int len, scanned; uint8_t *rec_bin; + sdp_record_t *rec; dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { @@ -207,8 +210,10 @@ static void pan_record_reply(DBusPendingCall *call, void *data) goto fail; } + rec = sdp_extract_pdu(rec_bin, &scanned); - if (connection_register(pr->conn, pr->path, pr->addr, pr->id) == -1) { + if (connection_register(pr->conn, pr->path, pr->addr, pr->id, + rec) == -1) { err_failed(pr->conn, pr->msg, "D-Bus path registration failed"); goto fail; } @@ -218,6 +223,7 @@ static void pan_record_reply(DBusPendingCall *call, void *data) create_path(pr->conn, pr->msg, g_strdup (pr->path), "ConnectionCreated"); fail: + sdp_record_free(rec); dbus_error_free(&derr); pending_reply_free(pr); dbus_message_unref(reply); -- 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') 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') 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') 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 d0c225bdc87726ead2b2bcf5ba8e80921c338b57 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 29 Mar 2007 19:40:17 +0000 Subject: Fix message unref and interface name bugs. --- network/connection.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 7b944c6c..03ee754d 100644 --- a/network/connection.c +++ b/network/connection.c @@ -61,7 +61,7 @@ struct network_conn { bdaddr_t src; bdaddr_t dst; char *path; /* D-Bus path */ - char *dev; /* BNEP interface name */ + char dev[16]; /* BNEP interface name */ char *name; char *desc; uint16_t id; /* Service Class Identifier */ @@ -74,6 +74,8 @@ struct __service_16 { uint16_t src; } __attribute__ ((packed)); +static char netdev[16] = "bnep%d"; + static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond, gpointer data) { @@ -428,14 +430,18 @@ static DBusHandlerResult connection_connect(DBusConnection *conn, goto fail; } + nc->msg = dbus_message_ref(msg); if(l2cap_connect(nc)) { error("Connect failed. %s(%d)", strerror(errno), errno); goto fail; } - nc->msg = dbus_message_ref(msg); return DBUS_HANDLER_RESULT_HANDLED; fail: + if (nc->msg) { + dbus_message_unref(nc->msg); + nc->msg = NULL; + } nc->state = DISCONNECTED; err_connection_failed(conn, msg, strerror(errno)); return DBUS_HANDLER_RESULT_HANDLED; @@ -595,7 +601,9 @@ int connection_register(DBusConnection *conn, const char *path, d->val.str); } - nc->dev = g_strdup("bnep%d"); + memset(nc->dev, 0, 16); + strncpy(nc->dev, netdev, 16); + nc->state = DISCONNECTED; nc->conn = conn; info("Registered connection path:%s", path); -- cgit From 3b82e98cb01ce9632701c0872e5e64f1290a0c8a Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 29 Mar 2007 20:23:05 +0000 Subject: Fixes to use DefaultAdapter when an adapter is necessary. --- network/manager.c | 107 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 71 insertions(+), 36 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 2f745c1c..1accb8a2 100644 --- a/network/manager.c +++ b/network/manager.c @@ -48,7 +48,6 @@ #include "common.h" struct manager { - bdaddr_t src; /* Local adapter BT address */ GSList *servers; /* Network registered servers paths */ GSList *connections; /* Network registered connections paths */ }; @@ -182,11 +181,12 @@ static void pan_record_reply(DBusPendingCall *call, void *data) DBusError derr; int len, scanned; uint8_t *rec_bin; - sdp_record_t *rec; + sdp_record_t *rec = NULL; dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { - if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) + if (dbus_error_has_name(&derr, + "org.bluez.Error.ConnectionAttemptFailed")) err_connection_failed(pr->conn, pr->msg, derr.message); else err_not_supported(pr->conn, pr->msg); @@ -267,18 +267,20 @@ static void pan_handle_reply(DBusPendingCall *call, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { - if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) + if (dbus_error_has_name(&derr, + "org.bluez.Error.ConnectionAttemptFailed")) err_connection_failed(pr->conn, pr->msg, derr.message); else err_not_supported(pr->conn, pr->msg); - error("GetRemoteServiceHandles: %s(%s)", derr.name, derr.message); + error("GetRemoteServiceHandles: %s(%s)", derr.name, + derr.message); goto fail; } if (!dbus_message_get_args(reply, &derr, - DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &phandle, &len, - DBUS_TYPE_INVALID)) { + DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &phandle, + &len, DBUS_TYPE_INVALID)) { err_not_supported(pr->conn, pr->msg); error("%s: %s", derr.name, derr.message); goto fail; @@ -302,7 +304,8 @@ fail: pending_reply_free(pr); } -static int get_handles(struct pending_reply *pr, DBusPendingCallNotifyFunction cb) +static int get_handles(struct pending_reply *pr, + DBusPendingCallNotifyFunction cb) { DBusMessage *msg; DBusPendingCall *pending; @@ -330,6 +333,65 @@ static int get_handles(struct pending_reply *pr, DBusPendingCallNotifyFunction c return 0; } +static void default_adapter_reply(DBusPendingCall *call, void *data) +{ + struct pending_reply *pr = data; + DBusMessage *reply = dbus_pending_call_steal_reply(call); + DBusError derr; + const char *adapter; + + dbus_error_init(&derr); + if (dbus_set_error_from_message(&derr, reply)) { + err_connection_failed(pr->conn, pr->msg, derr.message); + error("DefaultAdapter: %s(%s)", derr.name, derr.message); + goto fail; + } + + if (!dbus_message_get_args(reply, &derr, + DBUS_TYPE_STRING, &adapter, + DBUS_TYPE_INVALID)) { + err_connection_failed(pr->conn, pr->msg, derr.message); + error("%s: %s", derr.name, derr.message); + goto fail; + } + + pr->adapter_path = g_strdup(adapter); + + if (get_handles(pr, pan_handle_reply) < 0) { + err_failed(pr->conn, pr->msg, "D-Bus path registration failed"); + goto fail; + } + + dbus_message_unref(reply); + dbus_pending_call_unref(call); + return; +fail: + dbus_error_free(&derr); + pending_reply_free(pr); +} + +static int get_default_adapter(struct pending_reply *pr, + DBusPendingCallNotifyFunction cb) +{ + DBusMessage *msg; + DBusPendingCall *pending; + + msg = dbus_message_new_method_call("org.bluez", "/org/bluez", + "org.bluez.Manager", "DefaultAdapter"); + if (!msg) + return -1; + + if (dbus_connection_send_with_reply(pr->conn, msg, &pending, -1) == FALSE) { + error("Can't send D-Bus message."); + return -1; + } + + dbus_pending_call_set_notify(pending, cb, pr, NULL); + dbus_message_unref(msg); + + return 0; +} + static DBusHandlerResult list_servers(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -402,7 +464,6 @@ static DBusHandlerResult create_connection(DBusConnection *conn, struct pending_reply *pr; static int uid = 0; DBusError derr; - char src_addr[18]; const char *addr; const char *str; uint16_t id; @@ -429,11 +490,8 @@ static DBusHandlerResult create_connection(DBusConnection *conn, pr->id = id; pr->path = g_new0(char, 48); snprintf(pr->path, 48, NETWORK_PATH "/connection%d", uid++); - ba2str(&mgr->src, src_addr); - pr->adapter_path = g_new0(char, 32); - snprintf(pr->adapter_path , 32, "/org/bluez/hci%d", hci_devid(src_addr)); - if (get_handles(pr, pan_handle_reply) < 0) { + if (get_default_adapter(pr, default_adapter_reply) < 0) { err_failed(conn, msg, "D-Bus path registration failed"); pending_reply_free(pr); } @@ -524,12 +582,6 @@ static const DBusObjectPathVTable manager_table = { int network_dbus_init(void) { struct manager *mgr; - bdaddr_t src; -#if 0 - int dev_id; -#endif - - dbus_connection_set_exit_on_disconnect(connection, TRUE); mgr = g_new0(struct manager, 1); @@ -542,23 +594,6 @@ int network_dbus_init(void) info("Registered manager path:%s", NETWORK_PATH); - /* Set the default adapter */ - bacpy(&src, BDADDR_ANY); -#if 0 - dev_id = hci_get_route(&src); - if (dev_id < 0) { - error("Bluetooth device not available"); - goto fail; - } - - if (hci_devba(dev_id, &src) < 0) { - error("Can't get local adapter device info"); - goto fail; - } -#endif - - bacpy(&mgr->src, &src); - return 0; fail: -- 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/bridge.c | 17 +++++++++++++++++ network/bridge.h | 1 + network/server.c | 16 ++++++++++++---- 3 files changed, 30 insertions(+), 4 deletions(-) (limited to 'network') diff --git a/network/bridge.c b/network/bridge.c index 76c2a507..a6930194 100644 --- a/network/bridge.c +++ b/network/bridge.c @@ -74,3 +74,20 @@ int bridge_remove(const char *name) return 0; } + +int bridge_add_interface(const char *bridge, const char *dev) +{ + struct ifreq ifr; + int ifindex = if_nametoindex(dev); + + if (ifindex == 0) + return -ENODEV; + + strncpy(ifr.ifr_name, bridge, IFNAMSIZ); + ifr.ifr_ifindex = ifindex; + + if (ioctl(bridge_socket, SIOCBRADDIF, &ifr) < 0) + return -errno; + + return 0; +} diff --git a/network/bridge.h b/network/bridge.h index 45e744d3..2630b892 100644 --- a/network/bridge.h +++ b/network/bridge.h @@ -26,3 +26,4 @@ void bridge_cleanup(void); int bridge_create(const char *name); int bridge_remove(const char *name); +int bridge_add_interface(const char *bridge, const char *dev); 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') 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 e9e95fcbedbb256e0dbcb4f9f79cd5e7db1465fc Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 30 Mar 2007 14:38:32 +0000 Subject: Return an error when server already exist. --- network/manager.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 1accb8a2..33cbd36f 100644 --- a/network/manager.c +++ b/network/manager.c @@ -425,11 +425,9 @@ static DBusHandlerResult create_server(DBusConnection *conn, path = g_new0(char, 32); snprintf(path, 32, NETWORK_PATH "/server/%X", id); - /* Path already registered */ if (g_slist_find_custom(mgr->servers, path, (GCompareFunc) strcmp)) - return create_path(conn, msg, path, NULL); /* Return already exist error */ + return err_already_exists(conn, msg, "Server Already exists"); - /* FIXME: define which type should be used -- string/uuid str/uui128 */ if (server_register(conn, path, id) == -1) { err_failed(conn, msg, "D-Bus path registration failed"); g_free(path); -- cgit From 6accceac927f8a5451a9cab1ef885d5e0b236432 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 30 Mar 2007 17:21:11 +0000 Subject: Add err_already_exists. --- network/error.c | 8 ++++++++ network/error.h | 3 +++ 2 files changed, 11 insertions(+) (limited to 'network') diff --git a/network/error.c b/network/error.c index 684bda2a..f011c496 100644 --- a/network/error.c +++ b/network/error.c @@ -78,3 +78,11 @@ DBusHandlerResult err_not_supported(DBusConnection *conn, DBusMessage *msg) NETWORK_ERROR_INTERFACE ".NotSupported", "The service is not supported by the remote device")); } + +DBusHandlerResult err_already_exists(DBusConnection *conn, + DBusMessage *msg, const char *str) +{ + return send_message_and_unref(conn, + dbus_message_new_error(msg, + NETWORK_ERROR_INTERFACE ".AlreadyExists", str)); +} diff --git a/network/error.h b/network/error.h index 44e7690a..3022e392 100644 --- a/network/error.h +++ b/network/error.h @@ -35,3 +35,6 @@ DBusHandlerResult err_connection_failed(DBusConnection *conn, DBusHandlerResult err_invalid_args(DBusConnection *conn, DBusMessage *msg, const char *str); DBusHandlerResult err_not_supported(DBusConnection *conn, DBusMessage *msg); +DBusHandlerResult err_already_exists(DBusConnection *conn, + DBusMessage *msg, const char *str); + -- 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') 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/manager.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++--------- network/server.c | 80 ++++++++++++++++++++++++++++++++++++++++++++- network/server.h | 4 ++- 3 files changed, 164 insertions(+), 17 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 33cbd36f..ace1f602 100644 --- a/network/manager.c +++ b/network/manager.c @@ -77,7 +77,7 @@ static void pending_reply_free(struct pending_reply *pr) } static DBusHandlerResult create_path(DBusConnection *conn, - DBusMessage *msg, char *path, + DBusMessage *msg, const char *path, const char *sname) { DBusMessage *reply, *signal; @@ -101,7 +101,6 @@ static DBusHandlerResult create_path(DBusConnection *conn, dbus_message_append_args(reply, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID); - g_free(path); return send_message_and_unref(conn, reply); } @@ -221,7 +220,7 @@ static void pan_record_reply(DBusPendingCall *call, void *data) pr->mgr->connections = g_slist_append(pr->mgr->connections, g_strdup(pr->path)); - create_path(pr->conn, pr->msg, g_strdup (pr->path), "ConnectionCreated"); + create_path(pr->conn, pr->msg, pr->path, "ConnectionCreated"); fail: sdp_record_free(rec); dbus_error_free(&derr); @@ -333,6 +332,64 @@ static int get_handles(struct pending_reply *pr, return 0; } +static void get_address_reply(DBusPendingCall *call, void *data) +{ + struct pending_reply *pr = data; + DBusMessage *reply = dbus_pending_call_steal_reply(call); + DBusError derr; + const char *address; + + dbus_error_init(&derr); + if (dbus_set_error_from_message(&derr, reply)) { + error("GetAddress: %s(%s)", derr.name, derr.message); + goto fail; + } + + if (!dbus_message_get_args(reply, &derr, + DBUS_TYPE_STRING, &address, + DBUS_TYPE_INVALID)) { + error("%s: %s", derr.name, derr.message); + goto fail; + } + + if (server_register(pr->conn, address, pr->path, pr->id) < 0) { + err_failed(pr->conn, pr->msg, "D-Bus path registration failed"); + goto fail; + } + + pr->mgr->servers = g_slist_append(pr->mgr->servers, + g_strdup(pr->path)); + + create_path(pr->conn, pr->msg, pr->path, "ServerCreated"); +fail: + dbus_error_free(&derr); + dbus_message_unref(reply); + dbus_pending_call_unref(call); + return; +} + +static int get_address(struct pending_reply *pr, + DBusPendingCallNotifyFunction cb) +{ + DBusMessage *msg; + DBusPendingCall *pending; + + msg = dbus_message_new_method_call("org.bluez", pr->adapter_path, + "org.bluez.Adapter", "GetAddress"); + if (!msg) + return -1; + + if (dbus_connection_send_with_reply(pr->conn, msg, &pending, -1) == FALSE) { + error("Can't send D-Bus message."); + return -1; + } + + dbus_pending_call_set_notify(pending, cb, pr, NULL); + dbus_message_unref(msg); + + return 0; +} + static void default_adapter_reply(DBusPendingCall *call, void *data) { struct pending_reply *pr = data; @@ -357,7 +414,10 @@ static void default_adapter_reply(DBusPendingCall *call, void *data) pr->adapter_path = g_strdup(adapter); - if (get_handles(pr, pan_handle_reply) < 0) { + if (pr->id == BNEP_SVC_PANU && (get_handles(pr, pan_handle_reply) < 0)) { + err_failed(pr->conn, pr->msg, "D-Bus path registration failed"); + goto fail; + } else if (get_address(pr, get_address_reply) < 0) { err_failed(pr->conn, pr->msg, "D-Bus path registration failed"); goto fail; } @@ -404,9 +464,9 @@ static DBusHandlerResult create_server(DBusConnection *conn, DBusMessage *msg, void *data) { struct manager *mgr = data; + struct pending_reply *pr; DBusError derr; const char *str; - char *path; int id; dbus_error_init(&derr); @@ -422,21 +482,28 @@ static DBusHandlerResult create_server(DBusConnection *conn, if ((id != BNEP_SVC_GN) && (id != BNEP_SVC_NAP)) return err_invalid_args(conn, msg, "Not supported"); - path = g_new0(char, 32); - snprintf(path, 32, NETWORK_PATH "/server/%X", id); - - if (g_slist_find_custom(mgr->servers, path, (GCompareFunc) strcmp)) - return err_already_exists(conn, msg, "Server Already exists"); + pr = g_new(struct pending_reply, 1); + pr->conn = conn; + pr->msg = dbus_message_ref(msg); + pr->mgr = mgr; + pr->addr = NULL; + pr->id = id; + pr->path = g_new0(char, 32); + snprintf(pr->path, 32, NETWORK_PATH "/server/%s", bnep_name(id)); - if (server_register(conn, path, id) == -1) { - err_failed(conn, msg, "D-Bus path registration failed"); - g_free(path); + if (g_slist_find_custom(mgr->servers, pr->path, + (GCompareFunc) strcmp)) { + err_already_exists(conn, msg, "Server Already exists"); + pending_reply_free(pr); return DBUS_HANDLER_RESULT_HANDLED; } - mgr->servers = g_slist_append(mgr->servers, g_strdup(path)); + if (get_default_adapter(pr, default_adapter_reply) < 0) { + err_failed(conn, msg, "D-Bus path registration failed"); + pending_reply_free(pr); + } - return create_path(conn, msg, path, "ServerCreated"); + return DBUS_HANDLER_RESULT_HANDLED; } static DBusHandlerResult remove_server(DBusConnection *conn, diff --git a/network/server.c b/network/server.c index 67319107..0c0932ae 100644 --- a/network/server.c +++ b/network/server.c @@ -30,6 +30,8 @@ #include #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; +} diff --git a/network/server.h b/network/server.h index 27b38ba6..7db4ad18 100644 --- a/network/server.h +++ b/network/server.h @@ -21,4 +21,6 @@ * */ -int server_register(DBusConnection *conn, const char *path, uint16_t id); +int server_register(DBusConnection *conn, const char *addr, const char *path, + uint16_t id); +int read_server_uuid(bdaddr_t *src, uint16_t uuid, gboolean *enable); -- cgit From a2ace90c14ede86b8179a930fb104de4aca93849 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 5 Apr 2007 15:00:54 +0000 Subject: Fix bug while disconnecting. --- network/connection.c | 1 - network/manager.c | 8 +++++--- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 03ee754d..610e1e84 100644 --- a/network/connection.c +++ b/network/connection.c @@ -458,7 +458,6 @@ static DBusHandlerResult connection_disconnect(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } - close(nc->sk); bnep_kill_connection(&nc->dst); reply = dbus_message_new_method_return(msg); diff --git a/network/manager.c b/network/manager.c index ace1f602..1cbb9c70 100644 --- a/network/manager.c +++ b/network/manager.c @@ -414,9 +414,11 @@ static void default_adapter_reply(DBusPendingCall *call, void *data) pr->adapter_path = g_strdup(adapter); - if (pr->id == BNEP_SVC_PANU && (get_handles(pr, pan_handle_reply) < 0)) { - err_failed(pr->conn, pr->msg, "D-Bus path registration failed"); - goto fail; + if (pr->addr) { + if (get_handles(pr, pan_handle_reply) < 0) { + err_failed(pr->conn, pr->msg, "D-Bus path registration failed"); + goto fail; + } } else if (get_address(pr, get_address_reply) < 0) { err_failed(pr->conn, pr->msg, "D-Bus path registration failed"); goto fail; -- cgit From 6b9efc12eaf7ae2196bf7b80f3fc33366f97390e Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 5 Apr 2007 18:58:41 +0000 Subject: network: missing pending_reply initialization and connection ref/unref --- network/manager.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 1cbb9c70..408e0ab3 100644 --- a/network/manager.c +++ b/network/manager.c @@ -68,12 +68,14 @@ static void pending_reply_free(struct pending_reply *pr) { if (pr->addr) g_free(pr->addr); - if (pr->path) g_free(pr->path); - if (pr->adapter_path) g_free(pr->adapter_path); + if (pr->msg) + dbus_message_unref(pr->msg); + if (pr->conn) + dbus_connection_unref(pr->conn); } static DBusHandlerResult create_path(DBusConnection *conn, @@ -484,8 +486,8 @@ static DBusHandlerResult create_server(DBusConnection *conn, if ((id != BNEP_SVC_GN) && (id != BNEP_SVC_NAP)) return err_invalid_args(conn, msg, "Not supported"); - pr = g_new(struct pending_reply, 1); - pr->conn = conn; + pr = g_new0(struct pending_reply, 1); + pr->conn = dbus_connection_ref(conn);; pr->msg = dbus_message_ref(msg); pr->mgr = mgr; pr->addr = NULL; @@ -549,8 +551,8 @@ static DBusHandlerResult create_connection(DBusConnection *conn, if ((id != BNEP_SVC_GN) && (id != BNEP_SVC_NAP)) return err_invalid_args(conn, msg, "Not supported"); - pr = g_new(struct pending_reply, 1); - pr->conn = conn; + pr = g_new0(struct pending_reply, 1); + pr->conn = dbus_connection_ref(conn); pr->msg = dbus_message_ref(msg); pr->mgr = mgr; pr->addr = g_strdup(addr); -- 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') 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') 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 9743174631a196c41c50d30af936d62488e9b843 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 12 Apr 2007 12:19:39 +0000 Subject: network: code cleanup --- network/manager.c | 63 ++++++++++++++++++++----------------------------------- 1 file changed, 23 insertions(+), 40 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 408e0ab3..0195c960 100644 --- a/network/manager.c +++ b/network/manager.c @@ -53,13 +53,13 @@ struct manager { }; struct pending_reply { - DBusConnection *conn; - DBusMessage *msg; - struct manager *mgr; - uint16_t id; - char *addr; - char *path; - char *adapter_path; + DBusConnection *conn; + DBusMessage *msg; + struct manager *mgr; + char *addr; + char *path; + char *adapter_path; + uint16_t id; }; static DBusConnection *connection = NULL; @@ -648,37 +648,9 @@ static const DBusObjectPathVTable manager_table = { .unregister_function = manager_unregister, }; -int network_dbus_init(void) -{ - struct manager *mgr; - - mgr = g_new0(struct manager, 1); - - /* Fallback to catch invalid network path */ - if (dbus_connection_register_fallback(connection, NETWORK_PATH, - &manager_table, mgr) == FALSE) { - error("D-Bus failed to register %s path", NETWORK_PATH); - goto fail; - } - - info("Registered manager path:%s", NETWORK_PATH); - - return 0; - -fail: - manager_free(mgr); - - return -1; -} - -void network_dbus_exit(void) -{ - dbus_connection_unregister_object_path(connection, NETWORK_PATH); -} - int network_init(DBusConnection *conn) { - int err; + struct manager *mgr; if (bridge_init() < 0) { error("Can't init bridge module"); @@ -697,16 +669,27 @@ int network_init(DBusConnection *conn) connection = dbus_connection_ref(conn); - err = network_dbus_init(); - if (err < 0) + /* FIXME: make manager global */ + mgr = g_new0(struct manager, 1); + + /* Fallback to catch invalid network path */ + if (dbus_connection_register_fallback(connection, NETWORK_PATH, + &manager_table, mgr) == FALSE) { + error("D-Bus failed to register %s path", NETWORK_PATH); + manager_free(mgr); dbus_connection_unref(connection); - return err; + return -1; + } + + info("Registered manager path:%s", NETWORK_PATH); + + return 0; } void network_exit(void) { - network_dbus_exit(); + dbus_connection_unregister_object_path(connection, NETWORK_PATH); dbus_connection_unref(connection); -- cgit From ed17ae18d87cba8f8564bebde2f0707883b73d58 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 12 Apr 2007 12:49:42 +0000 Subject: Fix bug on GetInterface. --- network/connection.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 610e1e84..341ffae4 100644 --- a/network/connection.c +++ b/network/connection.c @@ -385,6 +385,7 @@ static DBusHandlerResult get_interface(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_conn *nc = data; + const char *pdev = nc->dev; DBusMessage *reply; if (nc->state != CONNECTED) { @@ -396,7 +397,7 @@ static DBusHandlerResult get_interface(DBusConnection *conn, DBusMessage *msg, if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; - dbus_message_append_args(reply, DBUS_TYPE_STRING, &nc->dev, + dbus_message_append_args(reply, DBUS_TYPE_STRING, &pdev, DBUS_TYPE_INVALID); return send_message_and_unref(conn, reply); -- cgit From ed62b516d4db8930b0f768caf462c53bbaecaa4e Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 12 Apr 2007 12:49:55 +0000 Subject: network: use global server/connection list for manager --- network/manager.c | 74 +++++++++++++++++-------------------------------------- 1 file changed, 22 insertions(+), 52 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 0195c960..b2b47aaa 100644 --- a/network/manager.c +++ b/network/manager.c @@ -47,15 +47,12 @@ #include "connection.h" #include "common.h" -struct manager { - GSList *servers; /* Network registered servers paths */ - GSList *connections; /* Network registered connections paths */ -}; +static GSList *server_paths = NULL; /* Network registered servers paths */ +static GSList *connection_paths = NULL; /* Network registered connections paths */ struct pending_reply { DBusConnection *conn; DBusMessage *msg; - struct manager *mgr; char *addr; char *path; char *adapter_path; @@ -219,8 +216,7 @@ static void pan_record_reply(DBusPendingCall *call, void *data) goto fail; } - pr->mgr->connections = g_slist_append(pr->mgr->connections, - g_strdup(pr->path)); + connection_paths = g_slist_append(connection_paths, g_strdup(pr->path)); create_path(pr->conn, pr->msg, pr->path, "ConnectionCreated"); fail: @@ -359,8 +355,7 @@ static void get_address_reply(DBusPendingCall *call, void *data) goto fail; } - pr->mgr->servers = g_slist_append(pr->mgr->servers, - g_strdup(pr->path)); + server_paths = g_slist_append(server_paths, g_strdup(pr->path)); create_path(pr->conn, pr->msg, pr->path, "ServerCreated"); fail: @@ -459,15 +454,12 @@ static int get_default_adapter(struct pending_reply *pr, static DBusHandlerResult list_servers(DBusConnection *conn, DBusMessage *msg, void *data) { - struct manager *mgr = data; - - return list_paths(conn, msg, mgr->servers); + return list_paths(conn, msg, server_paths); } static DBusHandlerResult create_server(DBusConnection *conn, DBusMessage *msg, void *data) { - struct manager *mgr = data; struct pending_reply *pr; DBusError derr; const char *str; @@ -489,13 +481,12 @@ static DBusHandlerResult create_server(DBusConnection *conn, pr = g_new0(struct pending_reply, 1); pr->conn = dbus_connection_ref(conn);; pr->msg = dbus_message_ref(msg); - pr->mgr = mgr; pr->addr = NULL; pr->id = id; pr->path = g_new0(char, 32); snprintf(pr->path, 32, NETWORK_PATH "/server/%s", bnep_name(id)); - if (g_slist_find_custom(mgr->servers, pr->path, + if (g_slist_find_custom(server_paths, pr->path, (GCompareFunc) strcmp)) { err_already_exists(conn, msg, "Server Already exists"); pending_reply_free(pr); @@ -513,23 +504,18 @@ static DBusHandlerResult create_server(DBusConnection *conn, static DBusHandlerResult remove_server(DBusConnection *conn, DBusMessage *msg, void *data) { - struct manager *mgr = data; - - return remove_path(conn, msg, &mgr->servers, "ServerRemoved"); + return remove_path(conn, msg, &server_paths, "ServerRemoved"); } static DBusHandlerResult list_connections(DBusConnection *conn, DBusMessage *msg, void *data) { - struct manager *mgr = data; - - return list_paths(conn, msg, mgr->connections); + return list_paths(conn, msg, connection_paths); } static DBusHandlerResult create_connection(DBusConnection *conn, DBusMessage *msg, void *data) { - struct manager *mgr = data; struct pending_reply *pr; static int uid = 0; DBusError derr; @@ -554,7 +540,6 @@ static DBusHandlerResult create_connection(DBusConnection *conn, pr = g_new0(struct pending_reply, 1); pr->conn = dbus_connection_ref(conn); pr->msg = dbus_message_ref(msg); - pr->mgr = mgr; pr->addr = g_strdup(addr); pr->id = id; pr->path = g_new0(char, 48); @@ -571,9 +556,7 @@ static DBusHandlerResult create_connection(DBusConnection *conn, static DBusHandlerResult remove_connection(DBusConnection *conn, DBusMessage *msg, void *data) { - struct manager *mgr = data; - - return remove_path(conn, msg, &mgr->connections, "ConnectionRemoved"); + return remove_path(conn, msg, &connection_paths, "ConnectionRemoved"); } static DBusHandlerResult manager_message(DBusConnection *conn, @@ -614,34 +597,25 @@ static DBusHandlerResult manager_message(DBusConnection *conn, return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -static void manager_free(struct manager *mgr) +static void manager_unregister(DBusConnection *conn, void *data) { - if (!mgr) - return; + info("Unregistered manager path"); - if (mgr->servers) { - g_slist_foreach(mgr->servers, (GFunc)g_free, NULL); - g_slist_free(mgr->servers); + if (server_paths) { + g_slist_foreach(server_paths, (GFunc)g_free, NULL); + g_slist_free(server_paths); + server_paths = NULL; } - if (mgr->connections) { - g_slist_foreach(mgr->connections, (GFunc)g_free, NULL); - g_slist_free(mgr->connections); + if (connection_paths) { + g_slist_foreach(connection_paths, (GFunc)g_free, NULL); + g_slist_free(connection_paths); + connection_paths = NULL; } - g_free (mgr); bnep_kill_all_connections(); } -static void manager_unregister(DBusConnection *conn, void *data) -{ - struct manager *mgr = data; - - info("Unregistered manager path"); - - manager_free(mgr); -} - /* Virtual table to handle manager object path hierarchy */ static const DBusObjectPathVTable manager_table = { .message_function = manager_message, @@ -650,8 +624,6 @@ static const DBusObjectPathVTable manager_table = { int network_init(DBusConnection *conn) { - struct manager *mgr; - if (bridge_init() < 0) { error("Can't init bridge module"); return -1; @@ -669,14 +641,10 @@ int network_init(DBusConnection *conn) connection = dbus_connection_ref(conn); - /* FIXME: make manager global */ - mgr = g_new0(struct manager, 1); - /* Fallback to catch invalid network path */ if (dbus_connection_register_fallback(connection, NETWORK_PATH, - &manager_table, mgr) == FALSE) { + &manager_table, NULL) == FALSE) { error("D-Bus failed to register %s path", NETWORK_PATH); - manager_free(mgr); dbus_connection_unref(connection); return -1; @@ -684,6 +652,8 @@ int network_init(DBusConnection *conn) info("Registered manager path:%s", NETWORK_PATH); + /* FIXME: Missing register stored servers */ + return 0; } -- cgit From b47f37f54576c39dc863c14cdc7a623fc13a729f Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 12 Apr 2007 13:33:23 +0000 Subject: network: added initial code to register stored servers --- network/manager.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 59 insertions(+), 6 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index b2b47aaa..491b3845 100644 --- a/network/manager.c +++ b/network/manager.c @@ -25,6 +25,9 @@ #include #endif +#include +#include + #include #include #include @@ -34,8 +37,9 @@ #include -#include "logging.h" #include "dbus.h" +#include "logging.h" +#include "textfile.h" #define NETWORK_PATH "/org/bluez/network" #define NETWORK_MANAGER_INTERFACE "org.bluez.network.Manager" @@ -47,6 +51,8 @@ #include "connection.h" #include "common.h" +#define MAX_PATH_LENGTH 64 /* D-Bus path */ + static GSList *server_paths = NULL; /* Network registered servers paths */ static GSList *connection_paths = NULL; /* Network registered connections paths */ @@ -483,8 +489,8 @@ static DBusHandlerResult create_server(DBusConnection *conn, pr->msg = dbus_message_ref(msg); pr->addr = NULL; pr->id = id; - pr->path = g_new0(char, 32); - snprintf(pr->path, 32, NETWORK_PATH "/server/%s", bnep_name(id)); + pr->path = g_new0(char, MAX_PATH_LENGTH); + snprintf(pr->path, MAX_PATH_LENGTH, NETWORK_PATH "/server/%s", bnep_name(id)); if (g_slist_find_custom(server_paths, pr->path, (GCompareFunc) strcmp)) { @@ -542,8 +548,8 @@ static DBusHandlerResult create_connection(DBusConnection *conn, pr->msg = dbus_message_ref(msg); pr->addr = g_strdup(addr); pr->id = id; - pr->path = g_new0(char, 48); - snprintf(pr->path, 48, NETWORK_PATH "/connection%d", uid++); + pr->path = g_new0(char, MAX_PATH_LENGTH); + snprintf(pr->path, MAX_PATH_LENGTH, NETWORK_PATH "/connection%d", uid++); if (get_default_adapter(pr, default_adapter_reply) < 0) { err_failed(conn, msg, "D-Bus path registration failed"); @@ -622,6 +628,53 @@ static const DBusObjectPathVTable manager_table = { .unregister_function = manager_unregister, }; +static void stored_server(char *key, char *value, void *data) +{ + char path[MAX_PATH_LENGTH]; + char addr[18]; + const bdaddr_t *src = data; + uint16_t id; + + /* FIXME: we need change the path to support multiple sources */ + + ba2str(src, addr); + id = bnep_service_id(key); + snprintf(path, MAX_PATH_LENGTH, "%s/server/%s", NETWORK_PATH, bnep_name(id)); + + if (server_register(connection, addr, path, id) < 0) + error("Register (%s, %s) path failed", addr, path); +} + +static void register_stored_servers(void) +{ + char dirname[PATH_MAX + 1]; + char filename[PATH_MAX + 1]; + struct dirent *de; + DIR *dir; + bdaddr_t src; + + snprintf(dirname, PATH_MAX, "%s", STORAGEDIR); + + dir = opendir(dirname); + if (!dir) + return; + + while ((de = readdir(dir)) != NULL) { + if (!isdigit(de->d_name[0])) + continue; + + create_name(filename, PATH_MAX, STORAGEDIR, + de->d_name, "network"); + + str2ba(de->d_name, &src); + + textfile_foreach(filename, stored_server, &src); + } + + closedir(dir); +} + + int network_init(DBusConnection *conn) { if (bridge_init() < 0) { @@ -652,7 +705,7 @@ int network_init(DBusConnection *conn) info("Registered manager path:%s", NETWORK_PATH); - /* FIXME: Missing register stored servers */ + register_stored_servers(); return 0; } -- cgit From 1cbec5ebe8d67b1b4dcef1768efde2ac1ac51970 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 12 Apr 2007 18:15:13 +0000 Subject: Add FindConnection method, bug fixes for disconnect events. --- network/connection.c | 38 ++++++++++++++++++++++++++++++++------ network/connection.h | 6 ++++-- network/manager.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 8 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 341ffae4..278fa1cc 100644 --- a/network/connection.c +++ b/network/connection.c @@ -82,12 +82,16 @@ static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond, struct network_conn *nc = data; DBusMessage *signal; - signal = dbus_message_new_signal(nc->path, - NETWORK_CONNECTION_INTERFACE, "Disconnected"); + if (nc->conn != NULL) { + signal = dbus_message_new_signal(nc->path, + NETWORK_CONNECTION_INTERFACE, "Disconnected"); - send_message_and_unref(nc->conn, signal); + send_message_and_unref(nc->conn, signal); + } info("%s disconnected", nc->dev); nc->state = DISCONNECTED; + memset(nc->dev, 0, 16); + strncpy(nc->dev, netdev, 16); g_io_channel_close(chan); g_io_channel_unref(chan); return FALSE; @@ -535,9 +539,6 @@ static void connection_free(struct network_conn *nc) if (nc->state == CONNECTED) bnep_kill_connection(&nc->dst); - if (nc->dev) - g_free(nc->dev); - if (nc->name) g_free(nc->name); @@ -545,6 +546,7 @@ static void connection_free(struct network_conn *nc) g_free(nc->desc); g_free(nc); + nc = NULL; } static void connection_unregister(DBusConnection *conn, void *data) @@ -612,3 +614,27 @@ fail: connection_free(nc); return -1; } + +int +connection_find_data(DBusConnection *conn, const char *path, + const char *pattern) +{ + struct network_conn *nc; + char addr[18]; + + if (!dbus_connection_get_object_path_data(conn, path, &nc)) + return -1; + + if (strcmp(pattern, nc->dev) == 0) + return 0; + + if (strcmp(pattern, nc->name) == 0) + return 0; + + ba2str(&nc->dst, addr); + + if (strcmp(pattern, addr) == 0) + return 0; + + return -1; +} diff --git a/network/connection.h b/network/connection.h index 08f36e1c..27bf2f69 100644 --- a/network/connection.h +++ b/network/connection.h @@ -22,5 +22,7 @@ */ int connection_register(DBusConnection *conn, const char *path, - const char *addr, uint16_t id, - const sdp_record_t *rec); + const char *addr, uint16_t id, + const sdp_record_t *rec); +int connection_find_data(DBusConnection *conn, const char *path, + const char *pattern); diff --git a/network/manager.c b/network/manager.c index 491b3845..d2b627db 100644 --- a/network/manager.c +++ b/network/manager.c @@ -519,6 +519,45 @@ static DBusHandlerResult list_connections(DBusConnection *conn, return list_paths(conn, msg, connection_paths); } +static DBusHandlerResult find_connection(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + DBusError derr; + const char *pattern; + const char *path; + GSList *list; + DBusMessage *reply; + + dbus_error_init(&derr); + if (!dbus_message_get_args(msg, &derr, + DBUS_TYPE_STRING, &pattern, + DBUS_TYPE_INVALID)) { + err_invalid_args(conn, msg, derr.message); + dbus_error_free(&derr); + return DBUS_HANDLER_RESULT_HANDLED; + } + + for (list = connection_paths; list; list = list->next) { + path = (const char *) list->data; + if (connection_find_data(conn, path, pattern) == 0) + break; + } + + if (list == NULL) { + err_failed(conn, msg, "No such connection"); + return DBUS_HANDLER_RESULT_HANDLED; + } + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_message_append_args(reply, DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); + + return send_message_and_unref(conn, reply); +} + static DBusHandlerResult create_connection(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -594,6 +633,9 @@ static DBusHandlerResult manager_message(DBusConnection *conn, if (strcmp(member, "ListConnections") == 0) return list_connections(conn, msg, data); + if (strcmp(member, "FindConnection") == 0) + return find_connection(conn, msg, data); + if (strcmp(member, "CreateConnection") == 0) return create_connection(conn, msg, data); -- 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/main.c | 2 ++ network/manager.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++--------- network/manager.h | 3 +++ network/server.c | 73 +++---------------------------------------------------- 4 files changed, 70 insertions(+), 81 deletions(-) (limited to 'network') diff --git a/network/main.c b/network/main.c index 74675184..2d9d44b6 100644 --- a/network/main.c +++ b/network/main.c @@ -33,6 +33,8 @@ #include #include +#include + #include "dbus.h" #include "logging.h" diff --git a/network/manager.c b/network/manager.c index d2b627db..c09cbc8b 100644 --- a/network/manager.c +++ b/network/manager.c @@ -28,6 +28,8 @@ #include #include +#include + #include #include #include @@ -53,9 +55,6 @@ #define MAX_PATH_LENGTH 64 /* D-Bus path */ -static GSList *server_paths = NULL; /* Network registered servers paths */ -static GSList *connection_paths = NULL; /* Network registered connections paths */ - struct pending_reply { DBusConnection *conn; DBusMessage *msg; @@ -65,8 +64,13 @@ struct pending_reply { uint16_t id; }; +static GSList *server_paths = NULL; /* Network registered servers paths */ +static GSList *connection_paths = NULL; /* Network registered connections paths */ + static DBusConnection *connection = NULL; +static int net_uid = 0; /* Network objects identifier */ + static void pending_reply_free(struct pending_reply *pr) { if (pr->addr) @@ -342,6 +346,7 @@ static void get_address_reply(DBusPendingCall *call, void *data) DBusMessage *reply = dbus_pending_call_steal_reply(call); DBusError derr; const char *address; + bdaddr_t src; dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { @@ -361,6 +366,9 @@ static void get_address_reply(DBusPendingCall *call, void *data) goto fail; } + str2ba(address, &src); + network_store_info(&src, pr->id, FALSE); + server_paths = g_slist_append(server_paths, g_strdup(pr->path)); create_path(pr->conn, pr->msg, pr->path, "ServerCreated"); @@ -490,7 +498,8 @@ static DBusHandlerResult create_server(DBusConnection *conn, pr->addr = NULL; pr->id = id; pr->path = g_new0(char, MAX_PATH_LENGTH); - snprintf(pr->path, MAX_PATH_LENGTH, NETWORK_PATH "/server/%s", bnep_name(id)); + snprintf(pr->path, MAX_PATH_LENGTH, NETWORK_PATH"/server/%s%d", + bnep_name(id), net_uid++); if (g_slist_find_custom(server_paths, pr->path, (GCompareFunc) strcmp)) { @@ -510,6 +519,7 @@ static DBusHandlerResult create_server(DBusConnection *conn, static DBusHandlerResult remove_server(DBusConnection *conn, DBusMessage *msg, void *data) { + /* FIXME: Remove from the storage */ return remove_path(conn, msg, &server_paths, "ServerRemoved"); } @@ -562,7 +572,6 @@ static DBusHandlerResult create_connection(DBusConnection *conn, DBusMessage *msg, void *data) { struct pending_reply *pr; - static int uid = 0; DBusError derr; const char *addr; const char *str; @@ -588,7 +597,8 @@ static DBusHandlerResult create_connection(DBusConnection *conn, pr->addr = g_strdup(addr); pr->id = id; pr->path = g_new0(char, MAX_PATH_LENGTH); - snprintf(pr->path, MAX_PATH_LENGTH, NETWORK_PATH "/connection%d", uid++); + snprintf(pr->path, MAX_PATH_LENGTH, + NETWORK_PATH"/connection%d", net_uid++); if (get_default_adapter(pr, default_adapter_reply) < 0) { err_failed(conn, msg, "D-Bus path registration failed"); @@ -601,6 +611,7 @@ static DBusHandlerResult create_connection(DBusConnection *conn, static DBusHandlerResult remove_connection(DBusConnection *conn, DBusMessage *msg, void *data) { + /* FIXME: Remove from the storage */ return remove_path(conn, msg, &connection_paths, "ConnectionRemoved"); } @@ -677,14 +688,12 @@ static void stored_server(char *key, char *value, void *data) const bdaddr_t *src = data; uint16_t id; - /* FIXME: we need change the path to support multiple sources */ - ba2str(src, addr); id = bnep_service_id(key); - snprintf(path, MAX_PATH_LENGTH, "%s/server/%s", NETWORK_PATH, bnep_name(id)); + snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/server/%s%d", + bnep_name(id), net_uid++); - if (server_register(connection, addr, path, id) < 0) - error("Register (%s, %s) path failed", addr, path); + server_register(connection, addr, path, id); } static void register_stored_servers(void) @@ -766,3 +775,45 @@ void network_exit(void) bnep_cleanup(); bridge_cleanup(); } + +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); +} + +int network_del_stored_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; +} + +int network_store_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; +} diff --git a/network/manager.h b/network/manager.h index d37ca3cd..d20b8dbd 100644 --- a/network/manager.h +++ b/network/manager.h @@ -23,3 +23,6 @@ int network_init(DBusConnection *conn); void network_exit(void); + +int network_del_stored_info(bdaddr_t *src, uint16_t uuid); +int network_store_info(bdaddr_t *src, uint16_t uuid, gboolean enable); 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 6e42f0eaa8f2ee001ddfc8a1b8498ad1abdc20dd Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 12 Apr 2007 18:48:18 +0000 Subject: Fix warning on build. --- network/connection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 278fa1cc..59aa3762 100644 --- a/network/connection.c +++ b/network/connection.c @@ -622,7 +622,7 @@ connection_find_data(DBusConnection *conn, const char *path, struct network_conn *nc; char addr[18]; - if (!dbus_connection_get_object_path_data(conn, path, &nc)) + if (!dbus_connection_get_object_path_data(conn, path, (void *)&nc)) return -1; if (strcmp(pattern, nc->dev) == 0) -- cgit From 1a02bbc361299198257ca32969d2d804ee9fb74c Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 12 Apr 2007 18:54:40 +0000 Subject: Fix code style. --- network/connection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 59aa3762..0e9311c4 100644 --- a/network/connection.c +++ b/network/connection.c @@ -622,7 +622,7 @@ connection_find_data(DBusConnection *conn, const char *path, struct network_conn *nc; char addr[18]; - if (!dbus_connection_get_object_path_data(conn, path, (void *)&nc)) + if (!dbus_connection_get_object_path_data(conn, path, (void *) &nc)) return -1; if (strcmp(pattern, nc->dev) == 0) -- cgit From 1556df2283e8480f3b96e9159940e606c4e2fe43 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 13 Apr 2007 13:11:51 +0000 Subject: network: code cleanup --- network/connection.c | 46 ++++++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 24 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 0e9311c4..e4f759aa 100644 --- a/network/connection.c +++ b/network/connection.c @@ -31,6 +31,8 @@ #include #include +#include + #include #include #include @@ -39,15 +41,13 @@ #include -#include - #include "logging.h" #include "dbus.h" #include "error.h" #include "common.h" +#include "connection.h" #define NETWORK_CONNECTION_INTERFACE "org.bluez.network.Connection" -#include "connection.h" typedef enum { CONNECTED, @@ -56,17 +56,17 @@ typedef enum { } conn_state; struct network_conn { - DBusConnection *conn; - DBusMessage *msg; - bdaddr_t src; - bdaddr_t dst; - char *path; /* D-Bus path */ - char dev[16]; /* BNEP interface name */ - char *name; - char *desc; - uint16_t id; /* Service Class Identifier */ - conn_state state; - int sk; + DBusConnection *conn; + DBusMessage *msg; + bdaddr_t src; + bdaddr_t dst; + char *path; /* D-Bus path */ + char dev[16]; /* BNEP interface name */ + char *name; + char *desc; + uint16_t id; /* Service Class Identifier */ + conn_state state; + int sk; }; struct __service_16 { @@ -579,7 +579,9 @@ int connection_register(DBusConnection *conn, const char *path, if (!dbus_connection_register_object_path(conn, path, &connection_table, nc)) { error("D-Bus failed to register %s path", path); - goto fail; + + connection_free(nc); + return -1; } nc->path = g_strdup(path); @@ -610,14 +612,10 @@ int connection_register(DBusConnection *conn, const char *path, nc->conn = conn; info("Registered connection path:%s", path); return 0; -fail: - connection_free(nc); - return -1; } -int -connection_find_data(DBusConnection *conn, const char *path, - const char *pattern) +int connection_find_data(DBusConnection *conn, + const char *path, const char *pattern) { struct network_conn *nc; char addr[18]; @@ -625,15 +623,15 @@ connection_find_data(DBusConnection *conn, const char *path, if (!dbus_connection_get_object_path_data(conn, path, (void *) &nc)) return -1; - if (strcmp(pattern, nc->dev) == 0) + if (strcasecmp(pattern, nc->dev) == 0) return 0; - if (strcmp(pattern, nc->name) == 0) + if (strcasecmp(pattern, nc->name) == 0) return 0; ba2str(&nc->dst, addr); - if (strcmp(pattern, addr) == 0) + if (strcasecmp(pattern, addr) == 0) return 0; return -1; -- cgit From bf2e27fac1f9c0af68eaa91e00375d8f8907ebc4 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 13 Apr 2007 13:14:02 +0000 Subject: network: initial skeleton to register stored network NAP/GN/PANU --- network/manager.c | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index c09cbc8b..2b7d21e8 100644 --- a/network/manager.c +++ b/network/manager.c @@ -681,22 +681,25 @@ static const DBusObjectPathVTable manager_table = { .unregister_function = manager_unregister, }; -static void stored_server(char *key, char *value, void *data) +static void register_stored_nap(const bdaddr_t *src, const char *filename) { - char path[MAX_PATH_LENGTH]; - char addr[18]; - const bdaddr_t *src = data; - uint16_t id; + /* FIXME: extract name, description, secure, enabled, address range, routing ...*/ +} + +static void register_stored_gn(const bdaddr_t *src, const char *filename) +{ + /* FIXME: extract name, description, secure, enabled, address range ...*/ +} - ba2str(src, addr); - id = bnep_service_id(key); - snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/server/%s%d", - bnep_name(id), net_uid++); +static void register_stored_connection(char *key, char *value, void *data) +{ + + /* Format: XX:XX:XX:XX:XX:XX#{NAP, GN} name:description */ - server_register(connection, addr, path, id); + info("connection - key:%s value:%s", key, value); } -static void register_stored_servers(void) +static void register_stored(void) { char dirname[PATH_MAX + 1]; char filename[PATH_MAX + 1]; @@ -714,18 +717,27 @@ static void register_stored_servers(void) if (!isdigit(de->d_name[0])) continue; + /* Connection objects */ create_name(filename, PATH_MAX, STORAGEDIR, de->d_name, "network"); str2ba(de->d_name, &src); + textfile_foreach(filename, register_stored_connection, &src); + + /* NAP objects */ + create_name(filename, PATH_MAX, STORAGEDIR, + de->d_name, "nap"); + register_stored_nap(&src, filename); - textfile_foreach(filename, stored_server, &src); + /* GN objects */ + create_name(filename, PATH_MAX, STORAGEDIR, + de->d_name, "gn"); + register_stored_gn(&src, filename); } closedir(dir); } - int network_init(DBusConnection *conn) { if (bridge_init() < 0) { @@ -756,7 +768,7 @@ int network_init(DBusConnection *conn) info("Registered manager path:%s", NETWORK_PATH); - register_stored_servers(); + register_stored(); return 0; } -- cgit From 54cc7aee9e7d723697ecb807871a65ce9af309a0 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 13 Apr 2007 15:09:31 +0000 Subject: network: added code to parse the network file --- network/manager.c | 71 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 14 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 2b7d21e8..93f0821d 100644 --- a/network/manager.c +++ b/network/manager.c @@ -681,22 +681,65 @@ static const DBusObjectPathVTable manager_table = { .unregister_function = manager_unregister, }; -static void register_stored_nap(const bdaddr_t *src, const char *filename) +static void parse_stored_connection(char *key, char *value, void *data) { - /* FIXME: extract name, description, secure, enabled, address range, routing ...*/ -} + bdaddr_t dst; + char path[MAX_PATH_LENGTH]; + char addr[18]; + const char *ptr; + char *name; + int len, id; -static void register_stored_gn(const bdaddr_t *src, const char *filename) -{ - /* FIXME: extract name, description, secure, enabled, address range ...*/ -} + /* Format: XX:XX:XX:XX:XX:XX#{NAP, GN} name:description */ -static void register_stored_connection(char *key, char *value, void *data) -{ + /* Parsing the key: address#role */ + ptr = strchr(key, '#'); - /* Format: XX:XX:XX:XX:XX:XX#{NAP, GN} name:description */ + /* Empty address or invalid len */ + if (!ptr || ((ptr - key) != 17)) + return; + + memset(addr, 0, 18); + strncpy(addr, key, 17); + str2ba(addr, &dst); + + /* Empty role */ + if (++ptr == NULL) + return; + + if (strcasecmp("nap", ptr) == 0) { + id = BNEP_SVC_NAP; + snprintf(path, MAX_PATH_LENGTH, + NETWORK_PATH"/server/nap%d", net_uid++); + } else if (strcasecmp("gn", ptr) == 0) { + id = BNEP_SVC_GN; + snprintf(path, MAX_PATH_LENGTH, + NETWORK_PATH"/server/gn%d", net_uid++); + } else { + /* Invalid role */ + return; + } + + /* Parsing the value: name and description */ + ptr = strchr(value, ':'); + + /* Empty name */ + if (!ptr) + return; + + len = ptr-value; + name = g_malloc0(len + 1); + strncpy(name, value, len); + + /* Empty description */ + if (++ptr == NULL) { + g_free(name); + return; + } + + /* FIXME: Change the connection_register prototype */ - info("connection - key:%s value:%s", key, value); + g_free(name); } static void register_stored(void) @@ -722,17 +765,17 @@ static void register_stored(void) de->d_name, "network"); str2ba(de->d_name, &src); - textfile_foreach(filename, register_stored_connection, &src); + textfile_foreach(filename, parse_stored_connection, &src); /* NAP objects */ create_name(filename, PATH_MAX, STORAGEDIR, de->d_name, "nap"); - register_stored_nap(&src, filename); + register_nap_from_file(&src, filename); /* GN objects */ create_name(filename, PATH_MAX, STORAGEDIR, de->d_name, "gn"); - register_stored_gn(&src, filename); + register_gn_from_file(&src, filename); } closedir(dir); -- 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 ++++++++++++ network/server.h | 6 ++++-- 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'network') 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; +} diff --git a/network/server.h b/network/server.h index 7db4ad18..23ebe772 100644 --- a/network/server.h +++ b/network/server.h @@ -21,6 +21,8 @@ * */ -int server_register(DBusConnection *conn, const char *addr, const char *path, - uint16_t id); +int server_register(DBusConnection *conn, const char *addr, + const char *path, uint16_t id); +int register_nap_from_file(const bdaddr_t *src, const char *filename); +int register_gn_from_file(const bdaddr_t *src, const char *filename); int read_server_uuid(bdaddr_t *src, uint16_t uuid, gboolean *enable); -- cgit From 4706fa6e70ea2e19c7892ade0323a35d4f0b5a47 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 13 Apr 2007 18:51:51 +0000 Subject: network: changed connection_register prototype --- network/connection.c | 37 ++++++++----------------------------- network/connection.h | 5 ++--- network/manager.c | 48 ++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 50 insertions(+), 40 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index e4f759aa..c7f22f4b 100644 --- a/network/connection.c +++ b/network/connection.c @@ -28,16 +28,12 @@ #include #include #include -#include -#include #include #include #include #include -#include -#include #include @@ -564,11 +560,10 @@ static const DBusObjectPathVTable connection_table = { .unregister_function = connection_unregister, }; -int connection_register(DBusConnection *conn, const char *path, - const char *addr, uint16_t id, const sdp_record_t *rec) +int connection_register(DBusConnection *conn, const char *path, bdaddr_t *src, + bdaddr_t *dst, uint16_t id, const char *name, const char *desc) { struct network_conn *nc; - sdp_data_t *d; if (!conn) return -1; @@ -578,39 +573,23 @@ int connection_register(DBusConnection *conn, const char *path, /* register path */ if (!dbus_connection_register_object_path(conn, path, &connection_table, nc)) { - error("D-Bus failed to register %s path", path); - connection_free(nc); return -1; } nc->path = g_strdup(path); - bacpy(&nc->src, BDADDR_ANY); - str2ba(addr, &nc->dst); + bacpy(&nc->src, src); + bacpy(&nc->dst, dst); nc->id = id; - - /* Extract service name from record */ - d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY); - if (d) { - nc->name = g_new0(char, d->unitSize); - snprintf(nc->name, d->unitSize, "%.*s", d->unitSize, - d->val.str); - } - - /* Extract service description from record */ - d = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY); - if (d) { - nc->desc = g_new0(char, d->unitSize); - snprintf(nc->desc, d->unitSize, "%.*s", d->unitSize, - d->val.str); - } - + nc->name = g_strdup(name); + nc->desc = g_strdup(desc); memset(nc->dev, 0, 16); strncpy(nc->dev, netdev, 16); - nc->state = DISCONNECTED; nc->conn = conn; + info("Registered connection path:%s", path); + return 0; } diff --git a/network/connection.h b/network/connection.h index 27bf2f69..1f810060 100644 --- a/network/connection.h +++ b/network/connection.h @@ -21,8 +21,7 @@ * */ -int connection_register(DBusConnection *conn, const char *path, - const char *addr, uint16_t id, - const sdp_record_t *rec); +int connection_register(DBusConnection *conn, const char *path, bdaddr_t *src, + bdaddr_t *dst, uint16_t id, const char *name, const char *desc); int connection_find_data(DBusConnection *conn, const char *path, const char *pattern); diff --git a/network/manager.c b/network/manager.c index 93f0821d..43bc9b71 100644 --- a/network/manager.c +++ b/network/manager.c @@ -58,10 +58,11 @@ struct pending_reply { DBusConnection *conn; DBusMessage *msg; - char *addr; - char *path; - char *adapter_path; - uint16_t id; + bdaddr_t src; /* Source Address */ + char *addr; /* Destination Address*/ + char *path; /* D-Bus object path */ + char *adapter_path; /* Default adapter path */ + uint16_t id; /* Role */ }; static GSList *server_paths = NULL; /* Network registered servers paths */ @@ -187,9 +188,12 @@ static void pan_record_reply(DBusPendingCall *call, void *data) struct pending_reply *pr = data; DBusMessage *reply = dbus_pending_call_steal_reply(call); DBusError derr; + bdaddr_t src, dst; int len, scanned; uint8_t *rec_bin; + sdp_data_t *d; sdp_record_t *rec = NULL; + char *name = NULL, *desc = NULL; dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { @@ -220,8 +224,28 @@ static void pan_record_reply(DBusPendingCall *call, void *data) rec = sdp_extract_pdu(rec_bin, &scanned); - if (connection_register(pr->conn, pr->path, pr->addr, pr->id, - rec) == -1) { + /* Extract service name from record */ + d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY); + if (d) { + name = g_new0(char, d->unitSize); + snprintf(name, d->unitSize, "%.*s", + d->unitSize, d->val.str); + } + + /* Extract service description from record */ + d = sdp_data_get(rec, SDP_ATTR_SVCDESC_PRIMARY); + if (d) { + desc = g_new0(char, d->unitSize); + snprintf(desc, d->unitSize, "%.*s", + d->unitSize, d->val.str); + } + + /* FIXME: it can' t be hard coded */ + bacpy(&src, BDADDR_ANY); + str2ba(pr->addr, &dst); + + if (connection_register(pr->conn, pr->path, &src, + &dst, pr->id, name, desc) < 0) { err_failed(pr->conn, pr->msg, "D-Bus path registration failed"); goto fail; } @@ -230,6 +254,12 @@ static void pan_record_reply(DBusPendingCall *call, void *data) create_path(pr->conn, pr->msg, pr->path, "ConnectionCreated"); fail: + + if (name) + g_free(name); + if (desc) + g_free(desc); + sdp_record_free(rec); dbus_error_free(&derr); pending_reply_free(pr); @@ -508,6 +538,7 @@ static DBusHandlerResult create_server(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } + /* FIXME: use hci_get_route */ if (get_default_adapter(pr, default_adapter_reply) < 0) { err_failed(conn, msg, "D-Bus path registration failed"); pending_reply_free(pr); @@ -600,6 +631,7 @@ static DBusHandlerResult create_connection(DBusConnection *conn, snprintf(pr->path, MAX_PATH_LENGTH, NETWORK_PATH"/connection%d", net_uid++); + /* FIXME: use hci_get_route */ if (get_default_adapter(pr, default_adapter_reply) < 0) { err_failed(conn, msg, "D-Bus path registration failed"); pending_reply_free(pr); @@ -683,7 +715,7 @@ static const DBusObjectPathVTable manager_table = { static void parse_stored_connection(char *key, char *value, void *data) { - bdaddr_t dst; + bdaddr_t dst, *src = data; char path[MAX_PATH_LENGTH]; char addr[18]; const char *ptr; @@ -737,7 +769,7 @@ static void parse_stored_connection(char *key, char *value, void *data) return; } - /* FIXME: Change the connection_register prototype */ + connection_register(connection, path, src, &dst, id, name, ptr); g_free(name); } -- 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/manager.c | 41 +++++++++++++++++++++++++---------------- network/server.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- network/server.h | 6 ++++-- 3 files changed, 71 insertions(+), 21 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 43bc9b71..15209592 100644 --- a/network/manager.c +++ b/network/manager.c @@ -739,18 +739,15 @@ static void parse_stored_connection(char *key, char *value, void *data) if (++ptr == NULL) return; - if (strcasecmp("nap", ptr) == 0) { + if (strcasecmp("nap", ptr) == 0) id = BNEP_SVC_NAP; - snprintf(path, MAX_PATH_LENGTH, - NETWORK_PATH"/server/nap%d", net_uid++); - } else if (strcasecmp("gn", ptr) == 0) { + else if (strcasecmp("gn", ptr) == 0) id = BNEP_SVC_GN; - snprintf(path, MAX_PATH_LENGTH, - NETWORK_PATH"/server/gn%d", net_uid++); - } else { - /* Invalid role */ + else return; - } + + snprintf(path, MAX_PATH_LENGTH, + NETWORK_PATH"/connection%d", net_uid++); /* Parsing the value: name and description */ ptr = strchr(value, ':'); @@ -778,8 +775,10 @@ static void register_stored(void) { char dirname[PATH_MAX + 1]; char filename[PATH_MAX + 1]; + char path[MAX_PATH_LENGTH]; struct dirent *de; DIR *dir; + struct stat s; bdaddr_t src; snprintf(dirname, PATH_MAX, "%s", STORAGEDIR); @@ -797,17 +796,27 @@ static void register_stored(void) de->d_name, "network"); str2ba(de->d_name, &src); - textfile_foreach(filename, parse_stored_connection, &src); + + + if (stat (filename, &s) == 0 && (s.st_mode & __S_IFREG)) + textfile_foreach(filename, parse_stored_connection, &src); /* NAP objects */ - create_name(filename, PATH_MAX, STORAGEDIR, - de->d_name, "nap"); - register_nap_from_file(&src, filename); + create_name(filename, PATH_MAX, STORAGEDIR, de->d_name, "nap"); + + if (stat (filename, &s) == 0 && (s.st_mode & __S_IFREG)) { + snprintf(path, MAX_PATH_LENGTH, + NETWORK_PATH"/server/nap%d", net_uid++); + register_nap_from_file(connection, path, &src, filename); + } /* GN objects */ - create_name(filename, PATH_MAX, STORAGEDIR, - de->d_name, "gn"); - register_gn_from_file(&src, filename); + create_name(filename, PATH_MAX, STORAGEDIR, de->d_name, "gn"); + if (stat (filename, &s) == 0 && (s.st_mode & __S_IFREG)) { + snprintf(path, MAX_PATH_LENGTH, + NETWORK_PATH"/server/gn%d", net_uid++); + register_gn_from_file(connection, path, &src, filename); + } } closedir(dir); 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; diff --git a/network/server.h b/network/server.h index 23ebe772..d96873b3 100644 --- a/network/server.h +++ b/network/server.h @@ -23,6 +23,8 @@ int server_register(DBusConnection *conn, const char *addr, const char *path, uint16_t id); -int register_nap_from_file(const bdaddr_t *src, const char *filename); -int register_gn_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); +int register_gn_from_file(DBusConnection *conn, const char *path, + const bdaddr_t *src, const char *filename); int read_server_uuid(bdaddr_t *src, uint16_t uuid, gboolean *enable); -- 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/manager.c | 7 ++++--- network/server.c | 18 +++++++----------- network/server.h | 6 ++---- 3 files changed, 13 insertions(+), 18 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 15209592..450fd872 100644 --- a/network/manager.c +++ b/network/manager.c @@ -803,11 +803,11 @@ static void register_stored(void) /* NAP objects */ create_name(filename, PATH_MAX, STORAGEDIR, de->d_name, "nap"); - if (stat (filename, &s) == 0 && (s.st_mode & __S_IFREG)) { snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/server/nap%d", net_uid++); - register_nap_from_file(connection, path, &src, filename); + server_register_from_file(connection, path, + &src, BNEP_SVC_NAP, filename); } /* GN objects */ @@ -815,7 +815,8 @@ static void register_stored(void) if (stat (filename, &s) == 0 && (s.st_mode & __S_IFREG)) { snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/server/gn%d", net_uid++); - register_gn_from_file(connection, path, &src, filename); + server_register_from_file(connection, path, + &src, BNEP_SVC_GN, filename); } } 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; } diff --git a/network/server.h b/network/server.h index d96873b3..c4dd51e6 100644 --- a/network/server.h +++ b/network/server.h @@ -23,8 +23,6 @@ int server_register(DBusConnection *conn, const char *addr, const char *path, uint16_t id); -int register_nap_from_file(DBusConnection *conn, const char *path, - const bdaddr_t *src, const char *filename); -int register_gn_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); int read_server_uuid(bdaddr_t *src, uint16_t uuid, gboolean *enable); -- 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/manager.c | 4 ++-- network/server.c | 28 +++++++++++++--------------- network/server.h | 4 ++-- 3 files changed, 17 insertions(+), 19 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 450fd872..b2ca7fe7 100644 --- a/network/manager.c +++ b/network/manager.c @@ -391,12 +391,12 @@ static void get_address_reply(DBusPendingCall *call, void *data) goto fail; } - if (server_register(pr->conn, address, pr->path, pr->id) < 0) { + str2ba(address, &src); + if (server_register(pr->conn, pr->path, &src, pr->id) < 0) { err_failed(pr->conn, pr->msg, "D-Bus path registration failed"); goto fail; } - str2ba(address, &src); network_store_info(&src, pr->id, FALSE); server_paths = g_slist_append(server_paths, g_strdup(pr->path)); 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); diff --git a/network/server.h b/network/server.h index c4dd51e6..613b628d 100644 --- a/network/server.h +++ b/network/server.h @@ -21,8 +21,8 @@ * */ -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); int server_register_from_file(DBusConnection *conn, const char *path, const bdaddr_t *src, uint16_t id, const char *filename); int read_server_uuid(bdaddr_t *src, uint16_t uuid, gboolean *enable); -- cgit From 476855d7cdf0fc2259f1aab3946b9719e567a808 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 13 Apr 2007 21:18:19 +0000 Subject: network: removed not defined function(read_server_uuid) --- network/server.h | 1 - 1 file changed, 1 deletion(-) (limited to 'network') diff --git a/network/server.h b/network/server.h index 613b628d..92d82f2f 100644 --- a/network/server.h +++ b/network/server.h @@ -25,4 +25,3 @@ int server_register(DBusConnection *conn, const char *path, bdaddr_t *src, uint16_t id); int server_register_from_file(DBusConnection *conn, const char *path, const bdaddr_t *src, uint16_t id, const char *filename); -int read_server_uuid(bdaddr_t *src, uint16_t uuid, gboolean *enable); -- 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') 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 373808d7a4932c4b5a2616e09f0d8e7d45ccabbe Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 13 Apr 2007 21:38:36 +0000 Subject: network: cleanup and added some FIXME tags --- network/manager.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index b2ca7fe7..ed793592 100644 --- a/network/manager.c +++ b/network/manager.c @@ -887,30 +887,28 @@ int network_del_stored_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); + /* FIXME: Wrong format */ - err = textfile_del(filename, str); + str = bnep_uuid(uuid); - return err; + return textfile_del(filename, str); } int network_store_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"); + /* FIXME: Wrong format */ + 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; + return textfile_put(filename, str, enable ? "1" : "0"); } -- 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') 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') 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/manager.c | 2 +- network/server.c | 28 ++++++++++++++++++++++++++++ network/server.h | 2 ++ 3 files changed, 31 insertions(+), 1 deletion(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index ed793592..86dc26dc 100644 --- a/network/manager.c +++ b/network/manager.c @@ -397,7 +397,7 @@ static void get_address_reply(DBusPendingCall *call, void *data) goto fail; } - network_store_info(&src, pr->id, FALSE); + server_store(pr->conn, pr->path); server_paths = g_slist_append(server_paths, g_strdup(pr->path)); 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; +} diff --git a/network/server.h b/network/server.h index 92d82f2f..e762da9d 100644 --- a/network/server.h +++ b/network/server.h @@ -25,3 +25,5 @@ int server_register(DBusConnection *conn, const char *path, bdaddr_t *src, uint16_t id); int server_register_from_file(DBusConnection *conn, const char *path, const bdaddr_t *src, uint16_t id, const char *filename); + +int server_store(DBusConnection *conn, const char *path); -- cgit From e5ba646776ba7c5c5c9c9d630bbfc8793f1c3b4e Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Sat, 14 Apr 2007 01:12:34 +0000 Subject: network: added connection_store --- network/connection.c | 39 ++++++++++++++++++++++++++++++++++++++- network/connection.h | 1 + network/manager.c | 1 + 3 files changed, 40 insertions(+), 1 deletion(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index c7f22f4b..0bd255d2 100644 --- a/network/connection.c +++ b/network/connection.c @@ -39,6 +39,8 @@ #include "logging.h" #include "dbus.h" +#include "textfile.h" + #include "error.h" #include "common.h" #include "connection.h" @@ -60,7 +62,7 @@ struct network_conn { char dev[16]; /* BNEP interface name */ char *name; char *desc; - uint16_t id; /* Service Class Identifier */ + uint16_t id; /* Role: Service Class Identifier */ conn_state state; int sk; }; @@ -593,6 +595,41 @@ int connection_register(DBusConnection *conn, const char *path, bdaddr_t *src, return 0; } +int connection_store(DBusConnection *conn, const char *path) +{ + struct network_conn *nc; + const char *role; + char key[32], *value; + char filename[PATH_MAX + 1]; + char src_addr[18], dst_addr[18]; + int len, err; + + if (!dbus_connection_get_object_path_data(conn, path, (void *) &nc)) + return -ENOENT; + + if (!nc->name || !nc->desc) + return -EINVAL; + + /* FIXME: name and desc validation - remove ':' */ + + ba2str(&nc->dst, dst_addr); + role = bnep_name(nc->id); + snprintf(key, 32, "%s#%s", dst_addr, role); + + len = strlen(nc->name) + strlen(nc->desc) + 2; + value = g_malloc0(len); + snprintf(value, len, "%s:%s", nc->name, nc->desc); + + ba2str(&nc->src, src_addr); + create_name(filename, PATH_MAX, STORAGEDIR, src_addr, "network"); + + err = textfile_put(filename, key, value); + + g_free(value); + + return err; +} + int connection_find_data(DBusConnection *conn, const char *path, const char *pattern) { diff --git a/network/connection.h b/network/connection.h index 1f810060..b03c3caa 100644 --- a/network/connection.h +++ b/network/connection.h @@ -23,5 +23,6 @@ int connection_register(DBusConnection *conn, const char *path, bdaddr_t *src, bdaddr_t *dst, uint16_t id, const char *name, const char *desc); +int connection_store(DBusConnection *conn, const char *path); int connection_find_data(DBusConnection *conn, const char *path, const char *pattern); diff --git a/network/manager.c b/network/manager.c index 86dc26dc..c546ed0c 100644 --- a/network/manager.c +++ b/network/manager.c @@ -250,6 +250,7 @@ static void pan_record_reply(DBusPendingCall *call, void *data) goto fail; } + connection_store(pr->conn, pr->path); connection_paths = g_slist_append(connection_paths, g_strdup(pr->path)); create_path(pr->conn, pr->msg, pr->path, "ConnectionCreated"); -- 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/manager.c | 4 ++-- network/server.c | 18 ++++++++++++++++++ network/server.h | 1 + 3 files changed, 21 insertions(+), 2 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index c546ed0c..f41d395e 100644 --- a/network/manager.c +++ b/network/manager.c @@ -168,6 +168,8 @@ static DBusHandlerResult remove_path(DBusConnection *conn, if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; + /* Remove the nap or gn file from the file system */ + server_remove_stored(conn, path); if (!dbus_connection_unregister_object_path(conn, path)) error("Network path unregister failed"); @@ -551,7 +553,6 @@ static DBusHandlerResult create_server(DBusConnection *conn, static DBusHandlerResult remove_server(DBusConnection *conn, DBusMessage *msg, void *data) { - /* FIXME: Remove from the storage */ return remove_path(conn, msg, &server_paths, "ServerRemoved"); } @@ -644,7 +645,6 @@ static DBusHandlerResult create_connection(DBusConnection *conn, static DBusHandlerResult remove_connection(DBusConnection *conn, DBusMessage *msg, void *data) { - /* FIXME: Remove from the storage */ return remove_path(conn, msg, &connection_paths, "ConnectionRemoved"); } 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); +} diff --git a/network/server.h b/network/server.h index e762da9d..30016f3e 100644 --- a/network/server.h +++ b/network/server.h @@ -27,3 +27,4 @@ int server_register_from_file(DBusConnection *conn, const char *path, const bdaddr_t *src, uint16_t id, const char *filename); int server_store(DBusConnection *conn, const char *path); +int server_remove_stored(DBusConnection *conn, const char *path); -- cgit From 3723149c0baab5f94d57221fa693e4d0ec19df6b Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 16 Apr 2007 13:26:16 +0000 Subject: network: missing append registered server paths to the list --- network/manager.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index f41d395e..78d69150 100644 --- a/network/manager.c +++ b/network/manager.c @@ -807,8 +807,11 @@ static void register_stored(void) if (stat (filename, &s) == 0 && (s.st_mode & __S_IFREG)) { snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/server/nap%d", net_uid++); - server_register_from_file(connection, path, - &src, BNEP_SVC_NAP, filename); + + if (server_register_from_file(connection, path, + &src, BNEP_SVC_NAP, filename) == 0) + server_paths = g_slist_append(server_paths, + g_strdup(path)); } /* GN objects */ @@ -816,8 +819,11 @@ static void register_stored(void) if (stat (filename, &s) == 0 && (s.st_mode & __S_IFREG)) { snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/server/gn%d", net_uid++); - server_register_from_file(connection, path, - &src, BNEP_SVC_GN, filename); + + if (server_register_from_file(connection, path, + &src, BNEP_SVC_GN, filename) == 0) + server_paths = g_slist_append(server_paths, + g_strdup(path)); } } -- 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/manager.c | 30 ------------------------------ network/server.c | 19 +++++++++++++++++-- 2 files changed, 17 insertions(+), 32 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 78d69150..16123002 100644 --- a/network/manager.c +++ b/network/manager.c @@ -889,33 +889,3 @@ static inline int create_filename(char *buf, size_t size, return create_name(buf, size, STORAGEDIR, addr, name); } - -int network_del_stored_info(bdaddr_t *src, uint16_t uuid) -{ - char filename[PATH_MAX + 1]; - const char *str; - - create_filename(filename, PATH_MAX, src, "network"); - - /* FIXME: Wrong format */ - - str = bnep_uuid(uuid); - - return textfile_del(filename, str); -} - -int network_store_info(bdaddr_t *src, uint16_t uuid, gboolean enable) -{ - char filename[PATH_MAX + 1]; - const char *str; - - create_filename(filename, PATH_MAX, src, "network"); - - /* FIXME: Wrong format */ - - str = bnep_uuid(uuid); - - create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - - return textfile_put(filename, str, enable ? "1" : "0"); -} 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') 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 ea69da4ac5a927fde86de78ceaac6deadfedbff6 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 16 Apr 2007 14:03:38 +0000 Subject: Update network service documentation. --- network/network-api.txt | 85 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 73 insertions(+), 12 deletions(-) (limited to 'network') diff --git a/network/network-api.txt b/network/network-api.txt index c38b3e63..4edebffd 100644 --- a/network/network-api.txt +++ b/network/network-api.txt @@ -14,12 +14,16 @@ Methods string CreateServer(string uuid) Creates a network server object(GN or NAP). - Possible errors: TBD + Possible errors:org.bluez.network.AlreadyExists + org.bluez.network.NotSupported + org.bluez.network.ConnectionAttemptFailed + org.bluez.network.Failed void RemoveServer(string path) Removes the network server object for given path. - Possible errors: TBD + Possible errors:org.bluez.network.DoesNotExist + org.bluez.network.Failed array{string} ListServers() @@ -30,16 +34,29 @@ Methods string CreateServer(string uuid) Creates a network connection object(NAP or GN). + Possible errors:org.bluez.network.AlreadyExists + org.bluez.network.NotSupported + org.bluez.network.ConnectionAttemptFailed + org.bluez.network.Failed + string RemoveConnection(string path) Removes a network connection object for a given path. - Possible errors: TBD + Possible errors:org.bluez.network.DoesNotExist + org.bluez.network.Failed array{string} ListConnections() Returns an array of available network connections paths. + string FindConnection(string pattern) + + Returns an array of available network connections paths. + + Possible errors:org.bluez.network.DoesNotExist + org.bluez.network.Failed + Signals void ServerCreated(string path) @@ -57,31 +74,52 @@ Interface org.bluez.network.Server Object path /org/bluez/network/server* Methods string GetUUID() + Returns the uuid 128 string representation of the server. - void Enable() // do this automatically? - void Disable() // do this automatically? + void Enable() + + Enable server and updates service record. + + Possible errors:org.bluez.network.AlreadyExists + org.bluez.network.Failed + + void Disable() + + Disable server and remove service record. + + Possible errors:org.bluez.network.Failed + void SetName(string name) Sets the name attribute. string GetName() + Returns the service name. void SetAddressRange(string start, string end) + TBD void SetRouting(string interface) + TBD void SetSecurity(bool enable) - TBD + + Enable or disable encryption. bool GetSecurity() - TBD + + Returns server encryption. Signals + void Enabled() + + void Disabled() + Network Connection hierarchy (experimental) =========================================== @@ -89,28 +127,51 @@ Interface org.bluez.network.Connection Object path /org/bluez/network/connection* Methods string GetAddress() + Returns the Bluetooth address of the ending point. string GetUUID() + Returns the uuid 128 string representation of the connected service. string GetName() - TBD + + Returns the string representation of connected host. + + Possible errors:org.bluez.network.Failed string GetDescription() - TBD + + Returns the string description of connected host. + + Possible errors:org.bluez.network.Failed string GetInterface() - TBD + + Returns the string network interface. + + Possible errors:org.bluez.network.Failed void Connect() - TBD + + Connects to host. + + Possible errors:org.bluez.network.ConnectionAttemptFailed + org.bluez.network.Failed void Disconnect() - TBD + + Disconnects to host. + + Possible errors:org.bluez.network.Failed bool IsConnected() + Returns the connection status. Signals + + void Connected() + + void Disconnected() -- 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') 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/manager.c | 199 ++++++++++++------------------------------------------ network/server.c | 16 +++++ 2 files changed, 60 insertions(+), 155 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 16123002..88dc21e5 100644 --- a/network/manager.c +++ b/network/manager.c @@ -27,6 +27,7 @@ #include #include +#include #include @@ -58,8 +59,9 @@ struct pending_reply { DBusConnection *conn; DBusMessage *msg; - bdaddr_t src; /* Source Address */ - char *addr; /* Destination Address*/ + bdaddr_t src; /* Source address */ + bdaddr_t dst; /* Destination address */ + char *addr; /* Destination address */ char *path; /* D-Bus object path */ char *adapter_path; /* Default adapter path */ uint16_t id; /* Role */ @@ -74,6 +76,7 @@ static int net_uid = 0; /* Network objects identifier */ static void pending_reply_free(struct pending_reply *pr) { + if (pr->addr) g_free(pr->addr); if (pr->path) @@ -190,7 +193,6 @@ static void pan_record_reply(DBusPendingCall *call, void *data) struct pending_reply *pr = data; DBusMessage *reply = dbus_pending_call_steal_reply(call); DBusError derr; - bdaddr_t src, dst; int len, scanned; uint8_t *rec_bin; sdp_data_t *d; @@ -242,12 +244,8 @@ static void pan_record_reply(DBusPendingCall *call, void *data) d->unitSize, d->val.str); } - /* FIXME: it can' t be hard coded */ - bacpy(&src, BDADDR_ANY); - str2ba(pr->addr, &dst); - - if (connection_register(pr->conn, pr->path, &src, - &dst, pr->id, name, desc) < 0) { + if (connection_register(pr->conn, pr->path, &pr->src, + &pr->dst, pr->id, name, desc) < 0) { err_failed(pr->conn, pr->msg, "D-Bus path registration failed"); goto fail; } @@ -373,131 +371,6 @@ static int get_handles(struct pending_reply *pr, return 0; } -static void get_address_reply(DBusPendingCall *call, void *data) -{ - struct pending_reply *pr = data; - DBusMessage *reply = dbus_pending_call_steal_reply(call); - DBusError derr; - const char *address; - bdaddr_t src; - - dbus_error_init(&derr); - if (dbus_set_error_from_message(&derr, reply)) { - error("GetAddress: %s(%s)", derr.name, derr.message); - goto fail; - } - - if (!dbus_message_get_args(reply, &derr, - DBUS_TYPE_STRING, &address, - DBUS_TYPE_INVALID)) { - error("%s: %s", derr.name, derr.message); - goto fail; - } - - str2ba(address, &src); - if (server_register(pr->conn, pr->path, &src, pr->id) < 0) { - err_failed(pr->conn, pr->msg, "D-Bus path registration failed"); - goto fail; - } - - server_store(pr->conn, pr->path); - - server_paths = g_slist_append(server_paths, g_strdup(pr->path)); - - create_path(pr->conn, pr->msg, pr->path, "ServerCreated"); -fail: - dbus_error_free(&derr); - dbus_message_unref(reply); - dbus_pending_call_unref(call); - return; -} - -static int get_address(struct pending_reply *pr, - DBusPendingCallNotifyFunction cb) -{ - DBusMessage *msg; - DBusPendingCall *pending; - - msg = dbus_message_new_method_call("org.bluez", pr->adapter_path, - "org.bluez.Adapter", "GetAddress"); - if (!msg) - return -1; - - if (dbus_connection_send_with_reply(pr->conn, msg, &pending, -1) == FALSE) { - error("Can't send D-Bus message."); - return -1; - } - - dbus_pending_call_set_notify(pending, cb, pr, NULL); - dbus_message_unref(msg); - - return 0; -} - -static void default_adapter_reply(DBusPendingCall *call, void *data) -{ - struct pending_reply *pr = data; - DBusMessage *reply = dbus_pending_call_steal_reply(call); - DBusError derr; - const char *adapter; - - dbus_error_init(&derr); - if (dbus_set_error_from_message(&derr, reply)) { - err_connection_failed(pr->conn, pr->msg, derr.message); - error("DefaultAdapter: %s(%s)", derr.name, derr.message); - goto fail; - } - - if (!dbus_message_get_args(reply, &derr, - DBUS_TYPE_STRING, &adapter, - DBUS_TYPE_INVALID)) { - err_connection_failed(pr->conn, pr->msg, derr.message); - error("%s: %s", derr.name, derr.message); - goto fail; - } - - pr->adapter_path = g_strdup(adapter); - - if (pr->addr) { - if (get_handles(pr, pan_handle_reply) < 0) { - err_failed(pr->conn, pr->msg, "D-Bus path registration failed"); - goto fail; - } - } else if (get_address(pr, get_address_reply) < 0) { - err_failed(pr->conn, pr->msg, "D-Bus path registration failed"); - goto fail; - } - - dbus_message_unref(reply); - dbus_pending_call_unref(call); - return; -fail: - dbus_error_free(&derr); - pending_reply_free(pr); -} - -static int get_default_adapter(struct pending_reply *pr, - DBusPendingCallNotifyFunction cb) -{ - DBusMessage *msg; - DBusPendingCall *pending; - - msg = dbus_message_new_method_call("org.bluez", "/org/bluez", - "org.bluez.Manager", "DefaultAdapter"); - if (!msg) - return -1; - - if (dbus_connection_send_with_reply(pr->conn, msg, &pending, -1) == FALSE) { - error("Can't send D-Bus message."); - return -1; - } - - dbus_pending_call_set_notify(pending, cb, pr, NULL); - dbus_message_unref(msg); - - return 0; -} - static DBusHandlerResult list_servers(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -507,10 +380,12 @@ static DBusHandlerResult list_servers(DBusConnection *conn, DBusMessage *msg, static DBusHandlerResult create_server(DBusConnection *conn, DBusMessage *msg, void *data) { - struct pending_reply *pr; + char path[MAX_PATH_LENGTH]; DBusError derr; const char *str; - int id; + bdaddr_t src; + uint16_t id; + int dev_id; dbus_error_init(&derr); if (!dbus_message_get_args(msg, &derr, @@ -525,27 +400,32 @@ static DBusHandlerResult create_server(DBusConnection *conn, if ((id != BNEP_SVC_GN) && (id != BNEP_SVC_NAP)) return err_invalid_args(conn, msg, "Not supported"); - pr = g_new0(struct pending_reply, 1); - pr->conn = dbus_connection_ref(conn);; - pr->msg = dbus_message_ref(msg); - pr->addr = NULL; - pr->id = id; - pr->path = g_new0(char, MAX_PATH_LENGTH); - snprintf(pr->path, MAX_PATH_LENGTH, NETWORK_PATH"/server/%s%d", + snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/server/%s%d", bnep_name(id), net_uid++); - if (g_slist_find_custom(server_paths, pr->path, + if (g_slist_find_custom(server_paths, path, (GCompareFunc) strcmp)) { err_already_exists(conn, msg, "Server Already exists"); - pending_reply_free(pr); return DBUS_HANDLER_RESULT_HANDLED; } - /* FIXME: use hci_get_route */ - if (get_default_adapter(pr, default_adapter_reply) < 0) { - err_failed(conn, msg, "D-Bus path registration failed"); - pending_reply_free(pr); - } + bacpy(&src, BDADDR_ANY); + + dev_id = hci_get_route(NULL); + + if (dev_id >= 0) + hci_devba(dev_id, &src); + + if (server_register(conn, path, &src, id) < 0) + return err_failed(conn, msg, + "D-Bus path registration failed"); + + if (bacmp(&src, BDADDR_ANY) != 0) + server_store(conn, path); + + server_paths = g_slist_append(server_paths, g_strdup(path)); + + create_path(conn, msg, path, "ServerCreated"); return DBUS_HANDLER_RESULT_HANDLED; } @@ -608,7 +488,9 @@ static DBusHandlerResult create_connection(DBusConnection *conn, DBusError derr; const char *addr; const char *str; + bdaddr_t src; uint16_t id; + int dev_id; dbus_error_init(&derr); if (!dbus_message_get_args(msg, &derr, @@ -624,20 +506,27 @@ static DBusHandlerResult create_connection(DBusConnection *conn, if ((id != BNEP_SVC_GN) && (id != BNEP_SVC_NAP)) return err_invalid_args(conn, msg, "Not supported"); + bacpy(&src, BDADDR_ANY); + dev_id = hci_get_route(NULL); + if ((dev_id < 0) || (hci_devba(dev_id, &src) < 0)) + return err_failed(conn, msg, "Adapter not available"); + pr = g_new0(struct pending_reply, 1); pr->conn = dbus_connection_ref(conn); pr->msg = dbus_message_ref(msg); + bacpy(&pr->src, &src); + str2ba(addr, &pr->dst); pr->addr = g_strdup(addr); pr->id = id; pr->path = g_new0(char, MAX_PATH_LENGTH); snprintf(pr->path, MAX_PATH_LENGTH, NETWORK_PATH"/connection%d", net_uid++); - /* FIXME: use hci_get_route */ - if (get_default_adapter(pr, default_adapter_reply) < 0) { - err_failed(conn, msg, "D-Bus path registration failed"); - pending_reply_free(pr); - } + pr->adapter_path = g_malloc0(16); + snprintf(pr->adapter_path, 16, "/org/bluez/hci%d", dev_id); + + if (get_handles(pr, pan_handle_reply) < 0) + return err_not_supported(conn, msg); return DBUS_HANDLER_RESULT_HANDLED; } 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 d3d1ce6e2bc9ecbfb70b5d306e419750ba0936b6 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 16 Apr 2007 19:41:59 +0000 Subject: network: missing append registered connection paths to the list --- network/manager.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 88dc21e5..95699d39 100644 --- a/network/manager.c +++ b/network/manager.c @@ -656,7 +656,11 @@ static void parse_stored_connection(char *key, char *value, void *data) return; } - connection_register(connection, path, src, &dst, id, name, ptr); + if (connection_register(connection, path, src, + &dst, id, name, ptr) == 0) { + connection_paths = g_slist_append(connection_paths, + g_strdup(path)); + } g_free(name); } -- 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/common.c | 33 ++++++++++++++++++++++++++++++--- network/common.h | 1 + network/connection.c | 7 ++++++- network/server.c | 13 +++---------- 4 files changed, 40 insertions(+), 14 deletions(-) (limited to 'network') diff --git a/network/common.c b/network/common.c index d9f60374..0a11d306 100644 --- a/network/common.c +++ b/network/common.c @@ -30,6 +30,9 @@ #include #include #include +#include +#include +#include #include #include @@ -139,13 +142,13 @@ int bnep_kill_all_connections(void) { struct bnep_connlist_req req; struct bnep_conninfo ci[7]; - int i; + int i, err; memset(&req, 0, sizeof(req)); req.cnum = 7; req.ci = ci; if (ioctl(ctl, BNEPGETCONNLIST, &req)) { - int err = errno; + err = errno; error("Failed to get connection list: %s (%d)", strerror(err), err); return -err; @@ -168,12 +171,36 @@ int bnep_connadd(int sk, uint16_t role, char *dev) req.device[15] = '\0'; req.sock = sk; req.role = role; - if (ioctl(ctl, BNEPCONNADD, &req)) { + if (ioctl(ctl, BNEPCONNADD, &req) < 0) { int err = errno; error("Failed to add device %s: %s(%d)", dev, strerror(err), err); return -err; } + strncpy(dev, req.device, 16); return 0; } + +int bnep_if_up(const char *devname, int up) +{ + int sd, err; + struct ifreq ifr; + + sd = socket(AF_INET6, SOCK_DGRAM, 0); + strcpy(ifr.ifr_name, devname); + + if (up) + ifr.ifr_flags |= IFF_UP; + else + 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); + return -err; + } + + return 0; +} diff --git a/network/common.h b/network/common.h index b3941e4f..bfbe83d2 100644 --- a/network/common.h +++ b/network/common.h @@ -32,3 +32,4 @@ int bnep_kill_connection(bdaddr_t *dst); int bnep_kill_all_connections(void); int bnep_connadd(int sk, uint16_t role, char *dev); +int bnep_if_up(const char *devname, int up); diff --git a/network/connection.c b/network/connection.c index 0bd255d2..50f60023 100644 --- a/network/connection.c +++ b/network/connection.c @@ -155,6 +155,8 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, goto failed; } + bnep_if_up(nc->dev, TRUE); + signal = dbus_message_new_signal(nc->path, NETWORK_CONNECTION_INTERFACE, "Connected"); @@ -461,6 +463,7 @@ static DBusHandlerResult connection_disconnect(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } + bnep_if_up(nc->dev, FALSE); bnep_kill_connection(&nc->dst); reply = dbus_message_new_method_return(msg); @@ -534,8 +537,10 @@ static void connection_free(struct network_conn *nc) if (nc->path) g_free(nc->path); - if (nc->state == CONNECTED) + if (nc->state == CONNECTED) { + bnep_if_up(nc->dev, FALSE); bnep_kill_connection(&nc->dst); + } if (nc->name) g_free(nc->name); 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 f14786d7146e71d34c72057595eeb90ff7feee01 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 17 Apr 2007 13:48:24 +0000 Subject: Add GetInfo() to network.Connection interface. --- network/connection.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 50f60023..0f4f1c51 100644 --- a/network/connection.c +++ b/network/connection.c @@ -39,6 +39,7 @@ #include "logging.h" #include "dbus.h" +#include "dbus-helper.h" #include "textfile.h" #include "error.h" @@ -491,6 +492,38 @@ static DBusHandlerResult is_connected(DBusConnection *conn, DBusMessage *msg, return send_message_and_unref(conn, reply); } +static DBusHandlerResult get_info(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + struct network_conn *nc = 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, &nc->name); + + uuid = bnep_uuid(nc->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 connection_message(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -526,6 +559,9 @@ static DBusHandlerResult connection_message(DBusConnection *conn, if (strcmp(member, "IsConnected") == 0) return is_connected(conn, msg, data); + if (strcmp(member, "GetInfo") == 0) + return get_info(conn, msg, data); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } -- cgit From cd7716fd58c5578f43634ddbb9e78ec508be2d21 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 17 Apr 2007 13:58:00 +0000 Subject: Update API documentation to include GetInfo. --- network/network-api.txt | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'network') diff --git a/network/network-api.txt b/network/network-api.txt index 4edebffd..17f24f8d 100644 --- a/network/network-api.txt +++ b/network/network-api.txt @@ -170,6 +170,10 @@ Methods string GetAddress() Returns the connection status. + dict GetInfo() + + Returns the connection properties. + Signals void Connected() -- 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') 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 54f74d381a5839455f734f08b285468987530a81 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 18 Apr 2007 13:54:53 +0000 Subject: Fix use of GIOChannel --- network/connection.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 0f4f1c51..c31c423a 100644 --- a/network/connection.c +++ b/network/connection.c @@ -92,7 +92,6 @@ static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond, memset(nc->dev, 0, 16); strncpy(nc->dev, netdev, 16); g_io_channel_close(chan); - g_io_channel_unref(chan); return FALSE; } @@ -178,7 +177,6 @@ failed: nc->state = DISCONNECTED; err_connection_failed(nc->conn, nc->msg, "bnep failed"); g_io_channel_close(chan); - g_io_channel_unref(chan); return FALSE; } @@ -188,6 +186,7 @@ static int bnep_connect(struct network_conn *nc) struct __service_16 *s; unsigned char pkt[BNEP_MTU]; GIOChannel *io; + int err = 0; /* Send request */ req = (void *) pkt; @@ -200,14 +199,18 @@ static int bnep_connect(struct network_conn *nc) io = g_io_channel_unix_new(nc->sk); g_io_channel_set_close_on_unref(io, FALSE); - if (send(nc->sk, pkt, sizeof(*req) + sizeof(*s), 0) != -1) { - g_io_add_watch(io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, - (GIOFunc) bnep_connect_cb, nc); - return 0; + + if (send(nc->sk, pkt, sizeof(*req) + sizeof(*s), 0) < 0) { + err = -errno; + goto out; } + g_io_add_watch(io, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL, + (GIOFunc) bnep_connect_cb, nc); + +out: g_io_channel_unref(io); - return -1; + return err; } static gboolean l2cap_connect_cb(GIOChannel *chan, @@ -217,7 +220,10 @@ static gboolean l2cap_connect_cb(GIOChannel *chan, socklen_t len; int sk, ret; - if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) + if (cond & G_IO_NVAL) + return FALSE; + + if (cond & (G_IO_ERR | G_IO_HUP)) goto failed; sk = g_io_channel_unix_get_fd(chan); @@ -238,13 +244,11 @@ static gboolean l2cap_connect_cb(GIOChannel *chan, goto failed; } - g_io_channel_unref(chan); return FALSE; failed: nc->state = DISCONNECTED; err_connection_failed(nc->conn, nc->msg, strerror(errno)); g_io_channel_close(chan); - g_io_channel_unref(chan); return FALSE; } @@ -270,9 +274,9 @@ static int l2cap_connect(struct network_conn *nc) l2a.l2_family = AF_BLUETOOTH; bacpy(&l2a.l2_bdaddr, &nc->src); - if (bind(nc->sk, (struct sockaddr *) &l2a, sizeof(l2a))) { + if (bind(nc->sk, (struct sockaddr *) &l2a, sizeof(l2a)) < 0) { error("Bind failed. %s(%d)", strerror(errno), errno); - return -1; + return -errno; } memset(&l2a, 0, sizeof(l2a)); @@ -282,7 +286,7 @@ static int l2cap_connect(struct network_conn *nc) if (set_nonblocking(nc->sk) < 0) { error("Set non blocking: %s (%d)", strerror(errno), errno); - return -1; + return -errno; } io = g_io_channel_unix_new(nc->sk); @@ -294,7 +298,7 @@ static int l2cap_connect(struct network_conn *nc) errno); g_io_channel_close(io); g_io_channel_unref(io); - return -1; + return -errno; } g_io_add_watch(io, G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL, (GIOFunc) l2cap_connect_cb, nc); @@ -303,6 +307,7 @@ static int l2cap_connect(struct network_conn *nc) l2cap_connect_cb(io, G_IO_OUT, nc); } + g_io_channel_unref(io); return 0; } -- cgit From f8c373978d73cd848240744acce657861f5a13f2 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 18 Apr 2007 18:10:41 +0000 Subject: Update network.server documentation. --- network/network-api.txt | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'network') diff --git a/network/network-api.txt b/network/network-api.txt index 17f24f8d..d155370e 100644 --- a/network/network-api.txt +++ b/network/network-api.txt @@ -114,6 +114,11 @@ Methods string GetUUID() Returns server encryption. + dict GetInfo() + + Returns the server properties. + + Signals void Enabled() -- cgit From cc8d980b559908480979eac0f4d33957fce70727 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 19 Apr 2007 17:48:23 +0000 Subject: Unref pending calls. --- network/manager.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 95699d39..898a183b 100644 --- a/network/manager.c +++ b/network/manager.c @@ -291,6 +291,7 @@ static int get_record(struct pending_reply *pr, uint32_t handle, dbus_pending_call_set_notify(pending, cb, pr, NULL); dbus_message_unref(msg); + dbus_pending_call_unref(pending); return 0; } @@ -367,6 +368,7 @@ static int get_handles(struct pending_reply *pr, dbus_pending_call_set_notify(pending, cb, pr, NULL); dbus_message_unref(msg); + dbus_pending_call_unref(pending); return 0; } -- cgit From 36d0506a28a2413467d2c5e793d53c45b2183d34 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 20 Apr 2007 15:41:32 +0000 Subject: Check connection busy before removing it. --- network/connection.c | 11 +++++++++++ network/connection.h | 1 + network/manager.c | 3 +++ 3 files changed, 15 insertions(+) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index c31c423a..e3b85929 100644 --- a/network/connection.c +++ b/network/connection.c @@ -698,3 +698,14 @@ int connection_find_data(DBusConnection *conn, return -1; } + +gboolean connection_has_pending(DBusConnection *conn, const char *path) +{ + struct network_conn *nc; + + if (!dbus_connection_get_object_path_data(conn, path, (void *) &nc)) + return FALSE; + + return (nc->state == CONNECTING); +} + diff --git a/network/connection.h b/network/connection.h index b03c3caa..205e44da 100644 --- a/network/connection.h +++ b/network/connection.h @@ -26,3 +26,4 @@ int connection_register(DBusConnection *conn, const char *path, bdaddr_t *src, int connection_store(DBusConnection *conn, const char *path); int connection_find_data(DBusConnection *conn, const char *path, const char *pattern); +gboolean connection_has_pending(DBusConnection *conn, const char *path); diff --git a/network/manager.c b/network/manager.c index 898a183b..65d8634b 100644 --- a/network/manager.c +++ b/network/manager.c @@ -164,6 +164,9 @@ static DBusHandlerResult remove_path(DBusConnection *conn, if (!l) return err_does_not_exist(conn, msg, "Path doesn't exist"); + if (*list == connection_paths && connection_has_pending (conn, path)) + return err_failed(conn, msg, "Connection is Busy"); + g_free(l->data); *list = g_slist_remove(*list, l->data); -- 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') 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 506d39ae95996e9d32e875ae3fa19311168f1249 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 25 Apr 2007 12:36:12 +0000 Subject: Use service name in error namespace. --- network/error.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network') diff --git a/network/error.c b/network/error.c index f011c496..8fcccd32 100644 --- a/network/error.c +++ b/network/error.c @@ -27,7 +27,7 @@ #include "error.h" -#define NETWORK_ERROR_INTERFACE "org.bluez.Error" +#define NETWORK_ERROR_INTERFACE "org.bluez.network.Error" DBusHandlerResult err_unknown_connection(DBusConnection *conn, DBusMessage *msg) -- cgit From 748b15f0a5eb6c1078a4dff64604f042c48a7a4a Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 25 Apr 2007 18:04:47 +0000 Subject: Fix bug while creating connection, unref pending call just once. --- network/manager.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 65d8634b..6f7a5257 100644 --- a/network/manager.c +++ b/network/manager.c @@ -268,7 +268,6 @@ fail: dbus_error_free(&derr); pending_reply_free(pr); dbus_message_unref(reply); - dbus_pending_call_unref(call); } static int get_record(struct pending_reply *pr, uint32_t handle, @@ -339,7 +338,6 @@ static void pan_handle_reply(DBusPendingCall *call, void *data) } dbus_message_unref(reply); - dbus_pending_call_unref(call); return; fail: dbus_error_free(&derr); -- 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') 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 999a1b2c1ff51119806d16430adbc5d7677ac4c4 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 27 Apr 2007 14:17:18 +0000 Subject: Update network API documentation. --- network/connection.c | 4 ++++ network/network-api.txt | 50 ++++++++++++++++++++++++------------------------- 2 files changed, 29 insertions(+), 25 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index e3b85929..2bbd3e60 100644 --- a/network/connection.c +++ b/network/connection.c @@ -104,6 +104,7 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, gsize r; int sk; DBusMessage *reply, *signal; + const char *pdev; if (cond & G_IO_NVAL) return FALSE; @@ -164,6 +165,9 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, reply = dbus_message_new_method_return(nc->msg); + pdev = nc->dev; + dbus_message_append_args(reply, DBUS_TYPE_STRING, &pdev, + DBUS_TYPE_INVALID); send_message_and_unref(nc->conn, reply); nc->state = CONNECTED; diff --git a/network/network-api.txt b/network/network-api.txt index d155370e..c50eb8d5 100644 --- a/network/network-api.txt +++ b/network/network-api.txt @@ -14,16 +14,16 @@ Methods string CreateServer(string uuid) Creates a network server object(GN or NAP). - Possible errors:org.bluez.network.AlreadyExists - org.bluez.network.NotSupported - org.bluez.network.ConnectionAttemptFailed - org.bluez.network.Failed + Possible errors:org.bluez.network.Error.AlreadyExists + org.bluez.network.Error.NotSupported + org.bluez.network.Error.ConnectionAttemptFailed + org.bluez.network.Error.Failed void RemoveServer(string path) Removes the network server object for given path. - Possible errors:org.bluez.network.DoesNotExist - org.bluez.network.Failed + Possible errors:org.bluez.network.Error.DoesNotExist + org.bluez.network.Error.Failed array{string} ListServers() @@ -34,17 +34,17 @@ Methods string CreateServer(string uuid) Creates a network connection object(NAP or GN). - Possible errors:org.bluez.network.AlreadyExists - org.bluez.network.NotSupported - org.bluez.network.ConnectionAttemptFailed - org.bluez.network.Failed + Possible errors:org.bluez.network.Error.AlreadyExists + org.bluez.network.Error.NotSupported + org.bluez.network.Error.ConnectionAttemptFailed + org.bluez.network.Error.Failed string RemoveConnection(string path) Removes a network connection object for a given path. - Possible errors:org.bluez.network.DoesNotExist - org.bluez.network.Failed + Possible errors:org.bluez.network.Error.DoesNotExist + org.bluez.network.Error.Failed array{string} ListConnections() @@ -54,8 +54,8 @@ Methods string CreateServer(string uuid) Returns an array of available network connections paths. - Possible errors:org.bluez.network.DoesNotExist - org.bluez.network.Failed + Possible errors:org.bluez.network.Error.DoesNotExist + org.bluez.network.Error.Failed Signals @@ -81,14 +81,14 @@ Methods string GetUUID() Enable server and updates service record. - Possible errors:org.bluez.network.AlreadyExists - org.bluez.network.Failed + Possible errors:org.bluez.network.Error.AlreadyExists + org.bluez.network.Error.Failed void Disable() Disable server and remove service record. - Possible errors:org.bluez.network.Failed + Possible errors:org.bluez.network.Error.Failed void SetName(string name) @@ -144,32 +144,32 @@ Methods string GetAddress() Returns the string representation of connected host. - Possible errors:org.bluez.network.Failed + Possible errors:org.bluez.network.Error.Failed string GetDescription() Returns the string description of connected host. - Possible errors:org.bluez.network.Failed + Possible errors:org.bluez.network.Error.Failed string GetInterface() Returns the string network interface. - Possible errors:org.bluez.network.Failed + Possible errors:org.bluez.network.Error.Failed - void Connect() + string Connect() - Connects to host. + Connects to host and return the network interface created. - Possible errors:org.bluez.network.ConnectionAttemptFailed - org.bluez.network.Failed + Possible errors:org.bluez.network.Error.ConnectionAttemptFailed + org.bluez.network.Error.Failed void Disconnect() Disconnects to host. - Possible errors:org.bluez.network.Failed + Possible errors:org.bluez.network.Error.Failed bool IsConnected() -- cgit From 3268722532e19150b0084dd3b64c3cf0b0bb03ea Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Tue, 1 May 2007 14:56:05 +0000 Subject: network: minor cleanup --- network/manager.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 6f7a5257..cc13ed62 100644 --- a/network/manager.c +++ b/network/manager.c @@ -428,9 +428,7 @@ static DBusHandlerResult create_server(DBusConnection *conn, server_paths = g_slist_append(server_paths, g_strdup(path)); - create_path(conn, msg, path, "ServerCreated"); - - return DBUS_HANDLER_RESULT_HANDLED; + return create_path(conn, msg, path, "ServerCreated"); } static DBusHandlerResult remove_server(DBusConnection *conn, -- 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/manager.c | 42 ++++++++++++++++++++++++++++++++++++++ network/server.c | 61 +++++++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 92 insertions(+), 11 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index cc13ed62..720f4eb1 100644 --- a/network/manager.c +++ b/network/manager.c @@ -431,6 +431,45 @@ static DBusHandlerResult create_server(DBusConnection *conn, return create_path(conn, msg, path, "ServerCreated"); } +static DBusHandlerResult find_server(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + DBusError derr; + const char *pattern; + const char *path; + GSList *list; + DBusMessage *reply; + + dbus_error_init(&derr); + if (!dbus_message_get_args(msg, &derr, + DBUS_TYPE_STRING, &pattern, + DBUS_TYPE_INVALID)) { + err_invalid_args(conn, msg, derr.message); + dbus_error_free(&derr); + return DBUS_HANDLER_RESULT_HANDLED; + } + + for (list = server_paths; list; list = list->next) { + path = (const char *) list->data; + if (server_find_data(conn, path, pattern) == 0) + break; + } + + if (list == NULL) { + err_failed(conn, msg, "No such server"); + return DBUS_HANDLER_RESULT_HANDLED; + } + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_message_append_args(reply, DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); + + return send_message_and_unref(conn, reply); +} + static DBusHandlerResult remove_server(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -561,6 +600,9 @@ static DBusHandlerResult manager_message(DBusConnection *conn, if (strcmp(member, "CreateServer") == 0) return create_server(conn, msg, data); + if (strcmp(member, "FindServer") == 0) + return find_server(conn, msg, data); + if (strcmp(member, "RemoveServer") == 0) return remove_server(conn, msg, data); 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 734d59c4b7d40106069f621747ccf63934b048ff Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 8 May 2007 13:57:23 +0000 Subject: Update API documentation --- network/network-api.txt | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'network') diff --git a/network/network-api.txt b/network/network-api.txt index c50eb8d5..efbe6ca5 100644 --- a/network/network-api.txt +++ b/network/network-api.txt @@ -30,6 +30,13 @@ Methods string CreateServer(string uuid) Returns an array of available network devices paths. Currently only NAP and GN are supported. + string FindServer(string pattern) + + Returns server path. + + Possible errors:org.bluez.network.Error.DoesNotExist + org.bluez.network.Error.Failed + string CreateConnection(string address, string uuid) Creates a network connection object(NAP or GN). @@ -52,7 +59,7 @@ Methods string CreateServer(string uuid) string FindConnection(string pattern) - Returns an array of available network connections paths. + Returns connection path. Possible errors:org.bluez.network.Error.DoesNotExist org.bluez.network.Error.Failed -- cgit From 89aa5447d1310dc3b9a8591dbe80abac9239a114 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 8 May 2007 14:00:22 +0000 Subject: Make connection host address available via GetInfo. --- network/connection.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 2bbd3e60..cd1e0a5d 100644 --- a/network/connection.c +++ b/network/connection.c @@ -509,6 +509,8 @@ static DBusHandlerResult get_info(DBusConnection *conn, DBusMessageIter iter; DBusMessageIter dict; const char *uuid; + char raddr[18]; + const char *paddr = raddr; reply = dbus_message_new_method_return(msg); if (!reply) @@ -528,6 +530,10 @@ static DBusHandlerResult get_info(DBusConnection *conn, dbus_message_iter_append_dict_entry(&dict, "uuid", DBUS_TYPE_STRING, &uuid); + ba2str(&nc->dst, raddr); + dbus_message_iter_append_dict_entry(&dict, "address", + DBUS_TYPE_STRING, &paddr); + dbus_message_iter_close_container(&iter, &dict); return send_message_and_unref(conn, reply); -- cgit From fcba5ddbba50277ab533ac9efc8414f8b839ec8e Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 8 May 2007 14:08:54 +0000 Subject: Add service test scripts --- network/Makefile.am | 2 +- network/test-network | 27 +++++++++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100755 network/test-network (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index e01bd4b9..17869043 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -23,6 +23,6 @@ AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ @HAL_CFLAGS@ @GLIB_CFLAGS@ INCLUDES = -I$(top_srcdir)/common -EXTRA_DIST = network.service network-api.txt +EXTRA_DIST = network.service network-api.txt test-network MAINTAINERCLEANFILES = Makefile.in diff --git a/network/test-network b/network/test-network new file mode 100755 index 00000000..8860003b --- /dev/null +++ b/network/test-network @@ -0,0 +1,27 @@ +#!/usr/bin/python + +import dbus + +bus = dbus.SystemBus() + +manager = dbus.Interface(bus.get_object('org.bluez', '/org/bluez'), + 'org.bluez.Manager') + +conn = manager.ActivateService('network') + +network = dbus.Interface(bus.get_object(conn, '/org/bluez/network'), + 'org.bluez.network.Manager') + +try: + nap = dbus.Interface(bus.get_object('org.bluez.network', + network.FindAdapter('nap')), + 'org.bluez.network.Server') +except: + pass + +try: + gn = dbus.Interface(bus.get_object('org.bluez.network', + network.FindAdapter('gn')), + 'org.bluez.network.Server') +except: + pass -- cgit From e9143c3e1fd1b882f475c98394f549d2b2aabcea Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 8 May 2007 14:41:11 +0000 Subject: Proceed if the bridge creation fails --- network/manager.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 720f4eb1..9309701b 100644 --- a/network/manager.c +++ b/network/manager.c @@ -25,9 +25,9 @@ #include #endif +#include #include #include -#include #include @@ -773,10 +773,8 @@ int network_init(DBusConnection *conn) return -1; } - if (bridge_create("pan0") < 0) { + if (bridge_create("pan0") < 0) error("Can't create bridge"); - return -1; - } if (bnep_init()) { error("Can't init bnep module"); -- 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 +++++--- network/server.h | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'network') 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) diff --git a/network/server.h b/network/server.h index 30016f3e..ff754711 100644 --- a/network/server.h +++ b/network/server.h @@ -28,3 +28,5 @@ int server_register_from_file(DBusConnection *conn, const char *path, int server_store(DBusConnection *conn, const char *path); int server_remove_stored(DBusConnection *conn, const char *path); +int server_find_data(DBusConnection *conn, const char *path, + const char *pattern); -- cgit From a643c69886a9cff7c50bb93852d523e3d996d2ed Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 8 May 2007 15:00:58 +0000 Subject: Fix network service test script --- network/test-network | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'network') diff --git a/network/test-network b/network/test-network index 8860003b..fe83cd21 100755 --- a/network/test-network +++ b/network/test-network @@ -13,15 +13,13 @@ network = dbus.Interface(bus.get_object(conn, '/org/bluez/network'), 'org.bluez.network.Manager') try: - nap = dbus.Interface(bus.get_object('org.bluez.network', - network.FindAdapter('nap')), + nap = dbus.Interface(bus.get_object(conn, network.FindServer('nap')), 'org.bluez.network.Server') except: pass try: - gn = dbus.Interface(bus.get_object('org.bluez.network', - network.FindAdapter('gn')), + gn = dbus.Interface(bus.get_object(conn, network.FindServer('gn')), 'org.bluez.network.Server') except: pass -- cgit From 5c5027129ae654846562825d1f0690ad6e594c4f Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 9 May 2007 14:04:20 +0000 Subject: Fix RemoveConnection documentation. --- network/network-api.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network') diff --git a/network/network-api.txt b/network/network-api.txt index efbe6ca5..d939d8a1 100644 --- a/network/network-api.txt +++ b/network/network-api.txt @@ -46,7 +46,7 @@ Methods string CreateServer(string uuid) org.bluez.network.Error.ConnectionAttemptFailed org.bluez.network.Error.Failed - string RemoveConnection(string path) + void RemoveConnection(string path) Removes a network connection object for a given path. -- 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/connection.c | 82 ++++++++++++++++------------------------- network/manager.c | 94 ++++++++++++++++++----------------------------- network/server.c | 102 +++++++++++++++++++++++---------------------------- 3 files changed, 113 insertions(+), 165 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index cd1e0a5d..cd963dad 100644 --- a/network/connection.c +++ b/network/connection.c @@ -539,47 +539,6 @@ static DBusHandlerResult get_info(DBusConnection *conn, return send_message_and_unref(conn, reply); } -static DBusHandlerResult connection_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_CONNECTION_INTERFACE, iface)) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - if (strcmp(member, "GetAddress") == 0) - return get_address(conn, msg, data); - - if (strcmp(member, "GetUUID") == 0) - return get_uuid(conn, msg, data); - - if (strcmp(member, "GetName") == 0) - return get_name(conn, msg, data); - - if (strcmp(member, "GetDescription") == 0) - return get_description(conn, msg, data); - - if (strcmp(member, "GetInterface") == 0) - return get_interface(conn, msg, data); - - if (strcmp(member, "Connect") == 0) - return connection_connect(conn, msg, data); - - if (strcmp(member, "Disconnect") == 0) - return connection_disconnect(conn, msg, data); - - if (strcmp(member, "IsConnected") == 0) - return is_connected(conn, msg, data); - - if (strcmp(member, "GetInfo") == 0) - return get_info(conn, msg, data); - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - static void connection_free(struct network_conn *nc) { if (!nc) @@ -612,10 +571,23 @@ static void connection_unregister(DBusConnection *conn, void *data) connection_free(nc); } -/* Virtual table to handle connection object path hierarchy */ -static const DBusObjectPathVTable connection_table = { - .message_function = connection_message, - .unregister_function = connection_unregister, +static DBusMethodVTable connection_methods[] = { + { "GetAddress", get_address, "", "s" }, + { "GetUUID", get_uuid, "", "s" }, + { "GetName", get_name, "", "s" }, + { "GetDescription", get_description, "", "s" }, + { "GetInterface", get_interface, "", "s" }, + { "Connect", connection_connect, "", "s" }, + { "Disconnect", connection_disconnect, "", "" }, + { "IsConnected", is_connected, "", "b" }, + { "GetInfo", get_info, "", "{sv}", }, + { NULL, NULL, NULL, NULL } +}; + +static DBusSignalVTable connection_signals[] = { + { "Connected", "" }, + { "Disconnected", "" }, + { NULL, NULL } }; int connection_register(DBusConnection *conn, const char *path, bdaddr_t *src, @@ -629,12 +601,22 @@ int connection_register(DBusConnection *conn, const char *path, bdaddr_t *src, nc = g_new0(struct network_conn, 1); /* register path */ - if (!dbus_connection_register_object_path(conn, path, - &connection_table, nc)) { + if (!dbus_connection_create_object_path(conn, path, nc, + connection_unregister)) { connection_free(nc); return -1; } + if (!dbus_connection_register_interface(conn, path, + NETWORK_CONNECTION_INTERFACE, + connection_methods, + connection_signals, NULL)) { + error("D-Bus failed to register %s interface", + NETWORK_CONNECTION_INTERFACE); + dbus_connection_destroy_object_path(conn, path); + return -1; + } + nc->path = g_strdup(path); bacpy(&nc->src, src); bacpy(&nc->dst, dst); @@ -660,7 +642,7 @@ int connection_store(DBusConnection *conn, const char *path) char src_addr[18], dst_addr[18]; int len, err; - if (!dbus_connection_get_object_path_data(conn, path, (void *) &nc)) + if (!dbus_connection_get_object_user_data(conn, path, (void *) &nc)) return -ENOENT; if (!nc->name || !nc->desc) @@ -692,7 +674,7 @@ int connection_find_data(DBusConnection *conn, struct network_conn *nc; char addr[18]; - if (!dbus_connection_get_object_path_data(conn, path, (void *) &nc)) + if (!dbus_connection_get_object_user_data(conn, path, (void *) &nc)) return -1; if (strcasecmp(pattern, nc->dev) == 0) @@ -713,7 +695,7 @@ gboolean connection_has_pending(DBusConnection *conn, const char *path) { struct network_conn *nc; - if (!dbus_connection_get_object_path_data(conn, path, (void *) &nc)) + if (!dbus_connection_get_object_user_data(conn, path, (void *) &nc)) return FALSE; return (nc->state == CONNECTING); diff --git a/network/manager.c b/network/manager.c index 9309701b..8e8a4066 100644 --- a/network/manager.c +++ b/network/manager.c @@ -41,6 +41,7 @@ #include #include "dbus.h" +#include "dbus-helper.h" #include "logging.h" #include "textfile.h" @@ -577,50 +578,6 @@ static DBusHandlerResult remove_connection(DBusConnection *conn, return remove_path(conn, msg, &connection_paths, "ConnectionRemoved"); } -static DBusHandlerResult manager_message(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - const char *path, *iface, *member; - - path = dbus_message_get_path(msg); - iface = dbus_message_get_interface(msg); - member = dbus_message_get_member(msg); - - /* Catching fallback paths */ - if (strcmp(NETWORK_PATH, path) != 0) - return err_unknown_connection(conn, msg); - - /* Accept messages from the manager interface only */ - if (strcmp(NETWORK_MANAGER_INTERFACE, iface)) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - if (strcmp(member, "ListServers") == 0) - return list_servers(conn, msg, data); - - if (strcmp(member, "CreateServer") == 0) - return create_server(conn, msg, data); - - if (strcmp(member, "FindServer") == 0) - return find_server(conn, msg, data); - - if (strcmp(member, "RemoveServer") == 0) - return remove_server(conn, msg, data); - - if (strcmp(member, "ListConnections") == 0) - return list_connections(conn, msg, data); - - if (strcmp(member, "FindConnection") == 0) - return find_connection(conn, msg, data); - - if (strcmp(member, "CreateConnection") == 0) - return create_connection(conn, msg, data); - - if (strcmp(member, "RemoveConnection") == 0) - return remove_connection(conn, msg, data); - - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; -} - static void manager_unregister(DBusConnection *conn, void *data) { info("Unregistered manager path"); @@ -640,12 +597,6 @@ static void manager_unregister(DBusConnection *conn, void *data) bnep_kill_all_connections(); } -/* Virtual table to handle manager object path hierarchy */ -static const DBusObjectPathVTable manager_table = { - .message_function = manager_message, - .unregister_function = manager_unregister, -}; - static void parse_stored_connection(char *key, char *value, void *data) { bdaddr_t dst, *src = data; @@ -766,6 +717,26 @@ static void register_stored(void) closedir(dir); } +static DBusMethodVTable manager_methods[] = { + { "ListServers", list_servers, "", "as" }, + { "CreateServer", create_server, "s", "s" }, + { "FindServer", find_server, "s", "s" }, + { "RemoveServer", remove_server, "s", "" }, + { "ListConnections", list_connections, "", "as" }, + { "FindConnection", find_connection, "s", "s" }, + { "CreateConnection", create_connection, "ss", "s" }, + { "RemoveConnection", remove_connection, "s", "" }, + { NULL, NULL, NULL, NULL } +}; + +static DBusSignalVTable manager_signals[] = { + { "ServerCreated", "s" }, + { "ServerRemoved", "s" }, + { "ConnectionCreated", "s" }, + { "ConnectionRemoved", "s" }, + { NULL, NULL } +}; + int network_init(DBusConnection *conn) { if (bridge_init() < 0) { @@ -781,17 +752,24 @@ int network_init(DBusConnection *conn) return -1; } - connection = dbus_connection_ref(conn); - - /* Fallback to catch invalid network path */ - if (dbus_connection_register_fallback(connection, NETWORK_PATH, - &manager_table, NULL) == FALSE) { - error("D-Bus failed to register %s path", NETWORK_PATH); - dbus_connection_unref(connection); + if (!dbus_connection_create_object_path(conn, NETWORK_PATH, + NULL, manager_unregister)) { + error("D-Bus failed to create %s path", NETWORK_PATH); + return -1; + } + if (!dbus_connection_register_interface(conn, NETWORK_PATH, + NETWORK_MANAGER_INTERFACE, + manager_methods, + manager_signals, NULL)) { + error("Failed to register %s interface to %s", + NETWORK_MANAGER_INTERFACE, NETWORK_PATH); + dbus_connection_destroy_object_path(connection, NETWORK_PATH); return -1; } + connection = dbus_connection_ref(conn); + info("Registered manager path:%s", NETWORK_PATH); register_stored(); @@ -801,7 +779,7 @@ int network_init(DBusConnection *conn) void network_exit(void) { - dbus_connection_unregister_object_path(connection, NETWORK_PATH); + dbus_connection_destroy_object_path(connection, NETWORK_PATH); dbus_connection_unref(connection); 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 0ebe9945de9b9e91169619cf1e09a40796aad41b Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 9 May 2007 14:49:23 +0000 Subject: Use dbus_connection_destroy object path instead of dbus_connection_unregister_object_path --- network/manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 8e8a4066..07f30d46 100644 --- a/network/manager.c +++ b/network/manager.c @@ -177,7 +177,7 @@ static DBusHandlerResult remove_path(DBusConnection *conn, /* Remove the nap or gn file from the file system */ server_remove_stored(conn, path); - if (!dbus_connection_unregister_object_path(conn, path)) + if (!dbus_connection_destroy_object_path(conn, path)) error("Network path unregister failed"); signal = dbus_message_new_signal(NETWORK_PATH, -- 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/connection.c | 20 +++++++++----------- network/manager.c | 28 ++++++++++------------------ network/server.c | 18 +++++++----------- 3 files changed, 26 insertions(+), 40 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index cd963dad..d565fea2 100644 --- a/network/connection.c +++ b/network/connection.c @@ -79,13 +79,12 @@ static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond, gpointer data) { struct network_conn *nc = data; - DBusMessage *signal; if (nc->conn != NULL) { - signal = dbus_message_new_signal(nc->path, - NETWORK_CONNECTION_INTERFACE, "Disconnected"); - - send_message_and_unref(nc->conn, signal); + dbus_connection_emit_signal(nc->conn, nc->path, + NETWORK_CONNECTION_INTERFACE, + "Disconnected", + DBUS_TYPE_INVALID); } info("%s disconnected", nc->dev); nc->state = DISCONNECTED; @@ -103,7 +102,7 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, char pkt[BNEP_MTU]; gsize r; int sk; - DBusMessage *reply, *signal; + DBusMessage *reply; const char *pdev; if (cond & G_IO_NVAL) @@ -157,11 +156,10 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, } bnep_if_up(nc->dev, TRUE); - - signal = dbus_message_new_signal(nc->path, - NETWORK_CONNECTION_INTERFACE, "Connected"); - - send_message_and_unref(nc->conn, signal); + dbus_connection_emit_signal(nc->conn, nc->path, + NETWORK_CONNECTION_INTERFACE, + "Connected", + DBUS_TYPE_INVALID); reply = dbus_message_new_method_return(nc->msg); diff --git a/network/manager.c b/network/manager.c index 07f30d46..b61233c9 100644 --- a/network/manager.c +++ b/network/manager.c @@ -94,18 +94,14 @@ static DBusHandlerResult create_path(DBusConnection *conn, DBusMessage *msg, const char *path, const char *sname) { - DBusMessage *reply, *signal; + DBusMessage *reply; /* emit signal when it is a new path */ if (sname) { - signal = dbus_message_new_signal(NETWORK_PATH, - NETWORK_MANAGER_INTERFACE, sname); - - dbus_message_append_args(signal, - DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); - - send_message_and_unref(conn, signal); + dbus_connection_emit_signal(conn, NETWORK_PATH, + NETWORK_MANAGER_INTERFACE, + sname, DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); } reply = dbus_message_new_method_return(msg); @@ -148,7 +144,7 @@ static DBusHandlerResult remove_path(DBusConnection *conn, const char *sname) { const char *path; - DBusMessage *reply, *signal; + DBusMessage *reply; DBusError derr; GSList *l; @@ -180,14 +176,10 @@ static DBusHandlerResult remove_path(DBusConnection *conn, if (!dbus_connection_destroy_object_path(conn, path)) error("Network path unregister failed"); - signal = dbus_message_new_signal(NETWORK_PATH, - NETWORK_MANAGER_INTERFACE, sname); - - dbus_message_append_args(signal, - DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); - - send_message_and_unref(conn, signal); + dbus_connection_emit_signal(conn, NETWORK_PATH, + NETWORK_MANAGER_INTERFACE, + sname, DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); return send_message_and_unref(conn, reply); } 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 07958fc3612225ceeffcbbcbae320a2bedcd774d Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 10 May 2007 08:45:28 +0000 Subject: Update API descriptions --- network/network-api.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'network') diff --git a/network/network-api.txt b/network/network-api.txt index d939d8a1..f88679d6 100644 --- a/network/network-api.txt +++ b/network/network-api.txt @@ -12,7 +12,7 @@ Object path /org/bluez/network Methods string CreateServer(string uuid) - Creates a network server object(GN or NAP). + Creates a network server object (GN or NAP). Possible errors:org.bluez.network.Error.AlreadyExists org.bluez.network.Error.NotSupported @@ -74,6 +74,7 @@ Signals void ConnectionRemoved(string path) + Network Server hierarchy (experimental) ======================================= @@ -82,7 +83,8 @@ Object path /org/bluez/network/server* Methods string GetUUID() - Returns the uuid 128 string representation of the server. + Returns the UUID-128 string representation of + the server. void Enable() @@ -126,12 +128,11 @@ Methods string GetUUID() Returns the server properties. -Signals - - void Enabled() +Signals void Enabled() void Disabled() + Network Connection hierarchy (experimental) =========================================== @@ -167,7 +168,8 @@ Methods string GetAddress() string Connect() - Connects to host and return the network interface created. + Connects to host and return the network interface + created. Possible errors:org.bluez.network.Error.ConnectionAttemptFailed org.bluez.network.Error.Failed @@ -186,8 +188,6 @@ Methods string GetAddress() Returns the connection properties. -Signals - - void Connected() +Signals void Connected() void Disconnected() -- cgit From 57704487a484a6d599f12cee65b63f8daa7ecf8b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 14 May 2007 12:28:55 +0000 Subject: Add method to retrieve adapter address --- network/connection.c | 29 +++++++++++++++++++++++++---- network/network-api.txt | 48 ++++++++++++++++++++++++++---------------------- 2 files changed, 51 insertions(+), 26 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index d565fea2..9062c419 100644 --- a/network/connection.c +++ b/network/connection.c @@ -313,15 +313,36 @@ static int l2cap_connect(struct network_conn *nc) return 0; } +static DBusHandlerResult get_adapter(DBusConnection *conn, DBusMessage *msg, + void *data) +{ + struct network_conn *nc = data; + DBusMessage *reply; + char addr[18]; + const char *paddr = addr; + + ba2str(&nc->src, addr); + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_message_append_args(reply, DBUS_TYPE_STRING, &paddr, + DBUS_TYPE_INVALID); + + return send_message_and_unref(conn, reply); +} + static DBusHandlerResult get_address(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_conn *nc = data; DBusMessage *reply; - char raddr[18]; - const char *paddr = raddr; + char addr[18]; + const char *paddr = addr; + + ba2str(&nc->dst, addr); - ba2str(&nc->dst, raddr); reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; @@ -570,6 +591,7 @@ static void connection_unregister(DBusConnection *conn, void *data) } static DBusMethodVTable connection_methods[] = { + { "GetAdapter", get_adapter, "", "s" }, { "GetAddress", get_address, "", "s" }, { "GetUUID", get_uuid, "", "s" }, { "GetName", get_name, "", "s" }, @@ -698,4 +720,3 @@ gboolean connection_has_pending(DBusConnection *conn, const char *path) return (nc->state == CONNECTING); } - diff --git a/network/network-api.txt b/network/network-api.txt index f88679d6..aa562d74 100644 --- a/network/network-api.txt +++ b/network/network-api.txt @@ -14,16 +14,16 @@ Methods string CreateServer(string uuid) Creates a network server object (GN or NAP). - Possible errors:org.bluez.network.Error.AlreadyExists - org.bluez.network.Error.NotSupported - org.bluez.network.Error.ConnectionAttemptFailed - org.bluez.network.Error.Failed + Possible errors: org.bluez.network.Error.AlreadyExists + org.bluez.network.Error.NotSupported + org.bluez.network.Error.ConnectionAttemptFailed + org.bluez.network.Error.Failed void RemoveServer(string path) Removes the network server object for given path. - Possible errors:org.bluez.network.Error.DoesNotExist - org.bluez.network.Error.Failed + Possible errors: org.bluez.network.Error.DoesNotExist + org.bluez.network.Error.Failed array{string} ListServers() @@ -34,17 +34,17 @@ Methods string CreateServer(string uuid) Returns server path. - Possible errors:org.bluez.network.Error.DoesNotExist - org.bluez.network.Error.Failed + Possible errors: org.bluez.network.Error.DoesNotExist + org.bluez.network.Error.Failed string CreateConnection(string address, string uuid) Creates a network connection object(NAP or GN). - Possible errors:org.bluez.network.Error.AlreadyExists - org.bluez.network.Error.NotSupported - org.bluez.network.Error.ConnectionAttemptFailed - org.bluez.network.Error.Failed + Possible errors: org.bluez.network.Error.AlreadyExists + org.bluez.network.Error.NotSupported + org.bluez.network.Error.ConnectionAttemptFailed + org.bluez.network.Error.Failed void RemoveConnection(string path) @@ -90,14 +90,14 @@ Methods string GetUUID() Enable server and updates service record. - Possible errors:org.bluez.network.Error.AlreadyExists - org.bluez.network.Error.Failed + Possible errors: org.bluez.network.Error.AlreadyExists + org.bluez.network.Error.Failed void Disable() Disable server and remove service record. - Possible errors:org.bluez.network.Error.Failed + Possible errors: org.bluez.network.Error.Failed void SetName(string name) @@ -139,7 +139,11 @@ Network Connection hierarchy (experimental) Interface org.bluez.network.Connection Object path /org/bluez/network/connection* -Methods string GetAddress() +Methods string GetAdapter() + + Returns the Bluetooth address of the adapter. + + string GetAddress() Returns the Bluetooth address of the ending point. @@ -152,33 +156,33 @@ Methods string GetAddress() Returns the string representation of connected host. - Possible errors:org.bluez.network.Error.Failed + Possible errors: org.bluez.network.Error.Failed string GetDescription() Returns the string description of connected host. - Possible errors:org.bluez.network.Error.Failed + Possible errors: org.bluez.network.Error.Failed string GetInterface() Returns the string network interface. - Possible errors:org.bluez.network.Error.Failed + Possible errors: org.bluez.network.Error.Failed string Connect() Connects to host and return the network interface created. - Possible errors:org.bluez.network.Error.ConnectionAttemptFailed - org.bluez.network.Error.Failed + Possible errors: org.bluez.network.Error.ConnectionAttemptFailed + org.bluez.network.Error.Failed void Disconnect() Disconnects to host. - Possible errors:org.bluez.network.Error.Failed + Possible errors: org.bluez.network.Error.Failed bool IsConnected() -- cgit From 39d74106f6bbb9f998387dd27529fc077773a182 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 14 May 2007 15:05:20 +0000 Subject: Add CancelConnect to Connection interface. --- network/connection.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 9062c419..4f57e93a 100644 --- a/network/connection.c +++ b/network/connection.c @@ -176,9 +176,11 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, (GIOFunc) bnep_watchdog_cb, nc); return FALSE; failed: - nc->state = DISCONNECTED; - err_connection_failed(nc->conn, nc->msg, "bnep failed"); - g_io_channel_close(chan); + if (nc->state != DISCONNECTED) { + nc->state = DISCONNECTED; + err_connection_failed(nc->conn, nc->msg, "bnep failed"); + g_io_channel_close(chan); + } return FALSE; } @@ -465,7 +467,7 @@ static DBusHandlerResult connection_connect(DBusConnection *conn, } nc->msg = dbus_message_ref(msg); - if(l2cap_connect(nc)) { + if (l2cap_connect(nc) < 0) { error("Connect failed. %s(%d)", strerror(errno), errno); goto fail; } @@ -481,6 +483,25 @@ fail: return DBUS_HANDLER_RESULT_HANDLED; } +static DBusHandlerResult connection_cancel(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + struct network_conn *nc = data; + DBusMessage *reply; + + if (nc->state != CONNECTING) { + err_failed(conn, msg, "Device has no pending connect"); + return DBUS_HANDLER_RESULT_HANDLED; + } + + close(nc->sk); + nc->state = DISCONNECTED; + + reply = dbus_message_new_method_return(msg); + + return send_message_and_unref(conn, reply); +} + static DBusHandlerResult connection_disconnect(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -598,6 +619,7 @@ static DBusMethodVTable connection_methods[] = { { "GetDescription", get_description, "", "s" }, { "GetInterface", get_interface, "", "s" }, { "Connect", connection_connect, "", "s" }, + { "CancelConnect", connection_cancel, "", "" }, { "Disconnect", connection_disconnect, "", "" }, { "IsConnected", is_connected, "", "b" }, { "GetInfo", get_info, "", "{sv}", }, -- cgit From 13ca53c2faccdc5b75250c8c36a70340d4ae7214 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 15 May 2007 11:23:56 +0000 Subject: Add CancelConnect method description --- network/network-api.txt | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'network') diff --git a/network/network-api.txt b/network/network-api.txt index aa562d74..278ba8eb 100644 --- a/network/network-api.txt +++ b/network/network-api.txt @@ -178,6 +178,11 @@ Methods string GetAdapter() Possible errors: org.bluez.network.Error.ConnectionAttemptFailed org.bluez.network.Error.Failed + string CancelConnect() + + Abort connection attempt in case of errors or + timeouts in the client. + void Disconnect() Disconnects to host. -- cgit From f8afd4132d6a0feebe628be9faadb41cc5ca3b62 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 15 May 2007 12:13:24 +0000 Subject: Update CancelConnect documentation. --- network/network-api.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'network') diff --git a/network/network-api.txt b/network/network-api.txt index 278ba8eb..9bdf5ca8 100644 --- a/network/network-api.txt +++ b/network/network-api.txt @@ -178,11 +178,13 @@ Methods string GetAdapter() Possible errors: org.bluez.network.Error.ConnectionAttemptFailed org.bluez.network.Error.Failed - string CancelConnect() + void CancelConnect() Abort connection attempt in case of errors or timeouts in the client. + Possible errors: org.bluez.network.Error.Failed + void Disconnect() Disconnects to host. -- cgit From 417006053c2c16cd8ae5b947d0a8daae4f151b94 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 16 May 2007 13:13:58 +0000 Subject: Fixes storage problems with connections and fix bug of CreateConnection not checking for present connection with the same destination and profile. --- network/connection.c | 38 ++++++++++++++++++++++++++++++++--- network/connection.h | 1 + network/manager.c | 57 ++++++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 85 insertions(+), 11 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 4f57e93a..68c53b7b 100644 --- a/network/connection.c +++ b/network/connection.c @@ -28,7 +28,7 @@ #include #include #include - +#include #include #include @@ -702,19 +702,21 @@ int connection_store(DBusConnection *conn, const char *path) ba2str(&nc->src, src_addr); create_name(filename, PATH_MAX, STORAGEDIR, src_addr, "network"); + create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); err = textfile_put(filename, key, value); g_free(value); - return err; + return err; } int connection_find_data(DBusConnection *conn, const char *path, const char *pattern) { struct network_conn *nc; - char addr[18]; + char addr[18], key[32]; + const char *role; if (!dbus_connection_get_object_user_data(conn, path, (void *) &nc)) return -1; @@ -730,6 +732,12 @@ int connection_find_data(DBusConnection *conn, if (strcasecmp(pattern, addr) == 0) return 0; + role = bnep_name(nc->id); + snprintf(key, 32, "%s#%s", addr, role); + + if (strcasecmp(pattern, key) == 0) + return 0; + return -1; } @@ -742,3 +750,27 @@ gboolean connection_has_pending(DBusConnection *conn, const char *path) return (nc->state == CONNECTING); } + +int connection_remove_stored(DBusConnection *conn, const char *path) +{ + struct network_conn *nc; + const char *role; + char key[32]; + char filename[PATH_MAX + 1]; + char src_addr[18], dst_addr[18]; + int err; + + if (!dbus_connection_get_object_user_data(conn, path, (void *) &nc)) + return -ENOENT; + + ba2str(&nc->dst, dst_addr); + role = bnep_name(nc->id); + snprintf(key, 32, "%s#%s", dst_addr, role); + + ba2str(&nc->src, src_addr); + create_name(filename, PATH_MAX, STORAGEDIR, src_addr, "network"); + + err = textfile_del(filename, key); + + return err; +} diff --git a/network/connection.h b/network/connection.h index 205e44da..ff33789f 100644 --- a/network/connection.h +++ b/network/connection.h @@ -24,6 +24,7 @@ int connection_register(DBusConnection *conn, const char *path, bdaddr_t *src, bdaddr_t *dst, uint16_t id, const char *name, const char *desc); int connection_store(DBusConnection *conn, const char *path); +int connection_remove_stored(DBusConnection *conn, const char *path); int connection_find_data(DBusConnection *conn, const char *path, const char *pattern); gboolean connection_has_pending(DBusConnection *conn, const char *path); diff --git a/network/manager.c b/network/manager.c index b61233c9..8eac0bee 100644 --- a/network/manager.c +++ b/network/manager.c @@ -161,8 +161,15 @@ static DBusHandlerResult remove_path(DBusConnection *conn, if (!l) return err_does_not_exist(conn, msg, "Path doesn't exist"); - if (*list == connection_paths && connection_has_pending (conn, path)) - return err_failed(conn, msg, "Connection is Busy"); + /* Remove references from the storage */ + if (*list == connection_paths) { + if (connection_has_pending (conn, path)) + return err_failed(conn, msg, "Connection is Busy"); + + connection_remove_stored(conn, path); + } + else + server_remove_stored(conn, path); g_free(l->data); *list = g_slist_remove(*list, l->data); @@ -171,8 +178,6 @@ static DBusHandlerResult remove_path(DBusConnection *conn, if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; - /* Remove the nap or gn file from the file system */ - server_remove_stored(conn, path); if (!dbus_connection_destroy_object_path(conn, path)) error("Network path unregister failed"); @@ -524,6 +529,8 @@ static DBusHandlerResult create_connection(DBusConnection *conn, bdaddr_t src; uint16_t id; int dev_id; + char key[32]; + GSList *l; dbus_error_init(&derr); if (!dbus_message_get_args(msg, &derr, @@ -539,6 +546,17 @@ static DBusHandlerResult create_connection(DBusConnection *conn, if ((id != BNEP_SVC_GN) && (id != BNEP_SVC_NAP)) return err_invalid_args(conn, msg, "Not supported"); + snprintf(key, 32, "%s#%s", addr, bnep_name(id)); + + /* Checks if the connection was already been made */ + for (l = connection_paths; l; l = l->next) { + if (connection_find_data(conn, l->data, key) == 0) { + err_already_exists(conn, msg, + "Connection Already exists"); + return DBUS_HANDLER_RESULT_HANDLED; + } + } + bacpy(&src, BDADDR_ANY); dev_id = hci_get_route(NULL); if ((dev_id < 0) || (hci_devba(dev_id, &src) < 0)) @@ -644,8 +662,13 @@ static void parse_stored_connection(char *key, char *value, void *data) if (connection_register(connection, path, src, &dst, id, name, ptr) == 0) { - connection_paths = g_slist_append(connection_paths, - g_strdup(path)); + char *rpath = g_strdup(path); + connection_paths = g_slist_append(connection_paths, rpath); + dbus_connection_emit_signal(connection, NETWORK_PATH, + NETWORK_MANAGER_INTERFACE, + "ConnectionCreated", + DBUS_TYPE_STRING, &rpath, + DBUS_TYPE_INVALID); } g_free(name); @@ -688,9 +711,18 @@ static void register_stored(void) NETWORK_PATH"/server/nap%d", net_uid++); if (server_register_from_file(connection, path, - &src, BNEP_SVC_NAP, filename) == 0) + &src, BNEP_SVC_NAP, filename) == 0) { server_paths = g_slist_append(server_paths, g_strdup(path)); + + dbus_connection_emit_signal(connection, + NETWORK_PATH, + NETWORK_MANAGER_INTERFACE, + "ServerCreated", + DBUS_TYPE_STRING, + &path, + DBUS_TYPE_INVALID); + } } /* GN objects */ @@ -700,9 +732,18 @@ static void register_stored(void) NETWORK_PATH"/server/gn%d", net_uid++); if (server_register_from_file(connection, path, - &src, BNEP_SVC_GN, filename) == 0) + &src, BNEP_SVC_GN, filename) == 0) { server_paths = g_slist_append(server_paths, g_strdup(path)); + + dbus_connection_emit_signal(connection, + NETWORK_PATH, + NETWORK_MANAGER_INTERFACE, + "ServerCreated", + DBUS_TYPE_STRING, + &path, + DBUS_TYPE_INVALID); + } } } -- cgit From df7260b7a01d10f92849ca9a862a2a2d6ffac865 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 17 May 2007 17:05:47 +0000 Subject: Add LastConnection, DefaultConnection and ChangeDefaultConnection API methods and some minor fixes. --- network/connection.c | 29 +++-- network/connection.h | 4 +- network/manager.c | 295 ++++++++++++++++++++++++++++++++++++++---------- network/network-api.txt | 21 ++++ 4 files changed, 282 insertions(+), 67 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 68c53b7b..18bba87c 100644 --- a/network/connection.c +++ b/network/connection.c @@ -675,7 +675,8 @@ int connection_register(DBusConnection *conn, const char *path, bdaddr_t *src, return 0; } -int connection_store(DBusConnection *conn, const char *path) +int connection_store(DBusConnection *conn, const char *path, + gboolean default_path) { struct network_conn *nc; const char *role; @@ -696,17 +697,19 @@ int connection_store(DBusConnection *conn, const char *path) role = bnep_name(nc->id); snprintf(key, 32, "%s#%s", dst_addr, role); - len = strlen(nc->name) + strlen(nc->desc) + 2; - value = g_malloc0(len); - snprintf(value, len, "%s:%s", nc->name, nc->desc); - ba2str(&nc->src, src_addr); create_name(filename, PATH_MAX, STORAGEDIR, src_addr, "network"); create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - err = textfile_put(filename, key, value); - - g_free(value); + if (default_path) + err = textfile_put(filename, "default", key); + else { + len = strlen(nc->name) + strlen(nc->desc) + 2; + value = g_malloc0(len); + snprintf(value, len, "%s:%s", nc->name, nc->desc); + err = textfile_put(filename, key, value); + g_free(value); + } return err; } @@ -774,3 +777,13 @@ int connection_remove_stored(DBusConnection *conn, const char *path) return err; } + +gboolean connection_is_connected(DBusConnection *conn, const char *path) +{ + struct network_conn *nc; + + if (!dbus_connection_get_object_user_data(conn, path, (void *) &nc)) + return FALSE; + + return (nc->state == CONNECTED); +} diff --git a/network/connection.h b/network/connection.h index ff33789f..5561ee32 100644 --- a/network/connection.h +++ b/network/connection.h @@ -23,8 +23,10 @@ int connection_register(DBusConnection *conn, const char *path, bdaddr_t *src, bdaddr_t *dst, uint16_t id, const char *name, const char *desc); -int connection_store(DBusConnection *conn, const char *path); +int connection_store(DBusConnection *conn, const char *path, + gboolean default_path); int connection_remove_stored(DBusConnection *conn, const char *path); int connection_find_data(DBusConnection *conn, const char *path, const char *pattern); gboolean connection_has_pending(DBusConnection *conn, const char *path); +gboolean connection_is_connected(DBusConnection *conn, const char *path); diff --git a/network/manager.c b/network/manager.c index 8eac0bee..6d7654f9 100644 --- a/network/manager.c +++ b/network/manager.c @@ -70,6 +70,7 @@ struct pending_reply { static GSList *server_paths = NULL; /* Network registered servers paths */ static GSList *connection_paths = NULL; /* Network registered connections paths */ +static int default_index = -1; /* Network default connection path index */ static DBusConnection *connection = NULL; @@ -139,6 +140,27 @@ static DBusHandlerResult list_paths(DBusConnection *conn, DBusMessage *msg, return send_message_and_unref(conn, reply); } +static const char * last_connection_used(DBusConnection *conn) +{ + const char *path = NULL; + GSList *l; + int i; + + for (i = g_slist_length (connection_paths) -1; i > -1; i--) { + path = g_slist_nth_data (connection_paths, i); + if (connection_is_connected (conn, path)) + break; + } + + /* No connection connected fallback to last connection */ + if (i == -1) { + l = g_slist_last(connection_paths); + path = l->data; + } + + return path; +} + static DBusHandlerResult remove_path(DBusConnection *conn, DBusMessage *msg, GSList **list, const char *sname) @@ -163,10 +185,17 @@ static DBusHandlerResult remove_path(DBusConnection *conn, /* Remove references from the storage */ if (*list == connection_paths) { - if (connection_has_pending (conn, path)) + if (connection_has_pending(conn, path)) return err_failed(conn, msg, "Connection is Busy"); connection_remove_stored(conn, path); + /* Reset default connection */ + if (l == g_slist_nth(*list, default_index)) { + const char *dpath; + + dpath = last_connection_used(conn); + connection_store(conn, dpath, TRUE); + } } else server_remove_stored(conn, path); @@ -251,7 +280,7 @@ static void pan_record_reply(DBusPendingCall *call, void *data) goto fail; } - connection_store(pr->conn, pr->path); + connection_store(pr->conn, pr->path, FALSE); connection_paths = g_slist_append(connection_paths, g_strdup(pr->path)); create_path(pr->conn, pr->msg, pr->path, "ConnectionCreated"); @@ -401,7 +430,7 @@ static DBusHandlerResult create_server(DBusConnection *conn, if ((id != BNEP_SVC_GN) && (id != BNEP_SVC_NAP)) return err_invalid_args(conn, msg, "Not supported"); - snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/server/%s%d", + snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/%s%d", bnep_name(id), net_uid++); if (g_slist_find_custom(server_paths, path, @@ -480,6 +509,24 @@ static DBusHandlerResult list_connections(DBusConnection *conn, return list_paths(conn, msg, connection_paths); } +static GSList * find_connection_pattern(DBusConnection *conn, + const char *pattern) +{ + const char *path; + GSList *list; + + if (pattern == NULL) + return NULL; + + for (list = connection_paths; list; list = list->next) { + path = (const char *) list->data; + if (connection_find_data(conn, path, pattern) == 0) + break; + } + + return list; +} + static DBusHandlerResult find_connection(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -498,17 +545,15 @@ static DBusHandlerResult find_connection(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } - for (list = connection_paths; list; list = list->next) { - path = (const char *) list->data; - if (connection_find_data(conn, path, pattern) == 0) - break; - } + list = find_connection_pattern(conn, pattern); if (list == NULL) { err_failed(conn, msg, "No such connection"); return DBUS_HANDLER_RESULT_HANDLED; } + path = list->data; + reply = dbus_message_new_method_return(msg); if (!reply) return DBUS_HANDLER_RESULT_NEED_MEMORY; @@ -588,6 +633,118 @@ static DBusHandlerResult remove_connection(DBusConnection *conn, return remove_path(conn, msg, &connection_paths, "ConnectionRemoved"); } +static DBusHandlerResult last_connection(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + const char *path; + DBusMessage *reply; + + if (connection_paths == NULL || + g_slist_length (connection_paths) == 0) { + err_does_not_exist(conn, msg, "No such connection"); + return DBUS_HANDLER_RESULT_HANDLED; + } + + path = last_connection_used(conn); + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_message_append_args(reply, DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); + + return send_message_and_unref(conn, reply); +} + +static DBusHandlerResult default_connection(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + const char *path; + DBusMessage *reply; + + if (connection_paths == NULL || + g_slist_length (connection_paths) == 0) { + err_does_not_exist(conn, msg, "No such connection"); + return DBUS_HANDLER_RESULT_HANDLED; + } + + path = g_slist_nth_data (connection_paths, default_index); + + if (path == NULL) { + path = last_connection_used(conn); + connection_store(conn, path, TRUE); + } + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_message_append_args(reply, DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); + + return send_message_and_unref(conn, reply); +} + +static DBusHandlerResult change_default_connection(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + const char *path; + const char *pattern; + DBusMessage *reply; + DBusError derr; + GSList *list; + + dbus_error_init(&derr); + if (!dbus_message_get_args(msg, &derr, + DBUS_TYPE_STRING, &pattern, + DBUS_TYPE_INVALID)) { + err_invalid_args(conn, msg, derr.message); + dbus_error_free(&derr); + return DBUS_HANDLER_RESULT_HANDLED; + } + + if (connection_paths == NULL || + g_slist_length (connection_paths) == 0) { + err_does_not_exist(conn, msg, "No such connection"); + return DBUS_HANDLER_RESULT_HANDLED; + } + + list = g_slist_find_custom(connection_paths, pattern, (GCompareFunc) strcmp); + + /* Find object path via pattern */ + if (list == NULL) { + list = find_connection_pattern(conn, pattern); + + if (list == NULL) { + err_failed(conn, msg, "No such connection"); + return DBUS_HANDLER_RESULT_HANDLED; + } + else + path = list->data; + } + else + path = list->data; + + default_index = g_slist_position (connection_paths, list); + connection_store(connection, path, TRUE); + + dbus_connection_emit_signal(connection, NETWORK_PATH, + NETWORK_MANAGER_INTERFACE, + "DefaultConnectionChanged", + DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + dbus_message_append_args(reply, DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); + + return send_message_and_unref(conn, reply); +} + static void manager_unregister(DBusConnection *conn, void *data) { info("Unregistered manager path"); @@ -674,16 +831,77 @@ static void parse_stored_connection(char *key, char *value, void *data) g_free(name); } -static void register_stored(void) +static void register_connections_stored(const char *adapter) +{ + char filename[PATH_MAX + 1]; + char *pattern; + struct stat s; + GSList *list; + bdaddr_t src; + bdaddr_t default_src; + int dev_id; + + create_name(filename, PATH_MAX, STORAGEDIR, adapter, "network"); + + str2ba(adapter, &src); + + bacpy(&default_src, BDADDR_ANY); + dev_id = hci_get_route(NULL); + if (dev_id < 0) + hci_devba(dev_id, &default_src); + + if (stat (filename, &s) == 0 && (s.st_mode & __S_IFREG)) { + textfile_foreach(filename, parse_stored_connection, &src); + pattern = textfile_get(filename, "default"); + + list = find_connection_pattern(connection, pattern); + if (list != NULL) + default_index = g_slist_position(connection_paths, list); + else if (bacmp(&src, &default_src) == 0) { + list = g_slist_last(connection_paths); + if (list == NULL) + return; + default_index = g_slist_position(connection_paths, list); + connection_store(connection, list->data, TRUE); + } + } +} + +static void register_servers_stored(const char *adapter, const char *profile) { - char dirname[PATH_MAX + 1]; char filename[PATH_MAX + 1]; char path[MAX_PATH_LENGTH]; - struct dirent *de; - DIR *dir; + const char *ppath = path; + uint16_t id; struct stat s; bdaddr_t src; + if (strcmp(profile, "nap") == 0) + id = BNEP_SVC_NAP; + else + id = BNEP_SVC_GN; + + create_name(filename, PATH_MAX, STORAGEDIR, adapter, profile); + + str2ba(adapter, &src); + + if (stat (filename, &s) == 0 && (s.st_mode & __S_IFREG)) { + snprintf(path, MAX_PATH_LENGTH, + NETWORK_PATH"/%s%d", profile, net_uid++); + if (server_register_from_file(connection, path, + &src, id, filename) == 0) { + server_paths = g_slist_append(server_paths, + g_strdup(path)); + } + } +} + +static void register_stored(void) +{ + char dirname[PATH_MAX + 1]; + struct dirent *de; + DIR *dir; + snprintf(dirname, PATH_MAX, "%s", STORAGEDIR); dir = opendir(dirname); @@ -695,56 +913,13 @@ static void register_stored(void) continue; /* Connection objects */ - create_name(filename, PATH_MAX, STORAGEDIR, - de->d_name, "network"); - - str2ba(de->d_name, &src); - - - if (stat (filename, &s) == 0 && (s.st_mode & __S_IFREG)) - textfile_foreach(filename, parse_stored_connection, &src); + register_connections_stored(de->d_name); /* NAP objects */ - create_name(filename, PATH_MAX, STORAGEDIR, de->d_name, "nap"); - if (stat (filename, &s) == 0 && (s.st_mode & __S_IFREG)) { - snprintf(path, MAX_PATH_LENGTH, - NETWORK_PATH"/server/nap%d", net_uid++); - - if (server_register_from_file(connection, path, - &src, BNEP_SVC_NAP, filename) == 0) { - server_paths = g_slist_append(server_paths, - g_strdup(path)); - - dbus_connection_emit_signal(connection, - NETWORK_PATH, - NETWORK_MANAGER_INTERFACE, - "ServerCreated", - DBUS_TYPE_STRING, - &path, - DBUS_TYPE_INVALID); - } - } + register_servers_stored(de->d_name, "nap"); /* GN objects */ - create_name(filename, PATH_MAX, STORAGEDIR, de->d_name, "gn"); - if (stat (filename, &s) == 0 && (s.st_mode & __S_IFREG)) { - snprintf(path, MAX_PATH_LENGTH, - NETWORK_PATH"/server/gn%d", net_uid++); - - if (server_register_from_file(connection, path, - &src, BNEP_SVC_GN, filename) == 0) { - server_paths = g_slist_append(server_paths, - g_strdup(path)); - - dbus_connection_emit_signal(connection, - NETWORK_PATH, - NETWORK_MANAGER_INTERFACE, - "ServerCreated", - DBUS_TYPE_STRING, - &path, - DBUS_TYPE_INVALID); - } - } + register_servers_stored(de->d_name, "gn"); } closedir(dir); @@ -759,6 +934,9 @@ static DBusMethodVTable manager_methods[] = { { "FindConnection", find_connection, "s", "s" }, { "CreateConnection", create_connection, "ss", "s" }, { "RemoveConnection", remove_connection, "s", "" }, + { "LastConnection", last_connection, "", "s" }, + { "DefaultConnection", default_connection, "", "s" }, + { "ChangeDefaultConnection", change_default_connection, "s", "s"}, { NULL, NULL, NULL, NULL } }; @@ -767,6 +945,7 @@ static DBusSignalVTable manager_signals[] = { { "ServerRemoved", "s" }, { "ConnectionCreated", "s" }, { "ConnectionRemoved", "s" }, + { "DefaultConnectionChanged", "s" }, { NULL, NULL } }; diff --git a/network/network-api.txt b/network/network-api.txt index 9bdf5ca8..9a18085e 100644 --- a/network/network-api.txt +++ b/network/network-api.txt @@ -64,6 +64,25 @@ Methods string CreateServer(string uuid) Possible errors:org.bluez.network.Error.DoesNotExist org.bluez.network.Error.Failed + string LastConnection() + + Returns last connected connection path, if none is connected + fallback to last created connection. + + Possible errors:org.bluez.network.Error.DoesNotExist + + string DefaultConnection() + + Returns default connection path. + + Possible errors:org.bluez.network.Error.DoesNotExist + + string ChangeDefaultConnection(string pattern) + + Changes default connection path. + + Possible errors:org.bluez.network.Error.DoesNotExist + Signals void ServerCreated(string path) @@ -74,6 +93,8 @@ Signals void ConnectionRemoved(string path) + void DefaultConnectionChanged(string path) + Network Server hierarchy (experimental) ======================================= -- cgit From 07ae0be088425610ecdb201dc9c047ba95a73d4c Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Thu, 17 May 2007 19:52:32 +0000 Subject: Prevent use of missing function in eglib. --- network/manager.c | 82 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 60 insertions(+), 22 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 6d7654f9..81133b2e 100644 --- a/network/manager.c +++ b/network/manager.c @@ -146,15 +146,22 @@ static const char * last_connection_used(DBusConnection *conn) GSList *l; int i; + l = connection_paths; for (i = g_slist_length (connection_paths) -1; i > -1; i--) { - path = g_slist_nth_data (connection_paths, i); + int n = i; + while (n-- > 0 && l) + l = l->next; + + path = l ? l->data : NULL; if (connection_is_connected (conn, path)) break; } /* No connection connected fallback to last connection */ if (i == -1) { - l = g_slist_last(connection_paths); + l = connection_paths; + while (l->next) + l = l->next; path = l->data; } @@ -185,12 +192,20 @@ static DBusHandlerResult remove_path(DBusConnection *conn, /* Remove references from the storage */ if (*list == connection_paths) { + GSList *l_default; + int n; + if (connection_has_pending(conn, path)) return err_failed(conn, msg, "Connection is Busy"); connection_remove_stored(conn, path); + /* Reset default connection */ - if (l == g_slist_nth(*list, default_index)) { + n = default_index; + l_default = connection_paths; + while (n-- > 0 && l_default) + l_default = l_default->next; + if (l == l_default) { const char *dpath; dpath = last_connection_used(conn); @@ -662,6 +677,8 @@ static DBusHandlerResult default_connection(DBusConnection *conn, { const char *path; DBusMessage *reply; + GSList *link; + int n; if (connection_paths == NULL || g_slist_length (connection_paths) == 0) { @@ -669,7 +686,12 @@ static DBusHandlerResult default_connection(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } - path = g_slist_nth_data (connection_paths, default_index); + link = connection_paths; + n = default_index; + while (n-- > 0 && link) + link = link->next; + + path = link ? link->data : NULL; if (path == NULL) { path = last_connection_used(conn); @@ -686,6 +708,22 @@ static DBusHandlerResult default_connection(DBusConnection *conn, return send_message_and_unref(conn, reply); } +static void default_position(GSList *link) +{ + GSList *list; + int i = 0; + + list = connection_paths; + while (list) { + if (list == link) { + default_index = i; + break; + } + i++; + list = list->next; + } +} + static DBusHandlerResult change_default_connection(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -693,7 +731,7 @@ static DBusHandlerResult change_default_connection(DBusConnection *conn, const char *pattern; DBusMessage *reply; DBusError derr; - GSList *list; + GSList *link; dbus_error_init(&derr); if (!dbus_message_get_args(msg, &derr, @@ -710,24 +748,23 @@ static DBusHandlerResult change_default_connection(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } - list = g_slist_find_custom(connection_paths, pattern, (GCompareFunc) strcmp); + link = g_slist_find_custom(connection_paths, pattern, (GCompareFunc) strcmp); /* Find object path via pattern */ - if (list == NULL) { - list = find_connection_pattern(conn, pattern); + if (link == NULL) { + link = find_connection_pattern(conn, pattern); - if (list == NULL) { + if (link == NULL) { err_failed(conn, msg, "No such connection"); return DBUS_HANDLER_RESULT_HANDLED; } else - path = list->data; + path = link->data; } else - path = list->data; + path = link->data; - default_index = g_slist_position (connection_paths, list); - connection_store(connection, path, TRUE); + default_position(link); dbus_connection_emit_signal(connection, NETWORK_PATH, NETWORK_MANAGER_INTERFACE, @@ -836,7 +873,7 @@ static void register_connections_stored(const char *adapter) char filename[PATH_MAX + 1]; char *pattern; struct stat s; - GSList *list; + GSList *link; bdaddr_t src; bdaddr_t default_src; int dev_id; @@ -854,15 +891,17 @@ static void register_connections_stored(const char *adapter) textfile_foreach(filename, parse_stored_connection, &src); pattern = textfile_get(filename, "default"); - list = find_connection_pattern(connection, pattern); - if (list != NULL) - default_index = g_slist_position(connection_paths, list); + link = find_connection_pattern(connection, pattern); + if (link != NULL) + default_position(link); else if (bacmp(&src, &default_src) == 0) { - list = g_slist_last(connection_paths); - if (list == NULL) + link = connection_paths; + while (link->next) + link = link->next; + if (link == NULL) return; - default_index = g_slist_position(connection_paths, list); - connection_store(connection, list->data, TRUE); + default_position(link); + connection_store(connection, link->data, TRUE); } } } @@ -871,7 +910,6 @@ static void register_servers_stored(const char *adapter, const char *profile) { char filename[PATH_MAX + 1]; char path[MAX_PATH_LENGTH]; - const char *ppath = path; uint16_t id; struct stat s; bdaddr_t src; -- cgit From 00a7a482ac18b339a311c0afb89741d6b3978f0e Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 18 May 2007 18:05:16 +0000 Subject: Revert changes of missing GSList functions. --- network/manager.c | 83 +++++++++++++++---------------------------------------- 1 file changed, 22 insertions(+), 61 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 81133b2e..c27d01c5 100644 --- a/network/manager.c +++ b/network/manager.c @@ -146,22 +146,15 @@ static const char * last_connection_used(DBusConnection *conn) GSList *l; int i; - l = connection_paths; for (i = g_slist_length (connection_paths) -1; i > -1; i--) { - int n = i; - while (n-- > 0 && l) - l = l->next; - - path = l ? l->data : NULL; - if (connection_is_connected (conn, path)) + path = g_slist_nth_data (connection_paths, i); + if (connection_is_connected(conn, path)) break; } /* No connection connected fallback to last connection */ if (i == -1) { - l = connection_paths; - while (l->next) - l = l->next; + l = g_slist_last(connection_paths); path = l->data; } @@ -192,20 +185,12 @@ static DBusHandlerResult remove_path(DBusConnection *conn, /* Remove references from the storage */ if (*list == connection_paths) { - GSList *l_default; - int n; - if (connection_has_pending(conn, path)) return err_failed(conn, msg, "Connection is Busy"); connection_remove_stored(conn, path); - /* Reset default connection */ - n = default_index; - l_default = connection_paths; - while (n-- > 0 && l_default) - l_default = l_default->next; - if (l == l_default) { + if (l == g_slist_nth(*list, default_index)) { const char *dpath; dpath = last_connection_used(conn); @@ -677,8 +662,6 @@ static DBusHandlerResult default_connection(DBusConnection *conn, { const char *path; DBusMessage *reply; - GSList *link; - int n; if (connection_paths == NULL || g_slist_length (connection_paths) == 0) { @@ -686,12 +669,7 @@ static DBusHandlerResult default_connection(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } - link = connection_paths; - n = default_index; - while (n-- > 0 && link) - link = link->next; - - path = link ? link->data : NULL; + path = g_slist_nth_data (connection_paths, default_index); if (path == NULL) { path = last_connection_used(conn); @@ -708,22 +686,6 @@ static DBusHandlerResult default_connection(DBusConnection *conn, return send_message_and_unref(conn, reply); } -static void default_position(GSList *link) -{ - GSList *list; - int i = 0; - - list = connection_paths; - while (list) { - if (list == link) { - default_index = i; - break; - } - i++; - list = list->next; - } -} - static DBusHandlerResult change_default_connection(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -731,7 +693,7 @@ static DBusHandlerResult change_default_connection(DBusConnection *conn, const char *pattern; DBusMessage *reply; DBusError derr; - GSList *link; + GSList *list; dbus_error_init(&derr); if (!dbus_message_get_args(msg, &derr, @@ -748,23 +710,24 @@ static DBusHandlerResult change_default_connection(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } - link = g_slist_find_custom(connection_paths, pattern, (GCompareFunc) strcmp); + list = g_slist_find_custom(connection_paths, pattern, (GCompareFunc) strcmp); /* Find object path via pattern */ - if (link == NULL) { - link = find_connection_pattern(conn, pattern); + if (list == NULL) { + list = find_connection_pattern(conn, pattern); - if (link == NULL) { + if (list == NULL) { err_failed(conn, msg, "No such connection"); return DBUS_HANDLER_RESULT_HANDLED; } else - path = link->data; + path = list->data; } else - path = link->data; + path = list->data; - default_position(link); + default_index = g_slist_position (connection_paths, list); + connection_store(connection, path, TRUE); dbus_connection_emit_signal(connection, NETWORK_PATH, NETWORK_MANAGER_INTERFACE, @@ -873,7 +836,7 @@ static void register_connections_stored(const char *adapter) char filename[PATH_MAX + 1]; char *pattern; struct stat s; - GSList *link; + GSList *list; bdaddr_t src; bdaddr_t default_src; int dev_id; @@ -891,17 +854,15 @@ static void register_connections_stored(const char *adapter) textfile_foreach(filename, parse_stored_connection, &src); pattern = textfile_get(filename, "default"); - link = find_connection_pattern(connection, pattern); - if (link != NULL) - default_position(link); + list = find_connection_pattern(connection, pattern); + if (list != NULL) + default_index = g_slist_position(connection_paths, list); else if (bacmp(&src, &default_src) == 0) { - link = connection_paths; - while (link->next) - link = link->next; - if (link == NULL) + list = g_slist_last(connection_paths); + if (list == NULL) return; - default_position(link); - connection_store(connection, link->data, TRUE); + default_index = g_slist_position(connection_paths, list); + connection_store(connection, list->data, TRUE); } } } -- cgit From b93e2bf23ca82984b2a5dea852b02967fc33ca3c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 22 May 2007 07:05:28 +0000 Subject: Update test script with last PANU connection --- network/network-api.txt | 14 +++++++------- network/test-network | 6 ++++++ 2 files changed, 13 insertions(+), 7 deletions(-) (limited to 'network') diff --git a/network/network-api.txt b/network/network-api.txt index 9a18085e..f925bc18 100644 --- a/network/network-api.txt +++ b/network/network-api.txt @@ -50,8 +50,8 @@ Methods string CreateServer(string uuid) Removes a network connection object for a given path. - Possible errors:org.bluez.network.Error.DoesNotExist - org.bluez.network.Error.Failed + Possible errors: org.bluez.network.Error.DoesNotExist + org.bluez.network.Error.Failed array{string} ListConnections() @@ -61,27 +61,27 @@ Methods string CreateServer(string uuid) Returns connection path. - Possible errors:org.bluez.network.Error.DoesNotExist - org.bluez.network.Error.Failed + Possible errors: org.bluez.network.Error.DoesNotExist + org.bluez.network.Error.Failed string LastConnection() Returns last connected connection path, if none is connected fallback to last created connection. - Possible errors:org.bluez.network.Error.DoesNotExist + Possible errors: org.bluez.network.Error.DoesNotExist string DefaultConnection() Returns default connection path. - Possible errors:org.bluez.network.Error.DoesNotExist + Possible errors: org.bluez.network.Error.DoesNotExist string ChangeDefaultConnection(string pattern) Changes default connection path. - Possible errors:org.bluez.network.Error.DoesNotExist + Possible errors: org.bluez.network.Error.DoesNotExist Signals diff --git a/network/test-network b/network/test-network index fe83cd21..3719deaa 100755 --- a/network/test-network +++ b/network/test-network @@ -23,3 +23,9 @@ try: 'org.bluez.network.Server') except: pass + +try: + panu = dbus.Interface(bus.get_object(conn, network.LastConnection()), + 'org.bluez.network.Connection') +except: + pass -- cgit From c70e57f5b9bf450aeb039d558e85fe0b1fab41d9 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 22 May 2007 13:00:25 +0000 Subject: Fix some documentation problems. --- network/network-api.txt | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'network') diff --git a/network/network-api.txt b/network/network-api.txt index f925bc18..c2d45da8 100644 --- a/network/network-api.txt +++ b/network/network-api.txt @@ -20,6 +20,7 @@ Methods string CreateServer(string uuid) org.bluez.network.Error.Failed void RemoveServer(string path) + Removes the network server object for given path. Possible errors: org.bluez.network.Error.DoesNotExist @@ -83,9 +84,7 @@ Methods string CreateServer(string uuid) Possible errors: org.bluez.network.Error.DoesNotExist -Signals - - void ServerCreated(string path) +Signals void ServerCreated(string path) void ServerRemoved(string path) @@ -148,7 +147,6 @@ Methods string GetUUID() Returns the server properties. - Signals void Enabled() void Disabled() -- 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/manager.c | 110 ++++++++++++++++++++++-------------------------------- network/manager.h | 3 ++ network/server.c | 104 +++++++++++++++++++++++++-------------------------- network/server.h | 3 +- 4 files changed, 99 insertions(+), 121 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index c27d01c5..148dd444 100644 --- a/network/manager.c +++ b/network/manager.c @@ -45,7 +45,6 @@ #include "logging.h" #include "textfile.h" -#define NETWORK_PATH "/org/bluez/network" #define NETWORK_MANAGER_INTERFACE "org.bluez.network.Manager" #include "error.h" @@ -55,8 +54,6 @@ #include "connection.h" #include "common.h" -#define MAX_PATH_LENGTH 64 /* D-Bus path */ - struct pending_reply { DBusConnection *conn; DBusMessage *msg; @@ -197,8 +194,6 @@ static DBusHandlerResult remove_path(DBusConnection *conn, connection_store(conn, dpath, TRUE); } } - else - server_remove_stored(conn, path); g_free(l->data); *list = g_slist_remove(*list, l->data); @@ -407,57 +402,6 @@ static DBusHandlerResult list_servers(DBusConnection *conn, DBusMessage *msg, return list_paths(conn, msg, server_paths); } -static DBusHandlerResult create_server(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - char path[MAX_PATH_LENGTH]; - DBusError derr; - const char *str; - bdaddr_t src; - uint16_t id; - int dev_id; - - dbus_error_init(&derr); - if (!dbus_message_get_args(msg, &derr, - DBUS_TYPE_STRING, &str, - DBUS_TYPE_INVALID)) { - err_invalid_args(conn, msg, derr.message); - dbus_error_free(&derr); - return DBUS_HANDLER_RESULT_HANDLED; - } - - id = bnep_service_id(str); - if ((id != BNEP_SVC_GN) && (id != BNEP_SVC_NAP)) - return err_invalid_args(conn, msg, "Not supported"); - - snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/%s%d", - bnep_name(id), net_uid++); - - if (g_slist_find_custom(server_paths, path, - (GCompareFunc) strcmp)) { - err_already_exists(conn, msg, "Server Already exists"); - return DBUS_HANDLER_RESULT_HANDLED; - } - - bacpy(&src, BDADDR_ANY); - - dev_id = hci_get_route(NULL); - - if (dev_id >= 0) - hci_devba(dev_id, &src); - - if (server_register(conn, path, &src, id) < 0) - return err_failed(conn, msg, - "D-Bus path registration failed"); - - if (bacmp(&src, BDADDR_ANY) != 0) - server_store(conn, path); - - server_paths = g_slist_append(server_paths, g_strdup(path)); - - return create_path(conn, msg, path, "ServerCreated"); -} - static DBusHandlerResult find_server(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -497,12 +441,6 @@ static DBusHandlerResult find_server(DBusConnection *conn, return send_message_and_unref(conn, reply); } -static DBusHandlerResult remove_server(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - return remove_path(conn, msg, &server_paths, "ServerRemoved"); -} - static DBusHandlerResult list_connections(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -867,6 +805,34 @@ static void register_connections_stored(const char *adapter) } } +static void register_server(uint16_t id) +{ + char path[MAX_PATH_LENGTH]; + bdaddr_t src; + int dev_id; + + snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/%s", bnep_name(id)); + + if (g_slist_find_custom(server_paths, path, + (GCompareFunc) strcmp)) + return; + + bacpy(&src, BDADDR_ANY); + + dev_id = hci_get_route(NULL); + + if (dev_id >= 0) + hci_devba(dev_id, &src); + + if (server_register(connection, path, &src, id) < 0) + return; + + if (bacmp(&src, BDADDR_ANY) != 0) + server_store(connection, path); + + server_paths = g_slist_append(server_paths, g_strdup(path)); +} + static void register_servers_stored(const char *adapter, const char *profile) { char filename[PATH_MAX + 1]; @@ -877,8 +843,10 @@ static void register_servers_stored(const char *adapter, const char *profile) if (strcmp(profile, "nap") == 0) id = BNEP_SVC_NAP; - else + else if (strcmp(profile, "gn") == 0) id = BNEP_SVC_GN; + else + id = BNEP_SVC_PANU; create_name(filename, PATH_MAX, STORAGEDIR, adapter, profile); @@ -886,7 +854,7 @@ static void register_servers_stored(const char *adapter, const char *profile) if (stat (filename, &s) == 0 && (s.st_mode & __S_IFREG)) { snprintf(path, MAX_PATH_LENGTH, - NETWORK_PATH"/%s%d", profile, net_uid++); + NETWORK_PATH"/%s", profile); if (server_register_from_file(connection, path, &src, id, filename) == 0) { server_paths = g_slist_append(server_paths, @@ -919,6 +887,9 @@ static void register_stored(void) /* GN objects */ register_servers_stored(de->d_name, "gn"); + + /* PANU objects */ + register_servers_stored(de->d_name, "panu"); } closedir(dir); @@ -926,9 +897,7 @@ static void register_stored(void) static DBusMethodVTable manager_methods[] = { { "ListServers", list_servers, "", "as" }, - { "CreateServer", create_server, "s", "s" }, { "FindServer", find_server, "s", "s" }, - { "RemoveServer", remove_server, "s", "" }, { "ListConnections", list_connections, "", "as" }, { "FindConnection", find_connection, "s", "s" }, { "CreateConnection", create_connection, "ss", "s" }, @@ -985,6 +954,15 @@ int network_init(DBusConnection *conn) register_stored(); + /* PAN user server */ + register_server(BNEP_SVC_PANU); + + /* Group Network server */ + register_server(BNEP_SVC_GN); + + /* Network Access Point server */ + register_server(BNEP_SVC_NAP); + return 0; } diff --git a/network/manager.h b/network/manager.h index d20b8dbd..9ad1009e 100644 --- a/network/manager.h +++ b/network/manager.h @@ -21,6 +21,9 @@ * */ +#define MAX_PATH_LENGTH 64 /* D-Bus path */ +#define NETWORK_PATH "/org/bluez/network" + int network_init(DBusConnection *conn); void network_exit(void); 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, diff --git a/network/server.h b/network/server.h index ff754711..fb6debdf 100644 --- a/network/server.h +++ b/network/server.h @@ -21,12 +21,13 @@ * */ + int server_register(DBusConnection *conn, const char *path, bdaddr_t *src, uint16_t id); int server_register_from_file(DBusConnection *conn, const char *path, const bdaddr_t *src, uint16_t id, const char *filename); int server_store(DBusConnection *conn, const char *path); -int server_remove_stored(DBusConnection *conn, const char *path); + int server_find_data(DBusConnection *conn, const char *path, const char *pattern); -- cgit From 5162283fd17b02c1ea0635b12a72f3bdc17891b8 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 16 Aug 2007 18:03:01 +0000 Subject: Small header cleanups --- network/error.c | 3 +++ network/error.h | 3 --- network/server.h | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'network') diff --git a/network/error.c b/network/error.c index 8fcccd32..43f10af3 100644 --- a/network/error.c +++ b/network/error.c @@ -25,6 +25,9 @@ #include #endif +#include + +#include "dbus.h" #include "error.h" #define NETWORK_ERROR_INTERFACE "org.bluez.network.Error" diff --git a/network/error.h b/network/error.h index 3022e392..b62d4796 100644 --- a/network/error.h +++ b/network/error.h @@ -21,8 +21,6 @@ * */ -#include "dbus.h" - DBusHandlerResult err_unknown_connection(DBusConnection *conn, DBusMessage *msg); DBusHandlerResult err_does_not_exist(DBusConnection *conn, @@ -37,4 +35,3 @@ DBusHandlerResult err_invalid_args(DBusConnection *conn, DBusHandlerResult err_not_supported(DBusConnection *conn, DBusMessage *msg); DBusHandlerResult err_already_exists(DBusConnection *conn, DBusMessage *msg, const char *str); - diff --git a/network/server.h b/network/server.h index fb6debdf..5765e42e 100644 --- a/network/server.h +++ b/network/server.h @@ -21,7 +21,6 @@ * */ - int server_register(DBusConnection *conn, const char *path, bdaddr_t *src, uint16_t id); int server_register_from_file(DBusConnection *conn, const char *path, -- cgit From 7715eed6e31bcd616ff663073c1d2480e199adf5 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 24 Aug 2007 18:35:07 +0000 Subject: network: removed unused signals(ServerCreated and ServerRemoved) --- network/manager.c | 2 -- network/network-api.txt | 6 +----- 2 files changed, 1 insertion(+), 7 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 148dd444..418f474b 100644 --- a/network/manager.c +++ b/network/manager.c @@ -909,8 +909,6 @@ static DBusMethodVTable manager_methods[] = { }; static DBusSignalVTable manager_signals[] = { - { "ServerCreated", "s" }, - { "ServerRemoved", "s" }, { "ConnectionCreated", "s" }, { "ConnectionRemoved", "s" }, { "DefaultConnectionChanged", "s" }, diff --git a/network/network-api.txt b/network/network-api.txt index c2d45da8..1c689093 100644 --- a/network/network-api.txt +++ b/network/network-api.txt @@ -84,11 +84,7 @@ Methods string CreateServer(string uuid) Possible errors: org.bluez.network.Error.DoesNotExist -Signals void ServerCreated(string path) - - void ServerRemoved(string path) - - void ConnectionCreated(string path) +Signals void ConnectionCreated(string path) void ConnectionRemoved(string path) -- cgit From 558c8c359bdbac0804207d41460b25ea33305195 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 24 Aug 2007 18:38:09 +0000 Subject: network: removed CreateServer/RemoveServer methods --- network/network-api.txt | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) (limited to 'network') diff --git a/network/network-api.txt b/network/network-api.txt index 1c689093..543b27be 100644 --- a/network/network-api.txt +++ b/network/network-api.txt @@ -10,23 +10,7 @@ Network Manager hierarchy Interface org.bluez.network.Manager Object path /org/bluez/network -Methods string CreateServer(string uuid) - - Creates a network server object (GN or NAP). - - Possible errors: org.bluez.network.Error.AlreadyExists - org.bluez.network.Error.NotSupported - org.bluez.network.Error.ConnectionAttemptFailed - org.bluez.network.Error.Failed - - void RemoveServer(string path) - - Removes the network server object for given path. - - Possible errors: org.bluez.network.Error.DoesNotExist - org.bluez.network.Error.Failed - - array{string} ListServers() +Methods array{string} ListServers() Returns an array of available network devices paths. Currently only NAP and GN are supported. -- 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') 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') 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/manager.c | 2 ++ network/server.c | 39 ++++++++++++++++++++------------------- 2 files changed, 22 insertions(+), 19 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 418f474b..0ac6228f 100644 --- a/network/manager.c +++ b/network/manager.c @@ -310,6 +310,7 @@ static int get_record(struct pending_reply *pr, uint32_t handle, if (dbus_connection_send_with_reply(pr->conn, msg, &pending, -1) == FALSE) { error("Can't send D-Bus message."); + dbus_message_unref(msg); return -1; } @@ -386,6 +387,7 @@ static int get_handles(struct pending_reply *pr, if (dbus_connection_send_with_reply(pr->conn, msg, &pending, -1) == FALSE) { error("Can't send D-Bus message."); + dbus_message_unref(msg); return -1; } 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') 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') 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') 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') 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') 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') 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 1b9cc018822ca0edde9d0485c382a13a90253e43 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 29 Aug 2007 17:50:49 +0000 Subject: network: concat remote name and service name to the connection name --- network/common.c | 19 +++++++++++++++++++ network/common.h | 2 ++ network/manager.c | 17 +++++++++++------ 3 files changed, 32 insertions(+), 6 deletions(-) (limited to 'network') diff --git a/network/common.c b/network/common.c index 0a11d306..d818829a 100644 --- a/network/common.c +++ b/network/common.c @@ -40,6 +40,7 @@ #include "logging.h" #include "common.h" +#include "textfile.h" static int ctl; @@ -204,3 +205,21 @@ int bnep_if_up(const char *devname, int up) return 0; } + +int read_remote_name(bdaddr_t *src, bdaddr_t *dst, char *buf, size_t size) +{ + char filename[PATH_MAX + 1], addr[18], *str; + + ba2str(src, addr); + create_name(filename, PATH_MAX, STORAGEDIR, addr, "names"); + + ba2str(dst, addr); + str = textfile_get(filename, addr); + if (!str) + return -ENOENT; + + snprintf(buf, size, "%s", str); + free(str); + + return 0; +} diff --git a/network/common.h b/network/common.h index bfbe83d2..1d8b57de 100644 --- a/network/common.h +++ b/network/common.h @@ -33,3 +33,5 @@ int bnep_kill_all_connections(void); int bnep_connadd(int sk, uint16_t role, char *dev); int bnep_if_up(const char *devname, int up); + +int read_remote_name(bdaddr_t *src, bdaddr_t *dst, char *buf, size_t size); diff --git a/network/manager.c b/network/manager.c index 0ac6228f..78d65431 100644 --- a/network/manager.c +++ b/network/manager.c @@ -54,6 +54,8 @@ #include "connection.h" #include "common.h" +#define MAX_NAME_SIZE 256 + struct pending_reply { DBusConnection *conn; DBusMessage *msg; @@ -222,7 +224,7 @@ static void pan_record_reply(DBusPendingCall *call, void *data) uint8_t *rec_bin; sdp_data_t *d; sdp_record_t *rec = NULL; - char *name = NULL, *desc = NULL; + char name[MAX_NAME_SIZE], *desc = NULL; dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { @@ -253,11 +255,16 @@ static void pan_record_reply(DBusPendingCall *call, void *data) rec = sdp_extract_pdu(rec_bin, &scanned); - /* Extract service name from record */ + /* Concat remote name and service name */ + memset(name, 0, MAX_NAME_SIZE); + if (read_remote_name(&pr->src, &pr->dst, name, MAX_NAME_SIZE) < 0) + len = 0; + else + len = strlen(name); + d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY); if (d) { - name = g_new0(char, d->unitSize); - snprintf(name, d->unitSize, "%.*s", + snprintf(name + len, MAX_NAME_SIZE - len, "(%.*s)", d->unitSize, d->val.str); } @@ -281,8 +288,6 @@ static void pan_record_reply(DBusPendingCall *call, void *data) create_path(pr->conn, pr->msg, pr->path, "ConnectionCreated"); fail: - if (name) - g_free(name); if (desc) g_free(desc); -- cgit From c068caff5e03b9a244c40df3b197cb253587162b Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 29 Aug 2007 18:01:27 +0000 Subject: network: CreateConnection - enable PANU to PANU connection --- network/manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 78d65431..26146642 100644 --- a/network/manager.c +++ b/network/manager.c @@ -533,7 +533,7 @@ static DBusHandlerResult create_connection(DBusConnection *conn, } id = bnep_service_id(str); - if ((id != BNEP_SVC_GN) && (id != BNEP_SVC_NAP)) + if (id != BNEP_SVC_GN && id != BNEP_SVC_NAP && id != BNEP_SVC_PANU) return err_invalid_args(conn, msg, "Not supported"); snprintf(key, 32, "%s#%s", addr, bnep_name(id)); -- cgit From 466c2fefdd1b38a47253fadd6cb55a0d8f68152a Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 29 Aug 2007 20:19:00 +0000 Subject: network-api: fixed server paths --- network/network-api.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'network') diff --git a/network/network-api.txt b/network/network-api.txt index 543b27be..542ddf02 100644 --- a/network/network-api.txt +++ b/network/network-api.txt @@ -79,7 +79,7 @@ Network Server hierarchy (experimental) ======================================= Interface org.bluez.network.Server -Object path /org/bluez/network/server* +Object path /org/bluez/network/{gn, nap, panu} Methods string GetUUID() @@ -117,7 +117,7 @@ Methods string GetUUID() void SetSecurity(bool enable) - Enable or disable encryption. + TBD bool GetSecurity() -- 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/manager.c | 26 ++++++---- network/server.c | 146 ++++++++++++++++++++++++------------------------------ network/server.h | 15 +++--- 3 files changed, 87 insertions(+), 100 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 26146642..b571b44b 100644 --- a/network/manager.c +++ b/network/manager.c @@ -429,7 +429,7 @@ static DBusHandlerResult find_server(DBusConnection *conn, for (list = server_paths; list; list = list->next) { path = (const char *) list->data; - if (server_find_data(conn, path, pattern) == 0) + if (server_find_data(path, pattern) == 0) break; } @@ -831,11 +831,11 @@ static void register_server(uint16_t id) if (dev_id >= 0) hci_devba(dev_id, &src); - if (server_register(connection, path, &src, id) < 0) + if (server_register(path, &src, id) < 0) return; if (bacmp(&src, BDADDR_ANY) != 0) - server_store(connection, path); + server_store(path); server_paths = g_slist_append(server_paths, g_strdup(path)); } @@ -862,8 +862,7 @@ static void register_servers_stored(const char *adapter, const char *profile) if (stat (filename, &s) == 0 && (s.st_mode & __S_IFREG)) { snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/%s", profile); - if (server_register_from_file(connection, path, - &src, id, filename) == 0) { + if (server_register_from_file(path, &src, id, filename) == 0) { server_paths = g_slist_append(server_paths, g_strdup(path)); } @@ -937,6 +936,16 @@ int network_init(DBusConnection *conn) return -1; } + /* + * 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 (server_init(conn) < 0) { + return -1; + } + if (!dbus_connection_create_object_path(conn, NETWORK_PATH, NULL, manager_unregister)) { error("D-Bus failed to create %s path", NETWORK_PATH); @@ -959,13 +968,9 @@ int network_init(DBusConnection *conn) register_stored(); - /* PAN user server */ + /* Register PANU, GN and NAP servers if they don't exist */ register_server(BNEP_SVC_PANU); - - /* Group Network server */ register_server(BNEP_SVC_GN); - - /* Network Access Point server */ register_server(BNEP_SVC_NAP); return 0; @@ -973,6 +978,7 @@ int network_init(DBusConnection *conn) void network_exit(void) { + server_exit(); dbus_connection_destroy_object_path(connection, NETWORK_PATH); dbus_connection_unref(connection); 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) diff --git a/network/server.h b/network/server.h index 5765e42e..d96b7ecb 100644 --- a/network/server.h +++ b/network/server.h @@ -20,13 +20,12 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ +int server_init(DBusConnection *conn); +void server_exit(); +int server_register(const char *path, bdaddr_t *src, uint16_t id); +int server_register_from_file(const char *path, const bdaddr_t *src, + uint16_t id, const char *filename); -int server_register(DBusConnection *conn, const char *path, - bdaddr_t *src, uint16_t id); -int server_register_from_file(DBusConnection *conn, const char *path, - const bdaddr_t *src, uint16_t id, const char *filename); +int server_store(const char *path); -int server_store(DBusConnection *conn, const char *path); - -int server_find_data(DBusConnection *conn, const char *path, - const char *pattern); +int server_find_data(const char *path, const char *pattern); -- 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') 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 87bb7258bdf221195d010b0e03cda7cd7c0195b9 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Wed, 29 Aug 2007 21:28:46 +0000 Subject: network: cleanup - unused error --- network/error.c | 9 --------- network/error.h | 2 -- 2 files changed, 11 deletions(-) (limited to 'network') diff --git a/network/error.c b/network/error.c index 43f10af3..24b3d124 100644 --- a/network/error.c +++ b/network/error.c @@ -32,15 +32,6 @@ #define NETWORK_ERROR_INTERFACE "org.bluez.network.Error" -DBusHandlerResult err_unknown_connection(DBusConnection *conn, - DBusMessage *msg) -{ - return send_message_and_unref(conn, - dbus_message_new_error(msg, - NETWORK_ERROR_INTERFACE ".UnknownConnection", - "Unknown connection path")); -} - DBusHandlerResult err_does_not_exist(DBusConnection *conn, DBusMessage *msg, const char *str) { diff --git a/network/error.h b/network/error.h index b62d4796..d4162d5c 100644 --- a/network/error.h +++ b/network/error.h @@ -21,8 +21,6 @@ * */ -DBusHandlerResult err_unknown_connection(DBusConnection *conn, - DBusMessage *msg); DBusHandlerResult err_does_not_exist(DBusConnection *conn, DBusMessage *msg, const char *str); DBusHandlerResult err_failed(DBusConnection *conn, DBusMessage *msg, -- 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') 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') 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 6904a4ec435fb8fc3faa22785ace288a18ed9d32 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 31 Aug 2007 19:25:41 +0000 Subject: network: check if bridge module is loaded --- network/bridge.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'network') diff --git a/network/bridge.c b/network/bridge.c index a6930194..cf77d6ab 100644 --- a/network/bridge.c +++ b/network/bridge.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include #include @@ -39,6 +41,11 @@ static int bridge_socket = -1; int bridge_init(void) { + struct stat st; + + if (stat("/sys/module/bridge", &st) < 0) + return -EOPNOTSUPP; + bridge_socket = socket(AF_INET, SOCK_STREAM, 0); if (bridge_socket < 0) return -errno; -- cgit From 5e4e6d23323b869b36fb02d815dd4b928f94eacb Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 4 Sep 2007 19:51:31 +0000 Subject: Fix connection storage. --- network/manager.c | 47 ++++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index b571b44b..5c619d94 100644 --- a/network/manager.c +++ b/network/manager.c @@ -766,11 +766,6 @@ static void parse_stored_connection(char *key, char *value, void *data) &dst, id, name, ptr) == 0) { char *rpath = g_strdup(path); connection_paths = g_slist_append(connection_paths, rpath); - dbus_connection_emit_signal(connection, NETWORK_PATH, - NETWORK_MANAGER_INTERFACE, - "ConnectionCreated", - DBUS_TYPE_STRING, &rpath, - DBUS_TYPE_INVALID); } g_free(name); @@ -780,7 +775,7 @@ static void register_connections_stored(const char *adapter) { char filename[PATH_MAX + 1]; char *pattern; - struct stat s; + struct stat st; GSList *list; bdaddr_t src; bdaddr_t default_src; @@ -790,26 +785,32 @@ static void register_connections_stored(const char *adapter) str2ba(adapter, &src); + if (stat(filename, &st) < 0) + return; + + if (!(st.st_mode & __S_IFREG)) + return; + + textfile_foreach(filename, parse_stored_connection, &src); + + /* Check default connection for current default adapter */ bacpy(&default_src, BDADDR_ANY); - dev_id = hci_get_route(NULL); + dev_id = hci_get_route(&default_src); if (dev_id < 0) - hci_devba(dev_id, &default_src); + return; - if (stat (filename, &s) == 0 && (s.st_mode & __S_IFREG)) { - textfile_foreach(filename, parse_stored_connection, &src); - pattern = textfile_get(filename, "default"); - - list = find_connection_pattern(connection, pattern); - if (list != NULL) - default_index = g_slist_position(connection_paths, list); - else if (bacmp(&src, &default_src) == 0) { - list = g_slist_last(connection_paths); - if (list == NULL) - return; - default_index = g_slist_position(connection_paths, list); - connection_store(connection, list->data, TRUE); - } - } + hci_devba(dev_id, &default_src); + if (bacmp(&default_src, &src) != 0) + return; + + pattern = textfile_get(filename, "default"); + if (!pattern) + return; + + list = find_connection_pattern(connection, pattern); + if (!list) + return; + default_index = g_slist_position(connection_paths, list); } static void register_server(uint16_t id) -- cgit From df26034b4deb62777d841e04eabe4f8af2c1f41a Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Sep 2007 15:46:41 +0000 Subject: Rely on bridge module autoloading --- network/bridge.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'network') diff --git a/network/bridge.c b/network/bridge.c index cf77d6ab..8ef06190 100644 --- a/network/bridge.c +++ b/network/bridge.c @@ -41,10 +41,12 @@ static int bridge_socket = -1; int bridge_init(void) { +#if 0 struct stat st; if (stat("/sys/module/bridge", &st) < 0) return -EOPNOTSUPP; +#endif bridge_socket = socket(AF_INET, SOCK_STREAM, 0); if (bridge_socket < 0) -- cgit From d474eef5f19a18f6414b042d127582e249953af1 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 13 Sep 2007 15:53:38 +0000 Subject: network: add one space between the remote device name and the service name --- network/manager.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 5c619d94..52e7dd6a 100644 --- a/network/manager.c +++ b/network/manager.c @@ -264,8 +264,12 @@ static void pan_record_reply(DBusPendingCall *call, void *data) d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY); if (d) { - snprintf(name + len, MAX_NAME_SIZE - len, "(%.*s)", - d->unitSize, d->val.str); + if (len) + snprintf(name + len, MAX_NAME_SIZE - len, " (%.*s)", + d->unitSize, d->val.str); + else + snprintf(name, MAX_NAME_SIZE, "%.*s", + d->unitSize, d->val.str); } /* Extract service description from record */ -- cgit From b1490204442e4ebda035d18c529baed048b6b5f5 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 13 Sep 2007 16:15:04 +0000 Subject: Make it look nice --- network/manager.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 52e7dd6a..7bc56142 100644 --- a/network/manager.c +++ b/network/manager.c @@ -264,12 +264,8 @@ static void pan_record_reply(DBusPendingCall *call, void *data) d = sdp_data_get(rec, SDP_ATTR_SVCNAME_PRIMARY); if (d) { - if (len) - snprintf(name + len, MAX_NAME_SIZE - len, " (%.*s)", - d->unitSize, d->val.str); - else - snprintf(name, MAX_NAME_SIZE, "%.*s", - d->unitSize, d->val.str); + snprintf(name + len, MAX_NAME_SIZE - len, + len ? " (%.*s)" : "%.*s", d->unitSize, d->val.str); } /* Extract service description from record */ -- cgit From 0b625c60310de7016f90dbf80c9d02c1b14dc375 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 14 Sep 2007 10:21:07 +0000 Subject: Add network service configuration file --- network/Makefile.am | 2 +- network/network.conf | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 network/network.conf (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index 17869043..c8ca039e 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -23,6 +23,6 @@ AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ @HAL_CFLAGS@ @GLIB_CFLAGS@ INCLUDES = -I$(top_srcdir)/common -EXTRA_DIST = network.service network-api.txt test-network +EXTRA_DIST = network.service network.conf network-api.txt test-network MAINTAINERCLEANFILES = Makefile.in diff --git a/network/network.conf b/network/network.conf new file mode 100644 index 00000000..f3c93bad --- /dev/null +++ b/network/network.conf @@ -0,0 +1,2 @@ +# Configuration file for the network service + -- 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/connection.h | 6 +++ network/main.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++ network/manager.c | 2 - network/manager.h | 11 +++++ network/network.conf | 36 ++++++++++++++++ network/server.c | 1 - network/server.h | 8 ++++ 7 files changed, 178 insertions(+), 3 deletions(-) (limited to 'network') diff --git a/network/connection.h b/network/connection.h index 5561ee32..35726732 100644 --- a/network/connection.h +++ b/network/connection.h @@ -21,6 +21,12 @@ * */ +struct connection_conf { + char *panu_script; + char *gn_script; + char *nap_script; +}; + int connection_register(DBusConnection *conn, const char *path, bdaddr_t *src, bdaddr_t *dst, uint16_t id, const char *name, const char *desc); int connection_store(DBusConnection *conn, const char *path, diff --git a/network/main.c b/network/main.c index 2d9d44b6..5d1f5013 100644 --- a/network/main.c +++ b/network/main.c @@ -41,13 +41,128 @@ #include "manager.h" #include "hal.h" +#define IFACE_PREFIX "bnep%d" +#define PANU_IFACE "pan0" +#define GN_IFACE "pan1" +#define NAP_IFACE "pan2" + static GMainLoop *main_loop; +static struct network_conf conf = { + .connection_enabled = TRUE, + .server_enabled = TRUE, + .iface_prefix = NULL, + .conn.panu_script = NULL, + .conn.gn_script = NULL, + .conn.nap_script = NULL, + .server.panu_iface = NULL, + .server.gn_iface = NULL, + .server.nap_iface = NULL, + .server.disable_security = FALSE +}; + static void sig_term(int sig) { g_main_loop_quit(main_loop); } +static void read_config(const char *file) +{ + GKeyFile *keyfile; + GError *err = NULL; + + keyfile = g_key_file_new(); + + if (!g_key_file_load_from_file(keyfile, file, 0, &err)) { + error("Parsing %s failed: %s", file, err->message); + g_error_free(err); + g_key_file_free(keyfile); + return; + } + + conf.iface_prefix = g_key_file_get_string(keyfile, "Connection", + "InterfacePrefix", &err); + if (!conf.iface_prefix) + conf.iface_prefix = g_strdup(IFACE_PREFIX); + if (err) { + debug("%s: %s", file, err->message); + g_error_free(err); + err = NULL; + } + + conf.conn.panu_script = g_key_file_get_string(keyfile, "Connection", + "PANUScript", &err); + if (err) { + debug("%s: %s", file, err->message); + g_error_free(err); + err = NULL; + } + + conf.conn.gn_script = g_key_file_get_string(keyfile, "Connection", + "GNScript", &err); + if (err) { + debug("%s: %s", file, err->message); + g_error_free(err); + err = NULL; + } + + conf.conn.nap_script = g_key_file_get_string(keyfile, "Connection", + "NAPScript", &err); + if (err) { + debug("%s: %s", file, err->message); + g_error_free(err); + err = NULL; + } + + conf.server.panu_iface = g_key_file_get_string(keyfile, "Server", + "PANUInterface", &err); + if (!conf.server.panu_iface) + conf.server.panu_iface = g_strdup(PANU_IFACE); + if (err) { + debug("%s: %s", file, err->message); + g_error_free(err); + err = NULL; + } + + conf.server.gn_iface = g_key_file_get_string(keyfile, "Server", + "GNInterface", &err); + if (!conf.server.gn_iface) + conf.server.gn_iface = g_strdup(GN_IFACE); + if (err) { + debug("%s: %s", file, err->message); + g_error_free(err); + err = NULL; + } + + conf.server.nap_iface = g_key_file_get_string(keyfile, "Server", + "NAPInterface", &err); + if (!conf.server.nap_iface) + conf.server.nap_iface = g_strdup(NAP_IFACE); + if (err) { + debug("%s: %s", file, err->message); + g_error_free(err); + err = NULL; + } + + conf.server.disable_security = g_key_file_get_boolean(keyfile, "Server", + "DisableSecurity", &err); + if (err) { + debug("%s: %s", file, err->message); + g_error_free(err); + err = NULL; + } + + debug("Config options: InterfacePrefix=%s, PANUScript=%s, GNScript=%s, " + "NAPScript=%s, PANUInterface=%s, GNInterface=%s, " + "NAPInterface=%s, DisableSecurity=%s", conf.iface_prefix, + conf.conn.panu_script, conf.conn.gn_script, conf.conn.nap_script, + conf.server.panu_iface, conf.server.gn_iface, + conf.server.nap_iface, + conf.server.disable_security ? "true" : "false"); + + g_key_file_free(keyfile); +} + int main(int argc, char *argv[]) { DBusConnection *conn; @@ -67,6 +182,8 @@ int main(int argc, char *argv[]) enable_debug(); + read_config(CONFIGDIR "/network.conf"); + main_loop = g_main_loop_new(NULL, FALSE); conn = dbus_bus_system_setup_with_main_loop(NULL, NULL, NULL); diff --git a/network/manager.c b/network/manager.c index 7bc56142..2bf76e03 100644 --- a/network/manager.c +++ b/network/manager.c @@ -50,8 +50,6 @@ #include "error.h" #include "bridge.h" #include "manager.h" -#include "server.h" -#include "connection.h" #include "common.h" #define MAX_NAME_SIZE 256 diff --git a/network/manager.h b/network/manager.h index 9ad1009e..45c7ada4 100644 --- a/network/manager.h +++ b/network/manager.h @@ -21,9 +21,20 @@ * */ +#include "connection.h" +#include "server.h" + #define MAX_PATH_LENGTH 64 /* D-Bus path */ #define NETWORK_PATH "/org/bluez/network" +struct network_conf { + gboolean connection_enabled; + gboolean server_enabled; + char *iface_prefix; + struct connection_conf conn; + struct server_conf server; +}; + int network_init(DBusConnection *conn); void network_exit(void); diff --git a/network/network.conf b/network/network.conf index f3c93bad..66136002 100644 --- a/network/network.conf +++ b/network/network.conf @@ -1,2 +1,38 @@ # Configuration file for the network service +# This section contains options which are not specific to any +# particular interface +[General] + +# If we want to disable support for specific services +# Defaults to supporting all implemented services +#Disable=Connection,Server + +# Network interface name prefix for connections. default:bnep%d +# (up to 16 characters) +InterfacePrefix=bnep%d + +[Connection] + +# PAN user connection interface up script. default: +PANUScript=/usr/sbin/avahi-autoipd + +# Group Network connection interface up script. default: +GNScript=/usr/sbin/avahi-autoipd + +# Network Access Point connection interface up script. default: +NAPScript=/sbin/dhclient + +[Server] + +# Network Interface name for PAN user server. default:pan0 +PANUInterface=pan0 + +# Network Interface name for Group Network server. default:pan1 +GNInterface=pan1 + +# Network Interface name for Network Access Point server. default:pan2 +NAPInterface=pan2 + +# Disable link encryption: default=false +DisableSecurity=false 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 { diff --git a/network/server.h b/network/server.h index d96b7ecb..2b148081 100644 --- a/network/server.h +++ b/network/server.h @@ -20,6 +20,14 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ + +struct server_conf { + char *panu_iface; + char *gn_iface; + char *nap_iface; + gboolean disable_security; +}; + int server_init(DBusConnection *conn); void server_exit(); int server_register(const char *path, bdaddr_t *src, uint16_t id); -- 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/connection.c | 95 +++++++++++++++++++++++++++++++++------------------- network/connection.h | 19 ++++++----- network/main.c | 2 +- network/manager.c | 49 ++++++++++++++++----------- network/manager.h | 2 +- network/server.c | 44 +++++++++++++++++------- network/server.h | 3 +- 7 files changed, 134 insertions(+), 80 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 18bba87c..e6a6c151 100644 --- a/network/connection.c +++ b/network/connection.c @@ -55,14 +55,14 @@ typedef enum { } conn_state; struct network_conn { - DBusConnection *conn; DBusMessage *msg; bdaddr_t src; bdaddr_t dst; char *path; /* D-Bus path */ - char dev[16]; /* BNEP interface name */ - char *name; - char *desc; + char dev[16]; /* Interface name */ + char *name; /* Service Name */ + char *desc; /* Service Description*/ + char *script; /* Interface up script*/ uint16_t id; /* Role: Service Class Identifier */ conn_state state; int sk; @@ -73,15 +73,17 @@ struct __service_16 { uint16_t src; } __attribute__ ((packed)); -static char netdev[16] = "bnep%d"; +static DBusConnection *connection = NULL; +static struct connection_conf *conf = NULL; +static const char *prefix = NULL; static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond, gpointer data) { struct network_conn *nc = data; - if (nc->conn != NULL) { - dbus_connection_emit_signal(nc->conn, nc->path, + if (connection != NULL) { + dbus_connection_emit_signal(connection, nc->path, NETWORK_CONNECTION_INTERFACE, "Disconnected", DBUS_TYPE_INVALID); @@ -89,7 +91,7 @@ static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond, info("%s disconnected", nc->dev); nc->state = DISCONNECTED; memset(nc->dev, 0, 16); - strncpy(nc->dev, netdev, 16); + strncpy(nc->dev, prefix, strlen(prefix)); g_io_channel_close(chan); return FALSE; } @@ -156,7 +158,7 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, } bnep_if_up(nc->dev, TRUE); - dbus_connection_emit_signal(nc->conn, nc->path, + dbus_connection_emit_signal(connection, nc->path, NETWORK_CONNECTION_INTERFACE, "Connected", DBUS_TYPE_INVALID); @@ -166,7 +168,7 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, pdev = nc->dev; dbus_message_append_args(reply, DBUS_TYPE_STRING, &pdev, DBUS_TYPE_INVALID); - send_message_and_unref(nc->conn, reply); + send_message_and_unref(connection, reply); nc->state = CONNECTED; @@ -178,7 +180,7 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, failed: if (nc->state != DISCONNECTED) { nc->state = DISCONNECTED; - err_connection_failed(nc->conn, nc->msg, "bnep failed"); + err_connection_failed(connection, nc->msg, "bnep failed"); g_io_channel_close(chan); } return FALSE; @@ -251,7 +253,7 @@ static gboolean l2cap_connect_cb(GIOChannel *chan, return FALSE; failed: nc->state = DISCONNECTED; - err_connection_failed(nc->conn, nc->msg, strerror(errno)); + err_connection_failed(connection, nc->msg, strerror(errno)); g_io_channel_close(chan); return FALSE; } @@ -597,7 +599,7 @@ static void connection_free(struct network_conn *nc) if (nc->desc) g_free(nc->desc); - + g_free(nc); nc = NULL; } @@ -632,30 +634,27 @@ static DBusSignalVTable connection_signals[] = { { NULL, NULL } }; -int connection_register(DBusConnection *conn, const char *path, bdaddr_t *src, - bdaddr_t *dst, uint16_t id, const char *name, const char *desc) +int connection_register(const char *path, bdaddr_t *src, bdaddr_t *dst, + uint16_t id, const char *name, const char *desc) { struct network_conn *nc; - if (!conn) - return -1; - nc = g_new0(struct network_conn, 1); /* register path */ - if (!dbus_connection_create_object_path(conn, path, nc, + if (!dbus_connection_create_object_path(connection, path, nc, connection_unregister)) { connection_free(nc); return -1; } - if (!dbus_connection_register_interface(conn, path, + if (!dbus_connection_register_interface(connection, path, NETWORK_CONNECTION_INTERFACE, connection_methods, connection_signals, NULL)) { error("D-Bus failed to register %s interface", NETWORK_CONNECTION_INTERFACE); - dbus_connection_destroy_object_path(conn, path); + dbus_connection_destroy_object_path(connection, path); return -1; } @@ -666,17 +665,21 @@ int connection_register(DBusConnection *conn, const char *path, bdaddr_t *src, nc->name = g_strdup(name); nc->desc = g_strdup(desc); memset(nc->dev, 0, 16); - strncpy(nc->dev, netdev, 16); + strncpy(nc->dev, prefix, strlen(prefix)); + if (id == BNEP_SVC_PANU) + nc->script = conf->panu_script; + else if (id == BNEP_SVC_GN) + nc->script = conf->gn_script; + else + nc->script = conf->nap_script; nc->state = DISCONNECTED; - nc->conn = conn; info("Registered connection path:%s", path); return 0; } -int connection_store(DBusConnection *conn, const char *path, - gboolean default_path) +int connection_store(const char *path, gboolean default_path) { struct network_conn *nc; const char *role; @@ -685,7 +688,8 @@ int connection_store(DBusConnection *conn, const char *path, char src_addr[18], dst_addr[18]; int len, err; - if (!dbus_connection_get_object_user_data(conn, path, (void *) &nc)) + if (!dbus_connection_get_object_user_data(connection, path, + (void *) &nc)) return -ENOENT; if (!nc->name || !nc->desc) @@ -714,14 +718,14 @@ int connection_store(DBusConnection *conn, const char *path, return err; } -int connection_find_data(DBusConnection *conn, - const char *path, const char *pattern) +int connection_find_data(const char *path, const char *pattern) { struct network_conn *nc; char addr[18], key[32]; const char *role; - if (!dbus_connection_get_object_user_data(conn, path, (void *) &nc)) + if (!dbus_connection_get_object_user_data(connection, path, + (void *) &nc)) return -1; if (strcasecmp(pattern, nc->dev) == 0) @@ -744,17 +748,18 @@ int connection_find_data(DBusConnection *conn, return -1; } -gboolean connection_has_pending(DBusConnection *conn, const char *path) +gboolean connection_has_pending(const char *path) { struct network_conn *nc; - if (!dbus_connection_get_object_user_data(conn, path, (void *) &nc)) + if (!dbus_connection_get_object_user_data(connection, path, + (void *) &nc)) return FALSE; return (nc->state == CONNECTING); } -int connection_remove_stored(DBusConnection *conn, const char *path) +int connection_remove_stored(const char *path) { struct network_conn *nc; const char *role; @@ -763,7 +768,8 @@ int connection_remove_stored(DBusConnection *conn, const char *path) char src_addr[18], dst_addr[18]; int err; - if (!dbus_connection_get_object_user_data(conn, path, (void *) &nc)) + if (!dbus_connection_get_object_user_data(connection, path, + (void *) &nc)) return -ENOENT; ba2str(&nc->dst, dst_addr); @@ -778,12 +784,31 @@ int connection_remove_stored(DBusConnection *conn, const char *path) return err; } -gboolean connection_is_connected(DBusConnection *conn, const char *path) +gboolean connection_is_connected(const char *path) { struct network_conn *nc; - if (!dbus_connection_get_object_user_data(conn, path, (void *) &nc)) + if (!dbus_connection_get_object_user_data(connection, path, + (void *) &nc)) return FALSE; return (nc->state == CONNECTED); } + +int connection_init(DBusConnection *conn, const char *iface_prefix, + struct connection_conf *conn_conf) +{ + connection = dbus_connection_ref(conn); + conf = conn_conf; + prefix = iface_prefix; + + return 0; +} + +void connection_exit() +{ + dbus_connection_unref(connection); + connection = NULL; + conf = NULL; + prefix = NULL; +} diff --git a/network/connection.h b/network/connection.h index 35726732..7cafa122 100644 --- a/network/connection.h +++ b/network/connection.h @@ -27,12 +27,13 @@ struct connection_conf { char *nap_script; }; -int connection_register(DBusConnection *conn, const char *path, bdaddr_t *src, - bdaddr_t *dst, uint16_t id, const char *name, const char *desc); -int connection_store(DBusConnection *conn, const char *path, - gboolean default_path); -int connection_remove_stored(DBusConnection *conn, const char *path); -int connection_find_data(DBusConnection *conn, const char *path, - const char *pattern); -gboolean connection_has_pending(DBusConnection *conn, const char *path); -gboolean connection_is_connected(DBusConnection *conn, const char *path); +int connection_init(DBusConnection *conn, const char *iface_prefix, + struct connection_conf *conn_conf); +void connection_exit(); +int connection_register(const char *path, bdaddr_t *src, bdaddr_t *dst, + uint16_t id, const char *name, const char *desc); +int connection_store(const char *path, gboolean default_path); +int connection_remove_stored(const char *path); +int connection_find_data(const char *path, const char *pattern); +gboolean connection_has_pending(const char *path); +gboolean connection_is_connected(const char *path); diff --git a/network/main.c b/network/main.c index 5d1f5013..6260ac4e 100644 --- a/network/main.c +++ b/network/main.c @@ -196,7 +196,7 @@ int main(int argc, char *argv[]) hal_create_device(NULL); - if (network_init(conn) < 0) { + if (network_init(conn, &conf) < 0) { dbus_connection_unref(conn); g_main_loop_unref(main_loop); exit(1); diff --git a/network/manager.c b/network/manager.c index 2bf76e03..6ca36955 100644 --- a/network/manager.c +++ b/network/manager.c @@ -65,14 +65,14 @@ struct pending_reply { uint16_t id; /* Role */ }; +static struct network_conf *conf = NULL;/* Network service configuration */ static GSList *server_paths = NULL; /* Network registered servers paths */ static GSList *connection_paths = NULL; /* Network registered connections paths */ static int default_index = -1; /* Network default connection path index */ +static int net_uid = 0; /* Network objects identifier */ static DBusConnection *connection = NULL; -static int net_uid = 0; /* Network objects identifier */ - static void pending_reply_free(struct pending_reply *pr) { @@ -145,7 +145,7 @@ static const char * last_connection_used(DBusConnection *conn) for (i = g_slist_length (connection_paths) -1; i > -1; i--) { path = g_slist_nth_data (connection_paths, i); - if (connection_is_connected(conn, path)) + if (connection_is_connected(path)) break; } @@ -182,16 +182,16 @@ static DBusHandlerResult remove_path(DBusConnection *conn, /* Remove references from the storage */ if (*list == connection_paths) { - if (connection_has_pending(conn, path)) + if (connection_has_pending(path)) return err_failed(conn, msg, "Connection is Busy"); - connection_remove_stored(conn, path); + connection_remove_stored(path); /* Reset default connection */ if (l == g_slist_nth(*list, default_index)) { const char *dpath; dpath = last_connection_used(conn); - connection_store(conn, dpath, TRUE); + connection_store(dpath, TRUE); } } @@ -274,13 +274,13 @@ static void pan_record_reply(DBusPendingCall *call, void *data) d->unitSize, d->val.str); } - if (connection_register(pr->conn, pr->path, &pr->src, - &pr->dst, pr->id, name, desc) < 0) { + if (connection_register(pr->path, &pr->src, &pr->dst, pr->id, name, + desc) < 0) { err_failed(pr->conn, pr->msg, "D-Bus path registration failed"); goto fail; } - connection_store(pr->conn, pr->path, FALSE); + connection_store(pr->path, FALSE); connection_paths = g_slist_append(connection_paths, g_strdup(pr->path)); create_path(pr->conn, pr->msg, pr->path, "ConnectionCreated"); @@ -463,7 +463,7 @@ static GSList * find_connection_pattern(DBusConnection *conn, for (list = connection_paths; list; list = list->next) { path = (const char *) list->data; - if (connection_find_data(conn, path, pattern) == 0) + if (connection_find_data(path, pattern) == 0) break; } @@ -538,7 +538,7 @@ static DBusHandlerResult create_connection(DBusConnection *conn, /* Checks if the connection was already been made */ for (l = connection_paths; l; l = l->next) { - if (connection_find_data(conn, l->data, key) == 0) { + if (connection_find_data(l->data, key) == 0) { err_already_exists(conn, msg, "Connection Already exists"); return DBUS_HANDLER_RESULT_HANDLED; @@ -616,7 +616,7 @@ static DBusHandlerResult default_connection(DBusConnection *conn, if (path == NULL) { path = last_connection_used(conn); - connection_store(conn, path, TRUE); + connection_store(path, TRUE); } reply = dbus_message_new_method_return(msg); @@ -670,7 +670,7 @@ static DBusHandlerResult change_default_connection(DBusConnection *conn, path = list->data; default_index = g_slist_position (connection_paths, list); - connection_store(connection, path, TRUE); + connection_store(path, TRUE); dbus_connection_emit_signal(connection, NETWORK_PATH, NETWORK_MANAGER_INTERFACE, @@ -760,8 +760,7 @@ static void parse_stored_connection(char *key, char *value, void *data) return; } - if (connection_register(connection, path, src, - &dst, id, name, ptr) == 0) { + if (connection_register(path, src, &dst, id, name, ptr) == 0) { char *rpath = g_strdup(path); connection_paths = g_slist_append(connection_paths, rpath); } @@ -920,15 +919,23 @@ static DBusSignalVTable manager_signals[] = { { NULL, NULL } }; -int network_init(DBusConnection *conn) +int network_init(DBusConnection *conn, struct network_conf *service_conf) { + conf = service_conf; + if (bridge_init() < 0) { error("Can't init bridge module"); return -1; } - if (bridge_create("pan0") < 0) - error("Can't create bridge"); + if (bridge_create(conf->server.panu_iface) < 0) + error("Can't create PANU bridge"); + + if (bridge_create(conf->server.gn_iface) < 0) + error("Can't create GN bridge"); + + if (bridge_create(conf->server.nap_iface) < 0) + error("Can't create NAP bridge"); if (bnep_init()) { error("Can't init bnep module"); @@ -941,9 +948,11 @@ int network_init(DBusConnection *conn) * (setup connection request) contains the destination service * field that defines which service the source is connecting to. */ - if (server_init(conn) < 0) { + if (server_init(conn, conf->iface_prefix, &conf->server) < 0) return -1; - } + + if (connection_init(conn, conf->iface_prefix, &conf->conn) < 0) + return -1; if (!dbus_connection_create_object_path(conn, NETWORK_PATH, NULL, manager_unregister)) { diff --git a/network/manager.h b/network/manager.h index 45c7ada4..0efacc14 100644 --- a/network/manager.h +++ b/network/manager.h @@ -35,7 +35,7 @@ struct network_conf { struct server_conf server; }; -int network_init(DBusConnection *conn); +int network_init(DBusConnection *conn, struct network_conf *service_conf); void network_exit(void); int network_del_stored_info(bdaddr_t *src, uint16_t uuid); 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 */ diff --git a/network/server.h b/network/server.h index 2b148081..233c7837 100644 --- a/network/server.h +++ b/network/server.h @@ -28,7 +28,8 @@ struct server_conf { gboolean disable_security; }; -int server_init(DBusConnection *conn); +int server_init(DBusConnection *conn, const char *iface_prefix, + struct server_conf *server_conf); void server_exit(); int server_register(const char *path, bdaddr_t *src, uint16_t id); int server_register_from_file(const char *path, const bdaddr_t *src, -- cgit From 536cb174ec2d4937bf14fee7d713018e1bb31404 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 28 Sep 2007 13:20:35 +0000 Subject: Fix bridge removal on service exit. --- network/manager.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 6ca36955..5e1ab2f0 100644 --- a/network/manager.c +++ b/network/manager.c @@ -993,8 +993,14 @@ void network_exit(void) connection = NULL; - if (bridge_remove("pan0") < 0) - error("Can't remove bridge"); + if (bridge_remove(conf->server.panu_iface) < 0) + error("Can't remove PANU bridge"); + + if (bridge_remove(conf->server.gn_iface) < 0) + error("Can't remove GN bridge"); + + if (bridge_remove(conf->server.nap_iface) < 0) + error("Can't remove NAP bridge"); bnep_cleanup(); bridge_cleanup(); -- 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/common.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++---- network/common.h | 6 +++- network/connection.c | 6 ++-- network/server.c | 6 ++-- 4 files changed, 99 insertions(+), 14 deletions(-) (limited to 'network') diff --git a/network/common.c b/network/common.c index d818829a..dce12415 100644 --- a/network/common.c +++ b/network/common.c @@ -32,17 +32,21 @@ #include #include #include +#include #include #include #include #include +#include + #include "logging.h" #include "common.h" #include "textfile.h" static int ctl; +static GSList *pids; #define PANU_UUID "00001115-0000-1000-8000-00805f9b34fb" #define NAP_UUID "00001116-0000-1000-8000-00805f9b34fb" @@ -59,6 +63,27 @@ static struct { { NULL } }; +struct bnep_data { + char *devname; + int pid; +}; + +static void script_exited(GPid pid, gint status, gpointer data) +{ + struct bnep_data *bnep = data; + + if (WIFEXITED(status)) + debug("%d exited with status %d", pid, WEXITSTATUS(status)); + else + debug("%d was killed by signal %d", pid, WTERMSIG(status)); + + g_spawn_close_pid(pid); + pid = 0; + + g_free(bnep->devname); + pids = g_slist_remove(pids, bnep); +} + uint16_t bnep_service_id(const char *svc) { int i; @@ -183,26 +208,82 @@ int bnep_connadd(int sk, uint16_t role, char *dev) return 0; } -int bnep_if_up(const char *devname, int up) +static void bnep_setup(gpointer data) { - int sd, err; +} + +int bnep_if_up(const char *devname, const char *script) +{ + int sd, err, pid; struct ifreq ifr; + const char *argv[3]; + struct bnep_data *bnep; sd = socket(AF_INET6, SOCK_DGRAM, 0); + memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, devname); - if (up) - ifr.ifr_flags |= IFF_UP; - else - ifr.ifr_flags &= ~IFF_UP; + 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); return -err; } + if (!script) + return 0; + + argv[0] = script; + argv[1] = devname; + argv[2] = NULL; + if (!g_spawn_async(NULL, (char **) argv, NULL, + G_SPAWN_DO_NOT_REAP_CHILD, bnep_setup, + (gpointer) devname, &pid, NULL)) { + error("Unable to execute %s", argv[0]); + return -1; + } + + bnep = g_new0(struct bnep_data, 1); + bnep->devname = g_strdup(devname); + bnep->pid = pid; + pids = g_slist_append(pids, bnep); + g_child_watch_add(pid, script_exited, bnep); + + return pid; +} + +int bnep_if_down(const char *devname) +{ + int sd, err; + struct ifreq ifr; + GSList *l; + + sd = socket(AF_INET6, SOCK_DGRAM, 0); + memset(&ifr, 0, sizeof(ifr)); + strcpy(ifr.ifr_name, devname); + + ifr.ifr_flags &= ~IFF_UP; + + if ((ioctl(sd, SIOCSIFFLAGS, (caddr_t) &ifr)) < 0) { + err = errno; + error("Could not bring down %d. %s(%d)", devname, strerror(err), + err); + return -err; + } + + for(l = pids; l; l = g_slist_next(l)) { + struct bnep_data *bnep = l->data; + + if (strcmp(devname, bnep->devname) == 0) { + if (kill(bnep->pid, SIGTERM) < 0) + error("kill(%d, SIGTERM): %s (%d)", bnep->pid, + strerror(errno), errno); + break; + } + } + return 0; } diff --git a/network/common.h b/network/common.h index 1d8b57de..de9d753d 100644 --- a/network/common.h +++ b/network/common.h @@ -21,6 +21,9 @@ * */ +#define MAX_PATH_LENGTH 64 /* D-Bus path */ +#define NETWORK_PATH "/org/bluez/network" + int bnep_init(void); int bnep_cleanup(void); @@ -32,6 +35,7 @@ int bnep_kill_connection(bdaddr_t *dst); int bnep_kill_all_connections(void); int bnep_connadd(int sk, uint16_t role, char *dev); -int bnep_if_up(const char *devname, int up); +int bnep_if_up(const char *devname, const char *script); +int bnep_if_down(const char *devname); int read_remote_name(bdaddr_t *src, bdaddr_t *dst, char *buf, size_t size); diff --git a/network/connection.c b/network/connection.c index e6a6c151..fb1b2cdf 100644 --- a/network/connection.c +++ b/network/connection.c @@ -157,7 +157,7 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, goto failed; } - bnep_if_up(nc->dev, TRUE); + bnep_if_up(nc->dev, nc->script); dbus_connection_emit_signal(connection, nc->path, NETWORK_CONNECTION_INTERFACE, "Connected", @@ -515,7 +515,7 @@ static DBusHandlerResult connection_disconnect(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } - bnep_if_up(nc->dev, FALSE); + bnep_if_down(nc->dev); bnep_kill_connection(&nc->dst); reply = dbus_message_new_method_return(msg); @@ -590,7 +590,7 @@ static void connection_free(struct network_conn *nc) g_free(nc->path); if (nc->state == CONNECTED) { - bnep_if_up(nc->dev, FALSE); + bnep_if_down(nc->dev); bnep_kill_connection(&nc->dst); } 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/bridge.c | 35 +++++++++++++++++++----- network/bridge.h | 9 ++++--- network/common.c | 24 ++++++++++++++--- network/common.h | 5 ++-- network/connection.c | 15 ++--------- network/connection.h | 9 +------ network/main.c | 75 ++++++++++++++++++++++++++-------------------------- network/manager.c | 22 ++++++--------- network/manager.h | 8 ++++-- network/network.conf | 29 ++++++++++---------- network/server.c | 31 +++++++--------------- network/server.h | 10 +------ 12 files changed, 136 insertions(+), 136 deletions(-) (limited to 'network') diff --git a/network/bridge.c b/network/bridge.c index 8ef06190..24f1bcc4 100644 --- a/network/bridge.c +++ b/network/bridge.c @@ -31,15 +31,20 @@ #include #include #include - #include #include +#include +#include +#include + #include "bridge.h" static int bridge_socket = -1; +static const char *gn_bridge; +static const char *nap_bridge; -int bridge_init(void) +int bridge_init(const char *gn_iface, const char *nap_iface) { #if 0 struct stat st; @@ -52,6 +57,8 @@ int bridge_init(void) if (bridge_socket < 0) return -errno; + gn_bridge = gn_iface; + nap_bridge = nap_iface; return 0; } @@ -62,9 +69,10 @@ void bridge_cleanup(void) bridge_socket = -1; } -int bridge_create(const char *name) +int bridge_create(int id) { int err; + const char *name = bridge_get_name(id); err = ioctl(bridge_socket, SIOCBRADDBR, name); if (err < 0) @@ -73,9 +81,10 @@ int bridge_create(const char *name) return 0; } -int bridge_remove(const char *name) +int bridge_remove(int id) { int err; + const char *name = bridge_get_name(id); err = ioctl(bridge_socket, SIOCBRDELBR, name); if (err < 0) @@ -84,15 +93,16 @@ int bridge_remove(const char *name) return 0; } -int bridge_add_interface(const char *bridge, const char *dev) +int bridge_add_interface(int id, const char *dev) { struct ifreq ifr; int ifindex = if_nametoindex(dev); + const char *name = bridge_get_name(id); - if (ifindex == 0) + if (ifindex == 0) return -ENODEV; - strncpy(ifr.ifr_name, bridge, IFNAMSIZ); + strncpy(ifr.ifr_name, name, IFNAMSIZ); ifr.ifr_ifindex = ifindex; if (ioctl(bridge_socket, SIOCBRADDIF, &ifr) < 0) @@ -100,3 +110,14 @@ int bridge_add_interface(const char *bridge, const char *dev) return 0; } + +const char *bridge_get_name(int id) +{ + if (id == BNEP_SVC_GN) + return gn_bridge; + + if (id == BNEP_SVC_NAP) + return nap_bridge; + + return NULL; +} diff --git a/network/bridge.h b/network/bridge.h index 2630b892..0861cfb7 100644 --- a/network/bridge.h +++ b/network/bridge.h @@ -21,9 +21,10 @@ * */ -int bridge_init(void); +int bridge_init(const char *gn_iface, const char *nap_iface); void bridge_cleanup(void); -int bridge_create(const char *name); -int bridge_remove(const char *name); -int bridge_add_interface(const char *bridge, const char *dev); +int bridge_create(int id); +int bridge_remove(int id); +int bridge_add_interface(int id, const char *dev); +const char *bridge_get_name(int id); diff --git a/network/common.c b/network/common.c index dce12415..991073ec 100644 --- a/network/common.c +++ b/network/common.c @@ -63,6 +63,10 @@ static struct { { NULL } }; +static const char *panu = NULL; +static const char *gn = NULL; +static const char *nap = NULL; + struct bnep_data { char *devname; int pid; @@ -129,7 +133,8 @@ const char *bnep_name(uint16_t id) return NULL; } -int bnep_init(void) +int bnep_init(const char *panu_script, const char *gn_script, + const char *nap_script) { ctl = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_BNEP); @@ -140,6 +145,9 @@ int bnep_init(void) return -err; } + panu = panu_script; + gn = gn_script; + nap = nap_script; return 0; } @@ -212,11 +220,11 @@ static void bnep_setup(gpointer data) { } -int bnep_if_up(const char *devname, const char *script) +int bnep_if_up(const char *devname, uint16_t id) { int sd, err, pid; struct ifreq ifr; - const char *argv[3]; + const char *argv[3], *script; struct bnep_data *bnep; sd = socket(AF_INET6, SOCK_DGRAM, 0); @@ -232,6 +240,16 @@ int bnep_if_up(const char *devname, const char *script) return -err; } + if (!id) + return 0; + + if (id == BNEP_SVC_PANU) + script = panu; + else if (id == BNEP_SVC_GN) + script = gn; + else + script = nap; + if (!script) return 0; diff --git a/network/common.h b/network/common.h index de9d753d..2b475864 100644 --- a/network/common.h +++ b/network/common.h @@ -24,7 +24,8 @@ #define MAX_PATH_LENGTH 64 /* D-Bus path */ #define NETWORK_PATH "/org/bluez/network" -int bnep_init(void); +int bnep_init(const char *panu_script, const char *gn_script, + const char *nap_script); int bnep_cleanup(void); uint16_t bnep_service_id(const char *svc); @@ -35,7 +36,7 @@ int bnep_kill_connection(bdaddr_t *dst); int bnep_kill_all_connections(void); int bnep_connadd(int sk, uint16_t role, char *dev); -int bnep_if_up(const char *devname, const char *script); +int bnep_if_up(const char *devname, uint16_t id); int bnep_if_down(const char *devname); int read_remote_name(bdaddr_t *src, bdaddr_t *dst, char *buf, size_t size); diff --git a/network/connection.c b/network/connection.c index fb1b2cdf..6157e377 100644 --- a/network/connection.c +++ b/network/connection.c @@ -62,7 +62,6 @@ struct network_conn { char dev[16]; /* Interface name */ char *name; /* Service Name */ char *desc; /* Service Description*/ - char *script; /* Interface up script*/ uint16_t id; /* Role: Service Class Identifier */ conn_state state; int sk; @@ -74,7 +73,6 @@ struct __service_16 { } __attribute__ ((packed)); static DBusConnection *connection = NULL; -static struct connection_conf *conf = NULL; static const char *prefix = NULL; static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond, @@ -157,7 +155,7 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, goto failed; } - bnep_if_up(nc->dev, nc->script); + bnep_if_up(nc->dev, nc->id); dbus_connection_emit_signal(connection, nc->path, NETWORK_CONNECTION_INTERFACE, "Connected", @@ -666,12 +664,6 @@ int connection_register(const char *path, bdaddr_t *src, bdaddr_t *dst, nc->desc = g_strdup(desc); memset(nc->dev, 0, 16); strncpy(nc->dev, prefix, strlen(prefix)); - if (id == BNEP_SVC_PANU) - nc->script = conf->panu_script; - else if (id == BNEP_SVC_GN) - nc->script = conf->gn_script; - else - nc->script = conf->nap_script; nc->state = DISCONNECTED; info("Registered connection path:%s", path); @@ -795,11 +787,9 @@ gboolean connection_is_connected(const char *path) return (nc->state == CONNECTED); } -int connection_init(DBusConnection *conn, const char *iface_prefix, - struct connection_conf *conn_conf) +int connection_init(DBusConnection *conn, const char *iface_prefix) { connection = dbus_connection_ref(conn); - conf = conn_conf; prefix = iface_prefix; return 0; @@ -809,6 +799,5 @@ void connection_exit() { dbus_connection_unref(connection); connection = NULL; - conf = NULL; prefix = NULL; } diff --git a/network/connection.h b/network/connection.h index 7cafa122..5e560811 100644 --- a/network/connection.h +++ b/network/connection.h @@ -21,14 +21,7 @@ * */ -struct connection_conf { - char *panu_script; - char *gn_script; - char *nap_script; -}; - -int connection_init(DBusConnection *conn, const char *iface_prefix, - struct connection_conf *conn_conf); +int connection_init(DBusConnection *conn, const char *iface_prefix); void connection_exit(); int connection_register(const char *path, bdaddr_t *src, bdaddr_t *dst, uint16_t id, const char *name, const char *desc); diff --git a/network/main.c b/network/main.c index 6260ac4e..3ede75fe 100644 --- a/network/main.c +++ b/network/main.c @@ -52,13 +52,12 @@ static struct network_conf conf = { .connection_enabled = TRUE, .server_enabled = TRUE, .iface_prefix = NULL, - .conn.panu_script = NULL, - .conn.gn_script = NULL, - .conn.nap_script = NULL, - .server.panu_iface = NULL, - .server.gn_iface = NULL, - .server.nap_iface = NULL, - .server.disable_security = FALSE + .panu_script = NULL, + .gn_script = NULL, + .nap_script = NULL, + .gn_iface = NULL, + .nap_iface = NULL, + .security = TRUE }; static void sig_term(int sig) @@ -70,6 +69,7 @@ static void read_config(const char *file) { GKeyFile *keyfile; GError *err = NULL; + const char *disabled; keyfile = g_key_file_new(); @@ -80,72 +80,75 @@ static void read_config(const char *file) return; } - conf.iface_prefix = g_key_file_get_string(keyfile, "Connection", - "InterfacePrefix", &err); - if (!conf.iface_prefix) - conf.iface_prefix = g_strdup(IFACE_PREFIX); + disabled = g_key_file_get_string(keyfile, "General", + "Disable", &err); if (err) { debug("%s: %s", file, err->message); g_error_free(err); err = NULL; + } else { + if (strstr(disabled, "Connection")) + conf.connection_enabled = FALSE; + if (strstr(disabled, "Server")) + conf.server_enabled = FALSE; } - conf.conn.panu_script = g_key_file_get_string(keyfile, "Connection", - "PANUScript", &err); + conf.iface_prefix = g_key_file_get_string(keyfile, "General", + "InterfacePrefix", &err); + if (!conf.iface_prefix) + conf.iface_prefix = g_strdup(IFACE_PREFIX); if (err) { debug("%s: %s", file, err->message); g_error_free(err); err = NULL; } - conf.conn.gn_script = g_key_file_get_string(keyfile, "Connection", - "GNScript", &err); + conf.security = g_key_file_get_boolean(keyfile, "General", + "DisableSecurity", &err); if (err) { debug("%s: %s", file, err->message); g_error_free(err); err = NULL; } - conf.conn.nap_script = g_key_file_get_string(keyfile, "Connection", - "NAPScript", &err); + conf.panu_script = g_key_file_get_string(keyfile, "PANU Role", + "Script", &err); if (err) { debug("%s: %s", file, err->message); g_error_free(err); err = NULL; } - conf.server.panu_iface = g_key_file_get_string(keyfile, "Server", - "PANUInterface", &err); - if (!conf.server.panu_iface) - conf.server.panu_iface = g_strdup(PANU_IFACE); + conf.gn_script = g_key_file_get_string(keyfile, "GN Role", + "Script", &err); if (err) { debug("%s: %s", file, err->message); g_error_free(err); err = NULL; } - conf.server.gn_iface = g_key_file_get_string(keyfile, "Server", - "GNInterface", &err); - if (!conf.server.gn_iface) - conf.server.gn_iface = g_strdup(GN_IFACE); + conf.nap_script = g_key_file_get_string(keyfile, "NAP Role", + "Script", &err); if (err) { debug("%s: %s", file, err->message); g_error_free(err); err = NULL; } - conf.server.nap_iface = g_key_file_get_string(keyfile, "Server", - "NAPInterface", &err); - if (!conf.server.nap_iface) - conf.server.nap_iface = g_strdup(NAP_IFACE); + conf.gn_iface = g_key_file_get_string(keyfile, "GN Role", + "Interface", &err); + if (!conf.gn_iface) + conf.gn_iface = g_strdup(GN_IFACE); if (err) { debug("%s: %s", file, err->message); g_error_free(err); err = NULL; } - conf.server.disable_security = g_key_file_get_boolean(keyfile, "Server", - "DisableSecurity", &err); + conf.nap_iface = g_key_file_get_string(keyfile, "NAP Role", + "Interface", &err); + if (!conf.nap_iface) + conf.nap_iface = g_strdup(NAP_IFACE); if (err) { debug("%s: %s", file, err->message); g_error_free(err); @@ -153,12 +156,10 @@ static void read_config(const char *file) } debug("Config options: InterfacePrefix=%s, PANUScript=%s, GNScript=%s, " - "NAPScript=%s, PANUInterface=%s, GNInterface=%s, " - "NAPInterface=%s, DisableSecurity=%s", conf.iface_prefix, - conf.conn.panu_script, conf.conn.gn_script, conf.conn.nap_script, - conf.server.panu_iface, conf.server.gn_iface, - conf.server.nap_iface, - conf.server.disable_security ? "true" : "false"); + "NAPScript=%s, GNInterface=%s, NAPInterface=%s, Security=%s", + conf.iface_prefix, conf.panu_script, conf.gn_script, + conf.nap_script, conf.gn_iface, conf.nap_iface, + conf.security ? "true" : "false"); g_key_file_free(keyfile); } diff --git a/network/manager.c b/network/manager.c index 5e1ab2f0..c82d1c03 100644 --- a/network/manager.c +++ b/network/manager.c @@ -923,21 +923,18 @@ int network_init(DBusConnection *conn, struct network_conf *service_conf) { conf = service_conf; - if (bridge_init() < 0) { + if (bridge_init(conf->gn_iface, conf->nap_iface) < 0) { error("Can't init bridge module"); return -1; } - if (bridge_create(conf->server.panu_iface) < 0) - error("Can't create PANU bridge"); - - if (bridge_create(conf->server.gn_iface) < 0) + if (bridge_create(BNEP_SVC_GN) < 0) error("Can't create GN bridge"); - if (bridge_create(conf->server.nap_iface) < 0) + if (bridge_create(BNEP_SVC_NAP) < 0) error("Can't create NAP bridge"); - if (bnep_init()) { + if (bnep_init(conf->panu_script, conf->gn_script, conf->nap_script)) { error("Can't init bnep module"); return -1; } @@ -948,10 +945,10 @@ int network_init(DBusConnection *conn, struct network_conf *service_conf) * (setup connection request) contains the destination service * field that defines which service the source is connecting to. */ - if (server_init(conn, conf->iface_prefix, &conf->server) < 0) + if (server_init(conn, conf->iface_prefix) < 0) return -1; - if (connection_init(conn, conf->iface_prefix, &conf->conn) < 0) + if (connection_init(conn, conf->iface_prefix) < 0) return -1; if (!dbus_connection_create_object_path(conn, NETWORK_PATH, @@ -993,13 +990,10 @@ void network_exit(void) connection = NULL; - if (bridge_remove(conf->server.panu_iface) < 0) - error("Can't remove PANU bridge"); - - if (bridge_remove(conf->server.gn_iface) < 0) + if (bridge_remove(BNEP_SVC_GN) < 0) error("Can't remove GN bridge"); - if (bridge_remove(conf->server.nap_iface) < 0) + if (bridge_remove(BNEP_SVC_NAP) < 0) error("Can't remove NAP bridge"); bnep_cleanup(); diff --git a/network/manager.h b/network/manager.h index 0efacc14..622665e8 100644 --- a/network/manager.h +++ b/network/manager.h @@ -30,9 +30,13 @@ struct network_conf { gboolean connection_enabled; gboolean server_enabled; + gboolean security; char *iface_prefix; - struct connection_conf conn; - struct server_conf server; + char *panu_script; + char *gn_script; + char *nap_script; + char *gn_iface; + char *nap_iface; }; int network_init(DBusConnection *conn, struct network_conf *service_conf); diff --git a/network/network.conf b/network/network.conf index 66136002..29e77fff 100644 --- a/network/network.conf +++ b/network/network.conf @@ -12,27 +12,26 @@ # (up to 16 characters) InterfacePrefix=bnep%d -[Connection] +# Disable link encryption: default=false +DisableSecurity=false -# PAN user connection interface up script. default: -PANUScript=/usr/sbin/avahi-autoipd +[PANU Role] -# Group Network connection interface up script. default: -GNScript=/usr/sbin/avahi-autoipd +# PAN user connection interface up script. default:none +Script=avahi-autoipd -# Network Access Point connection interface up script. default: -NAPScript=/sbin/dhclient +[GN Role] -[Server] +# Network Interface name for Group Network server. default:pan1 +Interface=pan0 -# Network Interface name for PAN user server. default:pan0 -PANUInterface=pan0 +# Group Network connection interface up script. default:none +Script=avahi-autoipd -# Network Interface name for Group Network server. default:pan1 -GNInterface=pan1 +[NAP Role] # Network Interface name for Network Access Point server. default:pan2 -NAPInterface=pan2 +Interface=pan1 -# Disable link encryption: default=false -DisableSecurity=false +# Network Access Point connection interface up script. default:none +Script=/sbin/dhclient 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 */ diff --git a/network/server.h b/network/server.h index 233c7837..9f49cad7 100644 --- a/network/server.h +++ b/network/server.h @@ -21,15 +21,7 @@ * */ -struct server_conf { - char *panu_iface; - char *gn_iface; - char *nap_iface; - gboolean disable_security; -}; - -int server_init(DBusConnection *conn, const char *iface_prefix, - struct server_conf *server_conf); +int server_init(DBusConnection *conn, const char *iface_prefix); void server_exit(); int server_register(const char *path, bdaddr_t *src, uint16_t id); int server_register_from_file(const char *path, const bdaddr_t *src, -- 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/common.c | 5 +++-- network/connection.c | 20 ++++++++++---------- network/main.c | 7 ++++--- network/manager.c | 14 +++++++------- network/network.conf | 2 +- network/server.c | 7 ++++--- 6 files changed, 29 insertions(+), 26 deletions(-) (limited to 'network') diff --git a/network/common.c b/network/common.c index 991073ec..96821f84 100644 --- a/network/common.c +++ b/network/common.c @@ -226,6 +226,7 @@ int bnep_if_up(const char *devname, uint16_t id) struct ifreq ifr; const char *argv[3], *script; struct bnep_data *bnep; + GSpawnFlags flags; sd = socket(AF_INET6, SOCK_DGRAM, 0); memset(&ifr, 0, sizeof(ifr)); @@ -256,8 +257,8 @@ int bnep_if_up(const char *devname, uint16_t id) argv[0] = script; argv[1] = devname; argv[2] = NULL; - if (!g_spawn_async(NULL, (char **) argv, NULL, - G_SPAWN_DO_NOT_REAP_CHILD, bnep_setup, + flags = G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH; + if (!g_spawn_async(NULL, (char **) argv, NULL, flags, bnep_setup, (gpointer) devname, &pid, NULL)) { error("Unable to execute %s", argv[0]); return -1; diff --git a/network/connection.c b/network/connection.c index 6157e377..245d4cc9 100644 --- a/network/connection.c +++ b/network/connection.c @@ -680,8 +680,8 @@ int connection_store(const char *path, gboolean default_path) char src_addr[18], dst_addr[18]; int len, err; - if (!dbus_connection_get_object_user_data(connection, path, - (void *) &nc)) + if (!dbus_connection_get_object_user_data(connection, + path, (void *) &nc)) return -ENOENT; if (!nc->name || !nc->desc) @@ -716,8 +716,8 @@ int connection_find_data(const char *path, const char *pattern) char addr[18], key[32]; const char *role; - if (!dbus_connection_get_object_user_data(connection, path, - (void *) &nc)) + if (!dbus_connection_get_object_user_data(connection, + path, (void *) &nc)) return -1; if (strcasecmp(pattern, nc->dev) == 0) @@ -744,8 +744,8 @@ gboolean connection_has_pending(const char *path) { struct network_conn *nc; - if (!dbus_connection_get_object_user_data(connection, path, - (void *) &nc)) + if (!dbus_connection_get_object_user_data(connection, + path, (void *) &nc)) return FALSE; return (nc->state == CONNECTING); @@ -760,8 +760,8 @@ int connection_remove_stored(const char *path) char src_addr[18], dst_addr[18]; int err; - if (!dbus_connection_get_object_user_data(connection, path, - (void *) &nc)) + if (!dbus_connection_get_object_user_data(connection, + path, (void *) &nc)) return -ENOENT; ba2str(&nc->dst, dst_addr); @@ -780,8 +780,8 @@ gboolean connection_is_connected(const char *path) { struct network_conn *nc; - if (!dbus_connection_get_object_user_data(connection, path, - (void *) &nc)) + if (!dbus_connection_get_object_user_data(connection, + path, (void *) &nc)) return FALSE; return (nc->state == CONNECTED); diff --git a/network/main.c b/network/main.c index 3ede75fe..6225ff4e 100644 --- a/network/main.c +++ b/network/main.c @@ -103,7 +103,7 @@ static void read_config(const char *file) err = NULL; } - conf.security = g_key_file_get_boolean(keyfile, "General", + conf.security = !g_key_file_get_boolean(keyfile, "General", "DisableSecurity", &err); if (err) { debug("%s: %s", file, err->message); @@ -155,8 +155,9 @@ static void read_config(const char *file) err = NULL; } - debug("Config options: InterfacePrefix=%s, PANUScript=%s, GNScript=%s, " - "NAPScript=%s, GNInterface=%s, NAPInterface=%s, Security=%s", + debug("Config options: InterfacePrefix=%s, PANU_Script=%s, " + "GN_Script=%s, NAP_Script=%s, GN_Interface=%s, " + "NAP_Interface=%s, Security=%s", conf.iface_prefix, conf.panu_script, conf.gn_script, conf.nap_script, conf.gn_iface, conf.nap_iface, conf.security ? "true" : "false"); diff --git a/network/manager.c b/network/manager.c index c82d1c03..b5b4f0a8 100644 --- a/network/manager.c +++ b/network/manager.c @@ -928,12 +928,6 @@ int network_init(DBusConnection *conn, struct network_conf *service_conf) return -1; } - if (bridge_create(BNEP_SVC_GN) < 0) - error("Can't create GN bridge"); - - if (bridge_create(BNEP_SVC_NAP) < 0) - error("Can't create NAP bridge"); - if (bnep_init(conf->panu_script, conf->gn_script, conf->nap_script)) { error("Can't init bnep module"); return -1; @@ -967,6 +961,12 @@ int network_init(DBusConnection *conn, struct network_conf *service_conf) return -1; } + if (bridge_create(BNEP_SVC_GN) < 0) + error("Can't create GN bridge"); + + if (bridge_create(BNEP_SVC_NAP) < 0) + error("Can't create NAP bridge"); + connection = dbus_connection_ref(conn); info("Registered manager path:%s", NETWORK_PATH); @@ -984,10 +984,10 @@ int network_init(DBusConnection *conn, struct network_conf *service_conf) void network_exit(void) { server_exit(); + connection_exit(); dbus_connection_destroy_object_path(connection, NETWORK_PATH); dbus_connection_unref(connection); - connection = NULL; if (bridge_remove(BNEP_SVC_GN) < 0) diff --git a/network/network.conf b/network/network.conf index 29e77fff..98524bfc 100644 --- a/network/network.conf +++ b/network/network.conf @@ -34,4 +34,4 @@ Script=avahi-autoipd Interface=pan1 # Network Access Point connection interface up script. default:none -Script=/sbin/dhclient +Script=dhclient 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') 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 1ed2cb39e498622f727be5dc129cd5105d34200f Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 28 Sep 2007 13:27:24 +0000 Subject: Fix bridge removal. --- network/bridge.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'network') diff --git a/network/bridge.c b/network/bridge.c index 24f1bcc4..e481ca80 100644 --- a/network/bridge.c +++ b/network/bridge.c @@ -39,6 +39,7 @@ #include #include "bridge.h" +#include "common.h" static int bridge_socket = -1; static const char *gn_bridge; @@ -86,6 +87,10 @@ int bridge_remove(int id) int err; const char *name = bridge_get_name(id); + err = bnep_if_down(name); + if (err < 0) + return err; + err = ioctl(bridge_socket, SIOCBRDELBR, name); if (err < 0) return -errno; @@ -99,6 +104,9 @@ int bridge_add_interface(int id, const char *dev) int ifindex = if_nametoindex(dev); const char *name = bridge_get_name(id); + if (!name) + return -EINVAL; + if (ifindex == 0) return -ENODEV; -- cgit From 76b8a8707dbb1887e94f812c4a9ca8b65d3353fd Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 28 Sep 2007 13:28:09 +0000 Subject: Fix interface down. --- network/common.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'network') diff --git a/network/common.c b/network/common.c index 96821f84..d7174a18 100644 --- a/network/common.c +++ b/network/common.c @@ -279,6 +279,18 @@ int bnep_if_down(const char *devname) struct ifreq ifr; GSList *l; + for(l = pids; l; l = g_slist_next(l)) { + struct bnep_data *bnep = l->data; + + if (strcmp(devname, bnep->devname) == 0) { + if (kill(bnep->pid, SIGTERM) < 0) + error("kill(%d, SIGTERM): %s (%d)", bnep->pid, + strerror(errno), errno); + pids = g_slist_remove(pids, bnep); + break; + } + } + sd = socket(AF_INET6, SOCK_DGRAM, 0); memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, devname); @@ -292,17 +304,6 @@ int bnep_if_down(const char *devname) return -err; } - for(l = pids; l; l = g_slist_next(l)) { - struct bnep_data *bnep = l->data; - - if (strcmp(devname, bnep->devname) == 0) { - if (kill(bnep->pid, SIGTERM) < 0) - error("kill(%d, SIGTERM): %s (%d)", bnep->pid, - strerror(errno), errno); - break; - } - } - return 0; } -- 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') 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 684fe2781c46ccfb30a4e653fad126286bddcdcb Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 28 Sep 2007 13:29:59 +0000 Subject: Fix default configuration when config file is missing. --- network/main.c | 42 +++++++++++++++++++++--------------------- network/network.conf | 24 ++++++++++++------------ 2 files changed, 33 insertions(+), 33 deletions(-) (limited to 'network') diff --git a/network/main.c b/network/main.c index 6225ff4e..8c9bdc54 100644 --- a/network/main.c +++ b/network/main.c @@ -42,9 +42,8 @@ #include "hal.h" #define IFACE_PREFIX "bnep%d" -#define PANU_IFACE "pan0" -#define GN_IFACE "pan1" -#define NAP_IFACE "pan2" +#define GN_IFACE "pan0" +#define NAP_IFACE "pan1" static GMainLoop *main_loop; @@ -76,8 +75,7 @@ static void read_config(const char *file) if (!g_key_file_load_from_file(keyfile, file, 0, &err)) { error("Parsing %s failed: %s", file, err->message); g_error_free(err); - g_key_file_free(keyfile); - return; + goto done; } disabled = g_key_file_get_string(keyfile, "General", @@ -93,16 +91,6 @@ static void read_config(const char *file) conf.server_enabled = FALSE; } - conf.iface_prefix = g_key_file_get_string(keyfile, "General", - "InterfacePrefix", &err); - if (!conf.iface_prefix) - conf.iface_prefix = g_strdup(IFACE_PREFIX); - if (err) { - debug("%s: %s", file, err->message); - g_error_free(err); - err = NULL; - } - conf.security = !g_key_file_get_boolean(keyfile, "General", "DisableSecurity", &err); if (err) { @@ -135,10 +123,16 @@ static void read_config(const char *file) err = NULL; } + conf.iface_prefix = g_key_file_get_string(keyfile, "PANU Role", + "Interface", &err); + if (err) { + debug("%s: %s", file, err->message); + g_error_free(err); + err = NULL; + } + conf.gn_iface = g_key_file_get_string(keyfile, "GN Role", "Interface", &err); - if (!conf.gn_iface) - conf.gn_iface = g_strdup(GN_IFACE); if (err) { debug("%s: %s", file, err->message); g_error_free(err); @@ -147,22 +141,28 @@ static void read_config(const char *file) conf.nap_iface = g_key_file_get_string(keyfile, "NAP Role", "Interface", &err); - if (!conf.nap_iface) - conf.nap_iface = g_strdup(NAP_IFACE); if (err) { debug("%s: %s", file, err->message); g_error_free(err); err = NULL; } +done: + g_key_file_free(keyfile); + + if (!conf.iface_prefix) + conf.iface_prefix = g_strdup(IFACE_PREFIX); + if (!conf.gn_iface) + conf.gn_iface = g_strdup(GN_IFACE); + if (!conf.nap_iface) + conf.nap_iface = g_strdup(NAP_IFACE); + debug("Config options: InterfacePrefix=%s, PANU_Script=%s, " "GN_Script=%s, NAP_Script=%s, GN_Interface=%s, " "NAP_Interface=%s, Security=%s", conf.iface_prefix, conf.panu_script, conf.gn_script, conf.nap_script, conf.gn_iface, conf.nap_iface, conf.security ? "true" : "false"); - - g_key_file_free(keyfile); } int main(int argc, char *argv[]) diff --git a/network/network.conf b/network/network.conf index 98524bfc..51a873e7 100644 --- a/network/network.conf +++ b/network/network.conf @@ -8,30 +8,30 @@ # Defaults to supporting all implemented services #Disable=Connection,Server -# Network interface name prefix for connections. default:bnep%d -# (up to 16 characters) -InterfacePrefix=bnep%d - # Disable link encryption: default=false -DisableSecurity=false +#DisableSecurity=true [PANU Role] +# Network interface name for PANU for connections. default:bnep%d +# (up to 16 characters) +#Interface= + # PAN user connection interface up script. default:none -Script=avahi-autoipd +#Script=avahi-autoipd [GN Role] -# Network Interface name for Group Network server. default:pan1 -Interface=pan0 +# Network Interface name for Group Network server. default:pan0 +#Interface= # Group Network connection interface up script. default:none -Script=avahi-autoipd +#Script=avahi-autoipd [NAP Role] -# Network Interface name for Network Access Point server. default:pan2 -Interface=pan1 +# Network Interface name for Network Access Point server. default:pan1 +#Interface= # Network Access Point connection interface up script. default:none -Script=dhclient +#Script=dhclient -- 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/manager.c | 2 +- network/server.c | 6 +++--- network/server.h | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index b5b4f0a8..053e03bb 100644 --- a/network/manager.c +++ b/network/manager.c @@ -939,7 +939,7 @@ int network_init(DBusConnection *conn, struct network_conf *service_conf) * (setup connection request) contains the destination service * field that defines which service the source is connecting to. */ - if (server_init(conn, conf->iface_prefix) < 0) + if (server_init(conn, conf->iface_prefix, conf->security) < 0) return -1; if (connection_init(conn, conf->iface_prefix) < 0) 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)", diff --git a/network/server.h b/network/server.h index 9f49cad7..839aea4b 100644 --- a/network/server.h +++ b/network/server.h @@ -21,7 +21,8 @@ * */ -int server_init(DBusConnection *conn, const char *iface_prefix); +int server_init(DBusConnection *conn, const char *iface_prefix, + gboolean secure); void server_exit(); int server_register(const char *path, bdaddr_t *src, uint16_t id); int server_register_from_file(const char *path, const bdaddr_t *src, -- cgit From 123ef726b4bb5c465cd8a5e7b7c003e55443b219 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 28 Sep 2007 13:31:42 +0000 Subject: Fix PANU connection not being restored from storage. --- network/manager.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 053e03bb..355b9665 100644 --- a/network/manager.c +++ b/network/manager.c @@ -737,6 +737,8 @@ static void parse_stored_connection(char *key, char *value, void *data) id = BNEP_SVC_NAP; else if (strcasecmp("gn", ptr) == 0) id = BNEP_SVC_GN; + else if (strcasecmp("panu", ptr) == 0) + id = BNEP_SVC_PANU; else return; -- 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/bridge.c | 10 ++++++++-- network/common.c | 51 +++++++++++++++++++++++++++++++++++---------------- network/network.conf | 6 +++--- network/server.c | 6 ------ 4 files changed, 46 insertions(+), 27 deletions(-) (limited to 'network') diff --git a/network/bridge.c b/network/bridge.c index e481ca80..ad4fc72e 100644 --- a/network/bridge.c +++ b/network/bridge.c @@ -101,6 +101,7 @@ int bridge_remove(int id) int bridge_add_interface(int id, const char *dev) { struct ifreq ifr; + int err; int ifindex = if_nametoindex(dev); const char *name = bridge_get_name(id); @@ -113,8 +114,13 @@ int bridge_add_interface(int id, const char *dev) strncpy(ifr.ifr_name, name, IFNAMSIZ); ifr.ifr_ifindex = ifindex; - if (ioctl(bridge_socket, SIOCBRADDIF, &ifr) < 0) - return -errno; + err = ioctl(bridge_socket, SIOCBRADDIF, &ifr); + if (err < 0) + return err; + + err = bnep_if_up(name, id); + if (err < 0) + return err; return 0; } diff --git a/network/common.c b/network/common.c index d7174a18..e634ac43 100644 --- a/network/common.c +++ b/network/common.c @@ -72,6 +72,14 @@ struct bnep_data { int pid; }; +static gint find_devname(gconstpointer a, gconstpointer b) +{ + struct bnep_data *data = (struct bnep_data *) a; + const char *devname = b; + + return strcmp(data->devname, devname); +} + static void script_exited(GPid pid, gint status, gpointer data) { struct bnep_data *bnep = data; @@ -228,6 +236,9 @@ int bnep_if_up(const char *devname, uint16_t id) struct bnep_data *bnep; GSpawnFlags flags; + if (g_slist_find_custom(pids, devname, find_devname)) + return 0; + sd = socket(AF_INET6, SOCK_DGRAM, 0); memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, devname); @@ -241,8 +252,11 @@ int bnep_if_up(const char *devname, uint16_t id) return -err; } + bnep = g_new0(struct bnep_data, 1); + bnep->devname = g_strdup(devname); + if (!id) - return 0; + goto done; if (id == BNEP_SVC_PANU) script = panu; @@ -252,7 +266,7 @@ int bnep_if_up(const char *devname, uint16_t id) script = nap; if (!script) - return 0; + goto done; argv[0] = script; argv[1] = devname; @@ -261,34 +275,37 @@ int bnep_if_up(const char *devname, uint16_t id) if (!g_spawn_async(NULL, (char **) argv, NULL, flags, bnep_setup, (gpointer) devname, &pid, NULL)) { error("Unable to execute %s", argv[0]); - return -1; + return -EINVAL; } - bnep = g_new0(struct bnep_data, 1); - bnep->devname = g_strdup(devname); bnep->pid = pid; - pids = g_slist_append(pids, bnep); g_child_watch_add(pid, script_exited, bnep); - return pid; +done: + pids = g_slist_append(pids, bnep); + + return bnep->pid; } int bnep_if_down(const char *devname) { int sd, err; struct ifreq ifr; + struct bnep_data *data; GSList *l; - for(l = pids; l; l = g_slist_next(l)) { - struct bnep_data *bnep = l->data; + l = g_slist_find_custom(pids, devname, find_devname); + if (!l) + return 0; - if (strcmp(devname, bnep->devname) == 0) { - if (kill(bnep->pid, SIGTERM) < 0) - error("kill(%d, SIGTERM): %s (%d)", bnep->pid, - strerror(errno), errno); - pids = g_slist_remove(pids, bnep); - break; - } + data = l->data; + if (data->pid) { + err = kill(data->pid, SIGTERM); + if (err < 0) + error("kill(%d, SIGTERM): %s (%d)", data->pid, + strerror(errno), errno); + else + data->pid = 0; } sd = socket(AF_INET6, SOCK_DGRAM, 0); @@ -304,6 +321,8 @@ int bnep_if_down(const char *devname) return -err; } + pids = g_slist_remove(pids, data); + return 0; } diff --git a/network/network.conf b/network/network.conf index 51a873e7..8677bd7b 100644 --- a/network/network.conf +++ b/network/network.conf @@ -18,7 +18,7 @@ #Interface= # PAN user connection interface up script. default:none -#Script=avahi-autoipd +Script=avahi-autoipd [GN Role] @@ -26,7 +26,7 @@ #Interface= # Group Network connection interface up script. default:none -#Script=avahi-autoipd +Script=avahi-autoipd [NAP Role] @@ -34,4 +34,4 @@ #Interface= # Network Access Point connection interface up script. default:none -#Script=dhclient +Script=dhclient 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 f3314791b10f4c7ccc17ab4fd51c9642a670e0a7 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 28 Sep 2007 13:35:08 +0000 Subject: Fix interface removal on script exit. --- network/common.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'network') diff --git a/network/common.c b/network/common.c index e634ac43..b5f42b19 100644 --- a/network/common.c +++ b/network/common.c @@ -89,11 +89,8 @@ static void script_exited(GPid pid, gint status, gpointer data) else debug("%d was killed by signal %d", pid, WTERMSIG(status)); - g_spawn_close_pid(pid); - pid = 0; - - g_free(bnep->devname); - pids = g_slist_remove(pids, bnep); + g_spawn_close_pid(bnep->pid); + bnep->pid = 0; } uint16_t bnep_service_id(const char *svc) -- 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/network-api.txt | 8 ------ network/server.c | 75 ++++--------------------------------------------- 2 files changed, 6 insertions(+), 77 deletions(-) (limited to 'network') diff --git a/network/network-api.txt b/network/network-api.txt index 542ddf02..63ac05d2 100644 --- a/network/network-api.txt +++ b/network/network-api.txt @@ -115,14 +115,6 @@ Methods string GetUUID() TBD - void SetSecurity(bool enable) - - TBD - - bool GetSecurity() - - Returns server encryption. - dict GetInfo() Returns the server properties. 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/manager.c | 11 +++++------ network/server.c | 5 ++++- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 355b9665..683ff0a0 100644 --- a/network/manager.c +++ b/network/manager.c @@ -825,17 +825,16 @@ static void register_server(uint16_t id) return; bacpy(&src, BDADDR_ANY); + dev_id = hci_get_route(&src); + if (dev_id < 0) + return; - dev_id = hci_get_route(NULL); - - if (dev_id >= 0) - hci_devba(dev_id, &src); + hci_devba(dev_id, &src); if (server_register(path, &src, id) < 0) return; - if (bacmp(&src, BDADDR_ANY) != 0) - server_store(path); + server_store(path); server_paths = g_slist_append(server_paths, g_strdup(path)); } 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/network-api.txt | 4 ++++ network/server.c | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) (limited to 'network') diff --git a/network/network-api.txt b/network/network-api.txt index 63ac05d2..e5916088 100644 --- a/network/network-api.txt +++ b/network/network-api.txt @@ -99,6 +99,10 @@ Methods string GetUUID() Possible errors: org.bluez.network.Error.Failed + bool IsEnabled() + + Returns the server status. + void SetName(string name) Sets the name attribute. 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 11275793e04e21cb7e26d6a7d289f98005a3c478 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 28 Sep 2007 13:39:38 +0000 Subject: Fix memory leak. --- network/common.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'network') diff --git a/network/common.c b/network/common.c index b5f42b19..cf351153 100644 --- a/network/common.c +++ b/network/common.c @@ -82,15 +82,12 @@ static gint find_devname(gconstpointer a, gconstpointer b) static void script_exited(GPid pid, gint status, gpointer data) { - struct bnep_data *bnep = data; - if (WIFEXITED(status)) debug("%d exited with status %d", pid, WEXITSTATUS(status)); else debug("%d was killed by signal %d", pid, WTERMSIG(status)); - g_spawn_close_pid(bnep->pid); - bnep->pid = 0; + g_spawn_close_pid(pid); } uint16_t bnep_service_id(const char *svc) @@ -288,21 +285,19 @@ int bnep_if_down(const char *devname) { int sd, err; struct ifreq ifr; - struct bnep_data *data; + struct bnep_data *bnep; GSList *l; l = g_slist_find_custom(pids, devname, find_devname); if (!l) return 0; - data = l->data; - if (data->pid) { - err = kill(data->pid, SIGTERM); + bnep = l->data; + if (bnep->pid) { + err = kill(bnep->pid, SIGTERM); if (err < 0) - error("kill(%d, SIGTERM): %s (%d)", data->pid, + error("kill(%d, SIGTERM): %s (%d)", bnep->pid, strerror(errno), errno); - else - data->pid = 0; } sd = socket(AF_INET6, SOCK_DGRAM, 0); @@ -318,7 +313,9 @@ int bnep_if_down(const char *devname) return -err; } - pids = g_slist_remove(pids, data); + pids = g_slist_remove(pids, bnep); + g_free(bnep->devname); + g_free(bnep); return 0; } -- 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/connection.c | 2 +- network/server.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 245d4cc9..821560f8 100644 --- a/network/connection.c +++ b/network/connection.c @@ -622,7 +622,7 @@ static DBusMethodVTable connection_methods[] = { { "CancelConnect", connection_cancel, "", "" }, { "Disconnect", connection_disconnect, "", "" }, { "IsConnected", is_connected, "", "b" }, - { "GetInfo", get_info, "", "{sv}", }, + { "GetInfo", get_info, "", "a{sv}" }, { NULL, NULL, NULL, NULL } }; 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 e3c231967270c94f9f147aab63be90e5c217fdaf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 8 Oct 2007 08:42:56 +0000 Subject: Allow PANU server and client connection --- network/test-network | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'network') diff --git a/network/test-network b/network/test-network index 3719deaa..f428c25f 100755 --- a/network/test-network +++ b/network/test-network @@ -25,7 +25,13 @@ except: pass try: - panu = dbus.Interface(bus.get_object(conn, network.LastConnection()), + panu = dbus.Interface(bus.get_object(conn, network.FindServer('panu')), + 'org.bluez.network.Server') +except: + pass + +try: + client = dbus.Interface(bus.get_object(conn, network.LastConnection()), 'org.bluez.network.Connection') except: pass -- 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/connection.c | 20 +++++++++++--- network/manager.c | 75 +++++++++++++++++++++++++++++++++++++++++++++------- network/server.c | 5 +++- 3 files changed, 86 insertions(+), 14 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 821560f8..439aaa30 100644 --- a/network/connection.c +++ b/network/connection.c @@ -32,6 +32,8 @@ #include #include +#include +#include #include #include @@ -56,6 +58,7 @@ typedef enum { struct network_conn { DBusMessage *msg; + bdaddr_t store; bdaddr_t src; bdaddr_t dst; char *path; /* D-Bus path */ @@ -636,6 +639,16 @@ int connection_register(const char *path, bdaddr_t *src, bdaddr_t *dst, uint16_t id, const char *name, const char *desc) { struct network_conn *nc; + bdaddr_t default_src; + int dev_id; + + if (!path) + return -EINVAL; + + bacpy(&default_src, BDADDR_ANY); + dev_id = hci_get_route(&default_src); + if ((dev_id < 0) || (hci_devba(dev_id, &default_src) < 0)) + return -1; nc = g_new0(struct network_conn, 1); @@ -657,7 +670,8 @@ int connection_register(const char *path, bdaddr_t *src, bdaddr_t *dst, } nc->path = g_strdup(path); - bacpy(&nc->src, src); + bacpy(&nc->store, src); + bacpy(&nc->src, &default_src); bacpy(&nc->dst, dst); nc->id = id; nc->name = g_strdup(name); @@ -693,7 +707,7 @@ int connection_store(const char *path, gboolean default_path) role = bnep_name(nc->id); snprintf(key, 32, "%s#%s", dst_addr, role); - ba2str(&nc->src, src_addr); + ba2str(&nc->store, src_addr); create_name(filename, PATH_MAX, STORAGEDIR, src_addr, "network"); create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); @@ -768,7 +782,7 @@ int connection_remove_stored(const char *path) role = bnep_name(nc->id); snprintf(key, 32, "%s#%s", dst_addr, role); - ba2str(&nc->src, src_addr); + ba2str(&nc->store, src_addr); create_name(filename, PATH_MAX, STORAGEDIR, src_addr, "network"); err = textfile_del(filename, key); diff --git a/network/manager.c b/network/manager.c index 683ff0a0..26553b7f 100644 --- a/network/manager.c +++ b/network/manager.c @@ -507,6 +507,60 @@ static DBusHandlerResult find_connection(DBusConnection *conn, return send_message_and_unref(conn, reply); } +char *find_adapter(DBusConnection *conn, bdaddr_t *src) +{ + DBusMessage *msg, *reply; + DBusError derr; + char address[18], *addr_ptr = address; + char *path, *ret; + + msg = dbus_message_new_method_call("org.bluez", "/org/bluez", + "org.bluez.Manager", + "FindAdapter"); + if (!msg) { + error("Unable to allocate new method call"); + return NULL; + } + + ba2str(src, address); + + dbus_message_append_args(msg, DBUS_TYPE_STRING, &addr_ptr, + 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) || + dbus_set_error_from_message(&derr, reply)) { + error("FindAdapter(%s) failed: %s", address, derr.message); + dbus_error_free(&derr); + return NULL; + } + + dbus_error_init(&derr); + dbus_message_get_args(reply, &derr, + DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set(&derr)) { + error("Unable to get message args"); + dbus_message_unref(reply); + dbus_error_free(&derr); + return FALSE; + } + + ret = g_strdup(path); + + dbus_message_unref(reply); + + debug("Got path %s for adapter with address %s", ret, address); + + return ret; +} + static DBusHandlerResult create_connection(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -546,11 +600,18 @@ static DBusHandlerResult create_connection(DBusConnection *conn, } bacpy(&src, BDADDR_ANY); - dev_id = hci_get_route(NULL); - if ((dev_id < 0) || (hci_devba(dev_id, &src) < 0)) + dev_id = hci_get_route(&src); + if (dev_id < 0 || hci_devba(dev_id, &src) < 0) return err_failed(conn, msg, "Adapter not available"); pr = g_new0(struct pending_reply, 1); + + pr->adapter_path = find_adapter(conn, &src); + if (!pr->adapter_path) { + pending_reply_free (pr); + return err_failed(conn, msg, "Adapter not available"); + } + pr->conn = dbus_connection_ref(conn); pr->msg = dbus_message_ref(msg); bacpy(&pr->src, &src); @@ -561,9 +622,6 @@ static DBusHandlerResult create_connection(DBusConnection *conn, snprintf(pr->path, MAX_PATH_LENGTH, NETWORK_PATH"/connection%d", net_uid++); - pr->adapter_path = g_malloc0(16); - snprintf(pr->adapter_path, 16, "/org/bluez/hci%d", dev_id); - if (get_handles(pr, pan_handle_reply) < 0) return err_not_supported(conn, msg); @@ -795,10 +853,9 @@ static void register_connections_stored(const char *adapter) /* Check default connection for current default adapter */ bacpy(&default_src, BDADDR_ANY); dev_id = hci_get_route(&default_src); - if (dev_id < 0) + if (dev_id < 0 || hci_devba(dev_id, &default_src) < 0) return; - hci_devba(dev_id, &default_src); if (bacmp(&default_src, &src) != 0) return; @@ -826,11 +883,9 @@ static void register_server(uint16_t id) bacpy(&src, BDADDR_ANY); dev_id = hci_get_route(&src); - if (dev_id < 0) + if (dev_id < 0 || hci_devba(dev_id, &src)) return; - hci_devba(dev_id, &src); - if (server_register(path, &src, id) < 0) return; 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 b636ccf2c9c5f5c7419c49c556b118930012d2e7 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 22 Oct 2007 20:53:30 +0000 Subject: Fix code style. --- network/connection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 439aaa30..933cdd98 100644 --- a/network/connection.c +++ b/network/connection.c @@ -647,7 +647,7 @@ int connection_register(const char *path, bdaddr_t *src, bdaddr_t *dst, bacpy(&default_src, BDADDR_ANY); dev_id = hci_get_route(&default_src); - if ((dev_id < 0) || (hci_devba(dev_id, &default_src) < 0)) + if (dev_id < 0 || hci_devba(dev_id, &default_src) < 0) return -1; nc = g_new0(struct network_conn, 1); -- cgit From 97fd2ad39b3a08d695f5d45783e2dd0ee377bf3f Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 31 Oct 2007 14:47:39 +0000 Subject: Handle disabling interfaces via configuration file. --- network/manager.c | 101 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 68 insertions(+), 33 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 26553b7f..6355f032 100644 --- a/network/manager.c +++ b/network/manager.c @@ -875,6 +875,9 @@ static void register_server(uint16_t id) bdaddr_t src; int dev_id; + if (!conf->server_enabled) + return; + snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/%s", bnep_name(id)); if (g_slist_find_custom(server_paths, path, @@ -940,24 +943,26 @@ static void register_stored(void) continue; /* Connection objects */ - register_connections_stored(de->d_name); + if (conf->connection_enabled) + register_connections_stored(de->d_name); - /* NAP objects */ - register_servers_stored(de->d_name, "nap"); + /* Server objects */ + if (conf->server_enabled) { + /* NAP objects */ + register_servers_stored(de->d_name, "nap"); - /* GN objects */ - register_servers_stored(de->d_name, "gn"); + /* GN objects */ + register_servers_stored(de->d_name, "gn"); - /* PANU objects */ - register_servers_stored(de->d_name, "panu"); + /* PANU objects */ + register_servers_stored(de->d_name, "panu"); + } } closedir(dir); } -static DBusMethodVTable manager_methods[] = { - { "ListServers", list_servers, "", "as" }, - { "FindServer", find_server, "s", "s" }, +static DBusMethodVTable connection_methods[] = { { "ListConnections", list_connections, "", "as" }, { "FindConnection", find_connection, "s", "s" }, { "CreateConnection", create_connection, "ss", "s" }, @@ -968,19 +973,49 @@ static DBusMethodVTable manager_methods[] = { { NULL, NULL, NULL, NULL } }; -static DBusSignalVTable manager_signals[] = { +static DBusSignalVTable connection_signals[] = { { "ConnectionCreated", "s" }, { "ConnectionRemoved", "s" }, { "DefaultConnectionChanged", "s" }, { NULL, NULL } }; +static DBusMethodVTable server_methods[] = { + { "ListServers", list_servers, "", "as" }, + { "FindServer", find_server, "s", "s" }, + { NULL, NULL, NULL, NULL } +}; + +static DBusMethodVTable manager_methods[] = { + { "ListServers", list_servers, "", "as" }, + { "FindServer", find_server, "s", "s" }, + { "ListConnections", list_connections, "", "as" }, + { "FindConnection", find_connection, "s", "s" }, + { "CreateConnection", create_connection, "ss", "s" }, + { "RemoveConnection", remove_connection, "s", "" }, + { "LastConnection", last_connection, "", "s" }, + { "DefaultConnection", default_connection, "", "s" }, + { "ChangeDefaultConnection", change_default_connection, "s", "s"}, + { NULL, NULL, NULL, NULL } +}; + int network_init(DBusConnection *conn, struct network_conf *service_conf) { + DBusMethodVTable *methods = NULL; + DBusSignalVTable *signals = NULL; + conf = service_conf; - if (bridge_init(conf->gn_iface, conf->nap_iface) < 0) { - error("Can't init bridge module"); + if (conf->server_enabled && conf->connection_enabled) { + methods = manager_methods; + signals = connection_signals; + } else if (conf->connection_enabled) { + methods = connection_methods; + signals = connection_signals; + } else if (conf->server_enabled) + methods = server_methods; + else { + error ("All interfaces were disabled"); return -1; } @@ -995,11 +1030,20 @@ int network_init(DBusConnection *conn, struct network_conf *service_conf) * (setup connection request) contains the destination service * field that defines which service the source is connecting to. */ - if (server_init(conn, conf->iface_prefix, conf->security) < 0) - return -1; + if (conf->server_enabled) { + if (bridge_init(conf->gn_iface, conf->nap_iface) < 0) { + error("Can't init bridge module"); + return -1; + } - if (connection_init(conn, conf->iface_prefix) < 0) - return -1; + if (server_init(conn, conf->iface_prefix, conf->security) < 0) + return -1; + } + + if (conf->connection_enabled) { + if (connection_init(conn, conf->iface_prefix) < 0) + return -1; + } if (!dbus_connection_create_object_path(conn, NETWORK_PATH, NULL, manager_unregister)) { @@ -1009,20 +1053,13 @@ int network_init(DBusConnection *conn, struct network_conf *service_conf) if (!dbus_connection_register_interface(conn, NETWORK_PATH, NETWORK_MANAGER_INTERFACE, - manager_methods, - manager_signals, NULL)) { + methods, signals, NULL)) { error("Failed to register %s interface to %s", NETWORK_MANAGER_INTERFACE, NETWORK_PATH); dbus_connection_destroy_object_path(connection, NETWORK_PATH); return -1; } - if (bridge_create(BNEP_SVC_GN) < 0) - error("Can't create GN bridge"); - - if (bridge_create(BNEP_SVC_NAP) < 0) - error("Can't create NAP bridge"); - connection = dbus_connection_ref(conn); info("Registered manager path:%s", NETWORK_PATH); @@ -1039,19 +1076,17 @@ int network_init(DBusConnection *conn, struct network_conf *service_conf) void network_exit(void) { - server_exit(); - connection_exit(); + if (conf->server_enabled) + server_exit(); + + if (conf->connection_enabled) + connection_exit(); + dbus_connection_destroy_object_path(connection, NETWORK_PATH); dbus_connection_unref(connection); connection = NULL; - if (bridge_remove(BNEP_SVC_GN) < 0) - error("Can't remove GN bridge"); - - if (bridge_remove(BNEP_SVC_NAP) < 0) - error("Can't remove NAP bridge"); - bnep_cleanup(); bridge_cleanup(); } -- 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/common.c | 85 ++++++++++++++++++++++++++++++++++++++++++++------------ network/server.c | 9 +++++- 2 files changed, 76 insertions(+), 18 deletions(-) (limited to 'network') diff --git a/network/common.c b/network/common.c index cf351153..7a88a1bd 100644 --- a/network/common.c +++ b/network/common.c @@ -69,6 +69,7 @@ static const char *nap = NULL; struct bnep_data { char *devname; + char *script; int pid; }; @@ -226,12 +227,29 @@ int bnep_if_up(const char *devname, uint16_t id) { int sd, err, pid; struct ifreq ifr; - const char *argv[3], *script; + const char *argv[5]; struct bnep_data *bnep; GSpawnFlags flags; + GSList *l; - if (g_slist_find_custom(pids, devname, find_devname)) - return 0; + /* Check if a script is running */ + if ((l = g_slist_find_custom(pids, devname, find_devname))) { + bnep = l->data; + + if (bnep->script && !strcmp(bnep->script, "avahi-autoipd")) { + argv[0] = bnep->script; + argv[1] = devname; + argv[2] = "--refresh"; + argv[3] = NULL; + + flags = G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH; + g_spawn_async(NULL, (char **) argv, NULL, flags, + bnep_setup, (gpointer) devname, &pid, + NULL); + + return bnep->pid; + } + } sd = socket(AF_INET6, SOCK_DGRAM, 0); memset(&ifr, 0, sizeof(ifr)); @@ -241,7 +259,7 @@ int bnep_if_up(const char *devname, uint16_t id) if ((ioctl(sd, SIOCSIFFLAGS, (caddr_t) &ifr)) < 0) { err = errno; - error("Could not bring up %d. %s(%d)", devname, strerror(err), + error("Could not bring up %s. %s(%d)", devname, strerror(err), err); return -err; } @@ -253,18 +271,25 @@ int bnep_if_up(const char *devname, uint16_t id) goto done; if (id == BNEP_SVC_PANU) - script = panu; + bnep->script = g_strdup(panu); else if (id == BNEP_SVC_GN) - script = gn; + bnep->script = g_strdup(gn); else - script = nap; + bnep->script = g_strdup(nap); - if (!script) + if (!bnep->script) goto done; - argv[0] = script; + argv[0] = bnep->script; argv[1] = devname; - argv[2] = NULL; + + if (!strcmp(bnep->script, "avahi-autoipd")) { + argv[2] = "--no-drop-root"; + argv[3] = "--no-chroot"; + argv[4] = NULL; + } else + argv[2] = NULL; + flags = G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH; if (!g_spawn_async(NULL, (char **) argv, NULL, flags, bnep_setup, (gpointer) devname, &pid, NULL)) { @@ -283,29 +308,49 @@ done: int bnep_if_down(const char *devname) { - int sd, err; + int sd, err, pid; struct ifreq ifr; struct bnep_data *bnep; GSList *l; + GSpawnFlags flags; + const char *argv[4]; l = g_slist_find_custom(pids, devname, find_devname); if (!l) return 0; bnep = l->data; - if (bnep->pid) { - err = kill(bnep->pid, SIGTERM); - if (err < 0) - error("kill(%d, SIGTERM): %s (%d)", bnep->pid, - strerror(errno), errno); + + if (!bnep->pid) + goto done; + + if (bnep->script && !strcmp (bnep->script, "avahi-autoipd")) { + argv[0] = bnep->script; + argv[1] = devname; + argv[2] = "--kill"; + argv[3] = NULL; + + flags = G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH; + g_spawn_async(NULL, (char **) argv, NULL, flags, bnep_setup, + (gpointer) devname, &pid, NULL); + + goto done; } + /* Kill script */ + err = kill(bnep->pid, SIGTERM); + if (err < 0) + error("kill(%d, SIGTERM): %s (%d)", bnep->pid, + strerror(errno), errno); + +done: sd = socket(AF_INET6, SOCK_DGRAM, 0); memset(&ifr, 0, sizeof(ifr)); strcpy(ifr.ifr_name, devname); ifr.ifr_flags &= ~IFF_UP; + /* Bring down the interface */ if ((ioctl(sd, SIOCSIFFLAGS, (caddr_t) &ifr)) < 0) { err = errno; error("Could not bring down %d. %s(%d)", devname, strerror(err), @@ -314,7 +359,13 @@ int bnep_if_down(const char *devname) } pids = g_slist_remove(pids, bnep); - g_free(bnep->devname); + + if (bnep->devname) + g_free(bnep->devname); + + if (bnep->script) + g_free(bnep->script); + g_free(bnep); return 0; 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 1884104ecb9b6b6a9ef6cc02d04e4861c9f1f6f6 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 31 Oct 2007 14:50:35 +0000 Subject: Add MULTICAST flag so interfaces could get announced by avahi-daemon. --- network/common.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'network') diff --git a/network/common.c b/network/common.c index 7a88a1bd..c7610a47 100644 --- a/network/common.c +++ b/network/common.c @@ -246,9 +246,9 @@ int bnep_if_up(const char *devname, uint16_t id) g_spawn_async(NULL, (char **) argv, NULL, flags, bnep_setup, (gpointer) devname, &pid, NULL); - - return bnep->pid; } + + return bnep->pid; } sd = socket(AF_INET6, SOCK_DGRAM, 0); @@ -256,6 +256,7 @@ int bnep_if_up(const char *devname, uint16_t id) strcpy(ifr.ifr_name, devname); ifr.ifr_flags |= IFF_UP; + ifr.ifr_flags |= IFF_MULTICAST; if ((ioctl(sd, SIOCSIFFLAGS, (caddr_t) &ifr)) < 0) { err = errno; -- 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/bridge.c | 8 ++++++-- network/server.c | 5 ++--- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'network') diff --git a/network/bridge.c b/network/bridge.c index ad4fc72e..7dbbd616 100644 --- a/network/bridge.c +++ b/network/bridge.c @@ -42,8 +42,8 @@ #include "common.h" static int bridge_socket = -1; -static const char *gn_bridge; -static const char *nap_bridge; +static const char *gn_bridge = NULL; +static const char *nap_bridge = NULL; int bridge_init(const char *gn_iface, const char *nap_iface) { @@ -118,6 +118,10 @@ int bridge_add_interface(int id, const char *dev) if (err < 0) return err; + /* Only run scripts in GN bridges */ + if (id != BNEP_SVC_GN) + return 0; + err = bnep_if_up(name, id); if (err < 0) return err; 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 4392fbd3d96e2eea0d91f0eb9fd059ab38255986 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 26 Nov 2007 13:41:36 +0000 Subject: Update API descriptions to match new error codes --- network/network-api.txt | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'network') diff --git a/network/network-api.txt b/network/network-api.txt index e5916088..2d46abfd 100644 --- a/network/network-api.txt +++ b/network/network-api.txt @@ -19,24 +19,24 @@ Methods array{string} ListServers() Returns server path. - Possible errors: org.bluez.network.Error.DoesNotExist - org.bluez.network.Error.Failed + Possible errors: org.bluez.Error.DoesNotExist + org.bluez.Error.Failed string CreateConnection(string address, string uuid) Creates a network connection object(NAP or GN). - Possible errors: org.bluez.network.Error.AlreadyExists - org.bluez.network.Error.NotSupported - org.bluez.network.Error.ConnectionAttemptFailed - org.bluez.network.Error.Failed + Possible errors: org.bluez.Error.AlreadyExists + org.bluez.Error.NotSupported + org.bluez.Error.ConnectionAttemptFailed + org.bluez.Error.Failed void RemoveConnection(string path) Removes a network connection object for a given path. - Possible errors: org.bluez.network.Error.DoesNotExist - org.bluez.network.Error.Failed + Possible errors: org.bluez.Error.DoesNotExist + org.bluez.Error.Failed array{string} ListConnections() @@ -46,27 +46,27 @@ Methods array{string} ListServers() Returns connection path. - Possible errors: org.bluez.network.Error.DoesNotExist - org.bluez.network.Error.Failed + Possible errors: org.bluez.Error.DoesNotExist + org.bluez.Error.Failed string LastConnection() Returns last connected connection path, if none is connected fallback to last created connection. - Possible errors: org.bluez.network.Error.DoesNotExist + Possible errors: org.bluez.Error.DoesNotExist string DefaultConnection() Returns default connection path. - Possible errors: org.bluez.network.Error.DoesNotExist + Possible errors: org.bluez.Error.DoesNotExist string ChangeDefaultConnection(string pattern) Changes default connection path. - Possible errors: org.bluez.network.Error.DoesNotExist + Possible errors: org.bluez.Error.DoesNotExist Signals void ConnectionCreated(string path) @@ -90,14 +90,14 @@ Methods string GetUUID() Enable server and updates service record. - Possible errors: org.bluez.network.Error.AlreadyExists - org.bluez.network.Error.Failed + Possible errors: org.bluez.Error.AlreadyExists + org.bluez.Error.Failed void Disable() Disable server and remove service record. - Possible errors: org.bluez.network.Error.Failed + Possible errors: org.bluez.Error.Failed bool IsEnabled() @@ -151,40 +151,40 @@ Methods string GetAdapter() Returns the string representation of connected host. - Possible errors: org.bluez.network.Error.Failed + Possible errors: org.bluez.Error.Failed string GetDescription() Returns the string description of connected host. - Possible errors: org.bluez.network.Error.Failed + Possible errors: org.bluez.Error.Failed string GetInterface() Returns the string network interface. - Possible errors: org.bluez.network.Error.Failed + Possible errors: org.bluez.Error.Failed string Connect() Connects to host and return the network interface created. - Possible errors: org.bluez.network.Error.ConnectionAttemptFailed - org.bluez.network.Error.Failed + Possible errors: org.bluez.Error.ConnectionAttemptFailed + org.bluez.Error.Failed void CancelConnect() Abort connection attempt in case of errors or timeouts in the client. - Possible errors: org.bluez.network.Error.Failed + Possible errors: org.bluez.Error.Failed void Disconnect() Disconnects to host. - Possible errors: org.bluez.network.Error.Failed + Possible errors: org.bluez.Error.Failed bool IsConnected() -- 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/Makefile.am | 2 +- network/connection.c | 20 ++++++------- network/error.c | 82 ---------------------------------------------------- network/error.h | 35 ---------------------- network/manager.c | 60 ++++++++++++++++++++------------------ network/server.c | 18 ++++++------ 6 files changed, 52 insertions(+), 165 deletions(-) delete mode 100644 network/error.c delete mode 100644 network/error.h (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index c8ca039e..2f8a7c3d 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -11,7 +11,7 @@ servicedir = $(libdir)/bluetooth service_PROGRAMS = bluetoothd-service-network bluetoothd_service_network_SOURCES = main.c \ - manager.h manager.c error.h error.c \ + manager.h manager.c \ server.h server.c bridge.h bridge.c \ connection.h connection.c common.h common.c diff --git a/network/connection.c b/network/connection.c index 933cdd98..1628a038 100644 --- a/network/connection.c +++ b/network/connection.c @@ -181,7 +181,7 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, failed: if (nc->state != DISCONNECTED) { nc->state = DISCONNECTED; - err_connection_failed(connection, nc->msg, "bnep failed"); + error_connection_attempt_failed(connection, nc->msg, EIO); g_io_channel_close(chan); } return FALSE; @@ -254,7 +254,7 @@ static gboolean l2cap_connect_cb(GIOChannel *chan, return FALSE; failed: nc->state = DISCONNECTED; - err_connection_failed(connection, nc->msg, strerror(errno)); + error_connection_attempt_failed(connection, nc->msg, errno); g_io_channel_close(chan); return FALSE; } @@ -383,7 +383,7 @@ static DBusHandlerResult get_name(DBusConnection *conn, DBusMessage *msg, DBusMessage *reply; if (!nc->name) { - err_failed(conn, msg, "Cannot find service name"); + error_failed(conn, msg, "Cannot find service name"); return DBUS_HANDLER_RESULT_HANDLED; } @@ -405,7 +405,7 @@ static DBusHandlerResult get_description(DBusConnection *conn, DBusMessage *reply; if (!nc->desc) { - err_failed(conn, msg, "Cannot find service description"); + error_failed(conn, msg, "Cannot find service description"); return DBUS_HANDLER_RESULT_HANDLED; } @@ -427,7 +427,7 @@ static DBusHandlerResult get_interface(DBusConnection *conn, DBusMessage *msg, DBusMessage *reply; if (nc->state != CONNECTED) { - err_failed(conn, msg, "Device not connected"); + error_failed(conn, msg, "Device not connected"); return DBUS_HANDLER_RESULT_HANDLED; } @@ -449,14 +449,14 @@ static DBusHandlerResult connection_connect(DBusConnection *conn, DBusError derr; if (nc->state != DISCONNECTED) { - err_failed(conn, msg, "Device already connected"); + error_failed(conn, msg, "Device already connected"); return DBUS_HANDLER_RESULT_HANDLED; } dbus_error_init(&derr); if (!dbus_message_get_args(msg, &derr, 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; } @@ -482,7 +482,7 @@ fail: nc->msg = NULL; } nc->state = DISCONNECTED; - err_connection_failed(conn, msg, strerror(errno)); + error_connection_attempt_failed(conn, msg, errno); return DBUS_HANDLER_RESULT_HANDLED; } @@ -493,7 +493,7 @@ static DBusHandlerResult connection_cancel(DBusConnection *conn, DBusMessage *reply; if (nc->state != CONNECTING) { - err_failed(conn, msg, "Device has no pending connect"); + error_failed(conn, msg, "Device has no pending connect"); return DBUS_HANDLER_RESULT_HANDLED; } @@ -512,7 +512,7 @@ static DBusHandlerResult connection_disconnect(DBusConnection *conn, DBusMessage *reply; if (nc->state != CONNECTED) { - err_failed(conn, msg, "Device not connected"); + error_failed(conn, msg, "Device not connected"); return DBUS_HANDLER_RESULT_HANDLED; } diff --git a/network/error.c b/network/error.c deleted file mode 100644 index 24b3d124..00000000 --- a/network/error.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * - * 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 - -#include "dbus.h" -#include "error.h" - -#define NETWORK_ERROR_INTERFACE "org.bluez.network.Error" - -DBusHandlerResult err_does_not_exist(DBusConnection *conn, DBusMessage *msg, - const char *str) -{ - return send_message_and_unref(conn, - dbus_message_new_error(msg, - NETWORK_ERROR_INTERFACE ".DoesNotExist", str)); -} - -DBusHandlerResult err_failed(DBusConnection *conn, DBusMessage *msg, - const char *str) -{ - return send_message_and_unref(conn, - dbus_message_new_error(msg, - NETWORK_ERROR_INTERFACE ".Failed", str)); -} - -DBusHandlerResult err_connection_failed(DBusConnection *conn, - DBusMessage *msg, const char *str) -{ - return send_message_and_unref(conn, - dbus_message_new_error(msg, - NETWORK_ERROR_INTERFACE".ConnectionAttemptFailed", - str)); -} - -DBusHandlerResult err_invalid_args(DBusConnection *conn, - DBusMessage *msg, const char *str) -{ - return send_message_and_unref(conn, - dbus_message_new_error(msg, - NETWORK_ERROR_INTERFACE ".InvalidArguments", str)); -} - -DBusHandlerResult err_not_supported(DBusConnection *conn, DBusMessage *msg) -{ - return send_message_and_unref(conn, - dbus_message_new_error(msg, - NETWORK_ERROR_INTERFACE ".NotSupported", - "The service is not supported by the remote device")); -} - -DBusHandlerResult err_already_exists(DBusConnection *conn, - DBusMessage *msg, const char *str) -{ - return send_message_and_unref(conn, - dbus_message_new_error(msg, - NETWORK_ERROR_INTERFACE ".AlreadyExists", str)); -} diff --git a/network/error.h b/network/error.h deleted file mode 100644 index d4162d5c..00000000 --- a/network/error.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * - * 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 - * - */ - -DBusHandlerResult err_does_not_exist(DBusConnection *conn, - DBusMessage *msg, const char *str); -DBusHandlerResult err_failed(DBusConnection *conn, DBusMessage *msg, - const char *str); -DBusHandlerResult err_connection_failed(DBusConnection *conn, - DBusMessage *msg, const char *str); - -DBusHandlerResult err_invalid_args(DBusConnection *conn, - DBusMessage *msg, const char *str); -DBusHandlerResult err_not_supported(DBusConnection *conn, DBusMessage *msg); -DBusHandlerResult err_already_exists(DBusConnection *conn, - DBusMessage *msg, const char *str); diff --git a/network/manager.c b/network/manager.c index 6355f032..5855cf1f 100644 --- a/network/manager.c +++ b/network/manager.c @@ -171,19 +171,19 @@ static DBusHandlerResult remove_path(DBusConnection *conn, if (!dbus_message_get_args(msg, &derr, DBUS_TYPE_STRING, &path, 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; } l = g_slist_find_custom(*list, path, (GCompareFunc) strcmp); if (!l) - return err_does_not_exist(conn, msg, "Path doesn't exist"); + return error_does_not_exist(conn, msg, "Path doesn't exist"); /* Remove references from the storage */ if (*list == connection_paths) { if (connection_has_pending(path)) - return err_failed(conn, msg, "Connection is Busy"); + return error_failed(conn, msg, "Connection is Busy"); connection_remove_stored(path); /* Reset default connection */ @@ -226,11 +226,13 @@ static void pan_record_reply(DBusPendingCall *call, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { + /* FIXME: forward error as is */ if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) - err_connection_failed(pr->conn, pr->msg, derr.message); + error_connection_attempt_failed(pr->conn, pr->msg, + EINVAL); else - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("GetRemoteServiceRecord failed: %s(%s)", derr.name, derr.message); @@ -240,13 +242,13 @@ static void pan_record_reply(DBusPendingCall *call, void *data) if (!dbus_message_get_args(reply, &derr, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &rec_bin, &len, DBUS_TYPE_INVALID)) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("%s: %s", derr.name, derr.message); goto fail; } if (len == 0) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("Invalid PAN service record length"); goto fail; } @@ -276,7 +278,7 @@ static void pan_record_reply(DBusPendingCall *call, void *data) if (connection_register(pr->path, &pr->src, &pr->dst, pr->id, name, desc) < 0) { - err_failed(pr->conn, pr->msg, "D-Bus path registration failed"); + error_failed(pr->conn, pr->msg, "D-Bus path registration failed"); goto fail; } @@ -334,11 +336,13 @@ static void pan_handle_reply(DBusPendingCall *call, void *data) dbus_error_init(&derr); if (dbus_set_error_from_message(&derr, reply)) { + /* FIXME : forward error as is */ if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) - err_connection_failed(pr->conn, pr->msg, derr.message); + error_connection_attempt_failed(pr->conn, pr->msg, + EINVAL); else - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("GetRemoteServiceHandles: %s(%s)", derr.name, derr.message); @@ -348,18 +352,18 @@ static void pan_handle_reply(DBusPendingCall *call, void *data) if (!dbus_message_get_args(reply, &derr, DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &phandle, &len, DBUS_TYPE_INVALID)) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); error("%s: %s", derr.name, derr.message); goto fail; } if (!len) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); goto fail; } if (get_record(pr, *phandle, pan_record_reply) < 0) { - err_not_supported(pr->conn, pr->msg); + error_not_supported(pr->conn, pr->msg); goto fail; } @@ -420,7 +424,7 @@ static DBusHandlerResult find_server(DBusConnection *conn, if (!dbus_message_get_args(msg, &derr, DBUS_TYPE_STRING, &pattern, 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; } @@ -432,7 +436,7 @@ static DBusHandlerResult find_server(DBusConnection *conn, } if (list == NULL) { - err_failed(conn, msg, "No such server"); + error_does_not_exist(conn, msg, "No such server"); return DBUS_HANDLER_RESULT_HANDLED; } @@ -483,7 +487,7 @@ static DBusHandlerResult find_connection(DBusConnection *conn, if (!dbus_message_get_args(msg, &derr, DBUS_TYPE_STRING, &pattern, 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; } @@ -491,7 +495,7 @@ static DBusHandlerResult find_connection(DBusConnection *conn, list = find_connection_pattern(conn, pattern); if (list == NULL) { - err_failed(conn, msg, "No such connection"); + error_does_not_exist(conn, msg, "No such connection"); return DBUS_HANDLER_RESULT_HANDLED; } @@ -579,21 +583,21 @@ static DBusHandlerResult create_connection(DBusConnection *conn, DBUS_TYPE_STRING, &addr, DBUS_TYPE_STRING, &str, 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; } id = bnep_service_id(str); if (id != BNEP_SVC_GN && id != BNEP_SVC_NAP && id != BNEP_SVC_PANU) - return err_invalid_args(conn, msg, "Not supported"); + return error_invalid_arguments(conn, msg, "Not supported"); snprintf(key, 32, "%s#%s", addr, bnep_name(id)); /* Checks if the connection was already been made */ for (l = connection_paths; l; l = l->next) { if (connection_find_data(l->data, key) == 0) { - err_already_exists(conn, msg, + error_already_exists(conn, msg, "Connection Already exists"); return DBUS_HANDLER_RESULT_HANDLED; } @@ -602,14 +606,14 @@ static DBusHandlerResult create_connection(DBusConnection *conn, bacpy(&src, BDADDR_ANY); dev_id = hci_get_route(&src); if (dev_id < 0 || hci_devba(dev_id, &src) < 0) - return err_failed(conn, msg, "Adapter not available"); + return error_failed(conn, msg, "Adapter not available"); pr = g_new0(struct pending_reply, 1); pr->adapter_path = find_adapter(conn, &src); if (!pr->adapter_path) { pending_reply_free (pr); - return err_failed(conn, msg, "Adapter not available"); + return error_failed(conn, msg, "Adapter not available"); } pr->conn = dbus_connection_ref(conn); @@ -623,7 +627,7 @@ static DBusHandlerResult create_connection(DBusConnection *conn, NETWORK_PATH"/connection%d", net_uid++); if (get_handles(pr, pan_handle_reply) < 0) - return err_not_supported(conn, msg); + return error_not_supported(conn, msg); return DBUS_HANDLER_RESULT_HANDLED; } @@ -642,7 +646,7 @@ static DBusHandlerResult last_connection(DBusConnection *conn, if (connection_paths == NULL || g_slist_length (connection_paths) == 0) { - err_does_not_exist(conn, msg, "No such connection"); + error_does_not_exist(conn, msg, "No such connection"); return DBUS_HANDLER_RESULT_HANDLED; } @@ -666,7 +670,7 @@ static DBusHandlerResult default_connection(DBusConnection *conn, if (connection_paths == NULL || g_slist_length (connection_paths) == 0) { - err_does_not_exist(conn, msg, "No such connection"); + error_does_not_exist(conn, msg, "No such connection"); return DBUS_HANDLER_RESULT_HANDLED; } @@ -700,14 +704,14 @@ static DBusHandlerResult change_default_connection(DBusConnection *conn, if (!dbus_message_get_args(msg, &derr, DBUS_TYPE_STRING, &pattern, 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 (connection_paths == NULL || g_slist_length (connection_paths) == 0) { - err_does_not_exist(conn, msg, "No such connection"); + error_does_not_exist(conn, msg, "No such connection"); return DBUS_HANDLER_RESULT_HANDLED; } @@ -718,7 +722,7 @@ static DBusHandlerResult change_default_connection(DBusConnection *conn, list = find_connection_pattern(conn, pattern); if (list == NULL) { - err_failed(conn, msg, "No such connection"); + error_does_not_exist(conn, msg, "No such connection"); return DBUS_HANDLER_RESULT_HANDLED; } else 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 20535eb126256b54a9822935a120a13494ff056b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 9 Dec 2007 02:54:19 +0000 Subject: Make sure to install network.conf --- network/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index 2f8a7c3d..3f79b311 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -3,7 +3,7 @@ if NETWORKSERVICE if CONFIGFILES confdir = $(sysconfdir)/bluetooth -conf_DATA = network.service +conf_DATA = network.service network.conf endif servicedir = $(libdir)/bluetooth -- cgit From 28d439d57877be7fc541c406e976f063844915a2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Wed, 12 Dec 2007 15:58:00 +0000 Subject: Don't install network.conf for now --- network/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index 3f79b311..2f8a7c3d 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -3,7 +3,7 @@ if NETWORKSERVICE if CONFIGFILES confdir = $(sysconfdir)/bluetooth -conf_DATA = network.service network.conf +conf_DATA = network.service endif servicedir = $(libdir)/bluetooth -- 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/bridge.c | 2 +- network/bridge.h | 2 +- network/common.c | 2 +- network/common.h | 2 +- network/connection.c | 2 +- network/connection.h | 2 +- network/main.c | 2 +- network/manager.c | 2 +- network/manager.h | 2 +- network/server.c | 2 +- network/server.h | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) (limited to 'network') diff --git a/network/bridge.c b/network/bridge.c index 7dbbd616..c4c3a064 100644 --- a/network/bridge.c +++ b/network/bridge.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 diff --git a/network/bridge.h b/network/bridge.h index 0861cfb7..13166520 100644 --- a/network/bridge.h +++ b/network/bridge.h @@ -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 diff --git a/network/common.c b/network/common.c index c7610a47..50105272 100644 --- a/network/common.c +++ b/network/common.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 diff --git a/network/common.h b/network/common.h index 2b475864..e6aa90f6 100644 --- a/network/common.h +++ b/network/common.h @@ -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 diff --git a/network/connection.c b/network/connection.c index 1628a038..6025984d 100644 --- a/network/connection.c +++ b/network/connection.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 diff --git a/network/connection.h b/network/connection.h index 5e560811..b2d3641d 100644 --- a/network/connection.h +++ b/network/connection.h @@ -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 diff --git a/network/main.c b/network/main.c index 8c9bdc54..914cb9c1 100644 --- a/network/main.c +++ b/network/main.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 diff --git a/network/manager.c b/network/manager.c index 5855cf1f..1647e34e 100644 --- a/network/manager.c +++ b/network/manager.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 diff --git a/network/manager.h b/network/manager.h index 622665e8..1b938c8b 100644 --- a/network/manager.h +++ b/network/manager.h @@ -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 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 diff --git a/network/server.h b/network/server.h index 839aea4b..6fb06b58 100644 --- a/network/server.h +++ b/network/server.h @@ -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') 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 0331fdbe6e368524f656b18b8ed4f7bc32b81772 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Fri, 29 Feb 2008 19:56:22 +0000 Subject: network: cleanup - unnecessary definition --- network/manager.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'network') diff --git a/network/manager.h b/network/manager.h index 1b938c8b..6d440a55 100644 --- a/network/manager.h +++ b/network/manager.h @@ -41,6 +41,3 @@ struct network_conf { int network_init(DBusConnection *conn, struct network_conf *service_conf); void network_exit(void); - -int network_del_stored_info(bdaddr_t *src, uint16_t uuid); -int network_store_info(bdaddr_t *src, uint16_t uuid, gboolean enable); -- cgit From c6638ee5c399991f1496b213de64529fcd8556eb Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 7 Mar 2008 17:45:29 +0000 Subject: Report socket error when bridge module fails to load. --- network/bridge.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'network') diff --git a/network/bridge.c b/network/bridge.c index c4c3a064..2c8570e4 100644 --- a/network/bridge.c +++ b/network/bridge.c @@ -38,6 +38,7 @@ #include #include +#include "logging.h" #include "bridge.h" #include "common.h" @@ -55,8 +56,11 @@ int bridge_init(const char *gn_iface, const char *nap_iface) #endif bridge_socket = socket(AF_INET, SOCK_STREAM, 0); - if (bridge_socket < 0) + if (bridge_socket < 0) { + error("Failed to open bridge socket: %s (%d)", + strerror(errno), errno); return -errno; + } gn_bridge = gn_iface; nap_bridge = nap_iface; -- cgit From 88e798a8b8126d997ded2adcebafbc3fb1fcb509 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sat, 22 Mar 2008 15:49:07 +0000 Subject: Convert network service into a plugin --- network/Makefile.am | 22 ++++++------- network/main.c | 85 ++++++++++++------------------------------------- network/manager.c | 4 +-- network/manager.h | 4 +-- network/network.service | 5 --- 5 files changed, 34 insertions(+), 86 deletions(-) delete mode 100644 network/network.service (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index 2f8a7c3d..da92a8c2 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -1,28 +1,24 @@ if NETWORKSERVICE -if CONFIGFILES -confdir = $(sysconfdir)/bluetooth +plugindir = $(libdir)/bluetooth/plugins -conf_DATA = network.service -endif - -servicedir = $(libdir)/bluetooth +plugin_LTLIBRARIES = libnetwork.la -service_PROGRAMS = bluetoothd-service-network - -bluetoothd_service_network_SOURCES = main.c \ +libnetwork_la_SOURCES = main.c \ manager.h manager.c \ server.h server.c bridge.h bridge.c \ connection.h connection.c common.h common.c LDADD = $(top_builddir)/common/libhelper.a \ - @GLIB_LIBS@ @HAL_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@ + @GLIB_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@ endif -AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ @HAL_CFLAGS@ @GLIB_CFLAGS@ +AM_LDFLAGS = -module -avoid-version -export-symbols-regex bluetooth_plugin_desc + +AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ @GLIB_CFLAGS@ -INCLUDES = -I$(top_srcdir)/common +INCLUDES = -I$(top_srcdir)/common -I$(top_srcdir)/hcid -EXTRA_DIST = network.service network.conf network-api.txt test-network +EXTRA_DIST = network.conf network-api.txt test-network MAINTAINERCLEANFILES = Makefile.in diff --git a/network/main.c b/network/main.c index 914cb9c1..e749762e 100644 --- a/network/main.c +++ b/network/main.c @@ -25,28 +25,22 @@ #include #endif -#include -#include -#include -#include #include -#include -#include - +#include #include +#include +#include + +#include "plugin.h" #include "dbus.h" #include "logging.h" - #include "manager.h" -#include "hal.h" #define IFACE_PREFIX "bnep%d" #define GN_IFACE "pan0" #define NAP_IFACE "pan1" -static GMainLoop *main_loop; - static struct network_conf conf = { .connection_enabled = TRUE, .server_enabled = TRUE, @@ -59,11 +53,6 @@ static struct network_conf conf = { .security = TRUE }; -static void sig_term(int sig) -{ - g_main_loop_quit(main_loop); -} - static void read_config(const char *file) { GKeyFile *keyfile; @@ -165,63 +154,31 @@ done: conf.security ? "true" : "false"); } -int main(int argc, char *argv[]) -{ - DBusConnection *conn; - struct sigaction sa; - - start_logging("network", "Bluetooth Network daemon"); - - memset(&sa, 0, sizeof(sa)); - sa.sa_flags = SA_NOCLDSTOP; - sa.sa_handler = sig_term; - sigaction(SIGTERM, &sa, NULL); - sigaction(SIGINT, &sa, NULL); +static DBusConnection *conn; - sa.sa_handler = SIG_IGN; - sigaction(SIGCHLD, &sa, NULL); - sigaction(SIGPIPE, &sa, NULL); - - enable_debug(); +static int network_init(void) +{ + conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (conn == NULL) + return -EIO; read_config(CONFIGDIR "/network.conf"); - main_loop = g_main_loop_new(NULL, FALSE); - - conn = dbus_bus_system_setup_with_main_loop(NULL, NULL, NULL); - if (!conn) { - g_main_loop_unref(main_loop); - exit(1); - } - - hal_init(conn); - - hal_create_device(NULL); - - if (network_init(conn, &conf) < 0) { + if (network_manager_init(conn, &conf) < 0) { dbus_connection_unref(conn); - g_main_loop_unref(main_loop); - exit(1); + return -EIO; } - if (argc > 1 && !strcmp(argv[1], "-s")) - register_external_service(conn, "network", "Network service", ""); + register_external_service(conn, "network", "Network service", ""); - g_main_loop_run(main_loop); - - network_exit(); - - hal_remove_device(NULL); + return 0; +} - hal_cleanup(); +static void network_exit(void) +{ + network_manager_exit(); dbus_connection_unref(conn); - - g_main_loop_unref(main_loop); - - info("Exit"); - - stop_logging(); - - return 0; } + +BLUETOOTH_PLUGIN_DEFINE("network", network_init, network_exit) diff --git a/network/manager.c b/network/manager.c index 1647e34e..0808706e 100644 --- a/network/manager.c +++ b/network/manager.c @@ -1003,7 +1003,7 @@ static DBusMethodVTable manager_methods[] = { { NULL, NULL, NULL, NULL } }; -int network_init(DBusConnection *conn, struct network_conf *service_conf) +int network_manager_init(DBusConnection *conn, struct network_conf *service_conf) { DBusMethodVTable *methods = NULL; DBusSignalVTable *signals = NULL; @@ -1078,7 +1078,7 @@ int network_init(DBusConnection *conn, struct network_conf *service_conf) return 0; } -void network_exit(void) +void network_manager_exit(void) { if (conf->server_enabled) server_exit(); diff --git a/network/manager.h b/network/manager.h index 6d440a55..9b16c2a3 100644 --- a/network/manager.h +++ b/network/manager.h @@ -39,5 +39,5 @@ struct network_conf { char *nap_iface; }; -int network_init(DBusConnection *conn, struct network_conf *service_conf); -void network_exit(void); +int network_manager_init(DBusConnection *conn, struct network_conf *service_conf); +void network_manager_exit(void); diff --git a/network/network.service b/network/network.service deleted file mode 100644 index 444bdff3..00000000 --- a/network/network.service +++ /dev/null @@ -1,5 +0,0 @@ -[Bluetooth Service] -Identifier=network -Name=Network service -Description=Bluetooth Personal Area Network service -Autostart=false -- 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/Makefile.am | 2 +- network/server.c | 197 ++++++++++++---------------------------------------- 2 files changed, 46 insertions(+), 153 deletions(-) (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index da92a8c2..5218ce6f 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -17,7 +17,7 @@ AM_LDFLAGS = -module -avoid-version -export-symbols-regex bluetooth_plugin_desc AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ @GLIB_CFLAGS@ -INCLUDES = -I$(top_srcdir)/common -I$(top_srcdir)/hcid +INCLUDES = -I$(top_srcdir)/common -I$(top_srcdir)/hcid -I$(top_srcdir)/sdpd EXTRA_DIST = network.conf network-api.txt test-network 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') 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 f9ba262724b4605bf45d0a1fd2c87eeeac714917 Mon Sep 17 00:00:00 2001 From: Vinicius Gomes Date: Thu, 27 Mar 2008 13:23:21 +0000 Subject: network: removing some blocking dbus calls from manager.c --- network/manager.c | 59 +++---------------------------------------------------- 1 file changed, 3 insertions(+), 56 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index 0808706e..a65f56a5 100644 --- a/network/manager.c +++ b/network/manager.c @@ -229,7 +229,7 @@ static void pan_record_reply(DBusPendingCall *call, void *data) /* FIXME: forward error as is */ if (dbus_error_has_name(&derr, "org.bluez.Error.ConnectionAttemptFailed")) - error_connection_attempt_failed(pr->conn, pr->msg, + error_connection_attempt_failed(pr->conn, pr->msg, EINVAL); else error_not_supported(pr->conn, pr->msg); @@ -511,60 +511,6 @@ static DBusHandlerResult find_connection(DBusConnection *conn, return send_message_and_unref(conn, reply); } -char *find_adapter(DBusConnection *conn, bdaddr_t *src) -{ - DBusMessage *msg, *reply; - DBusError derr; - char address[18], *addr_ptr = address; - char *path, *ret; - - msg = dbus_message_new_method_call("org.bluez", "/org/bluez", - "org.bluez.Manager", - "FindAdapter"); - if (!msg) { - error("Unable to allocate new method call"); - return NULL; - } - - ba2str(src, address); - - dbus_message_append_args(msg, DBUS_TYPE_STRING, &addr_ptr, - 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) || - dbus_set_error_from_message(&derr, reply)) { - error("FindAdapter(%s) failed: %s", address, derr.message); - dbus_error_free(&derr); - return NULL; - } - - dbus_error_init(&derr); - dbus_message_get_args(reply, &derr, - DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); - - if (dbus_error_is_set(&derr)) { - error("Unable to get message args"); - dbus_message_unref(reply); - dbus_error_free(&derr); - return FALSE; - } - - ret = g_strdup(path); - - dbus_message_unref(reply); - - debug("Got path %s for adapter with address %s", ret, address); - - return ret; -} - static DBusHandlerResult create_connection(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -610,7 +556,8 @@ static DBusHandlerResult create_connection(DBusConnection *conn, pr = g_new0(struct pending_reply, 1); - pr->adapter_path = find_adapter(conn, &src); + /* FIXME just to maintain compatibility */ + pr->adapter_path = g_strdup_printf("/org/bluez/hci%d", dev_id); if (!pr->adapter_path) { pending_reply_free (pr); return error_failed(conn, msg, "Adapter not available"); -- cgit From 31f2ffeffd5ff735329821113c4d4d4d54f4f8dd Mon Sep 17 00:00:00 2001 From: Vinicius Gomes Date: Fri, 11 Apr 2008 23:04:17 +0000 Subject: network: fixes a memory leak when reading the Disable config option. --- network/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'network') diff --git a/network/main.c b/network/main.c index e749762e..66266b90 100644 --- a/network/main.c +++ b/network/main.c @@ -57,7 +57,7 @@ static void read_config(const char *file) { GKeyFile *keyfile; GError *err = NULL; - const char *disabled; + char *disabled; keyfile = g_key_file_new(); @@ -79,6 +79,7 @@ static void read_config(const char *file) if (strstr(disabled, "Server")) conf.server_enabled = FALSE; } + g_free(disabled); conf.security = !g_key_file_get_boolean(keyfile, "General", "DisableSecurity", &err); -- 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') 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') 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 098cd10838193272c669348c5ffd0410218e1bcc Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 1 May 2008 01:05:46 +0000 Subject: fixed service authorization --- network/main.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'network') diff --git a/network/main.c b/network/main.c index 66266b90..2dfd6696 100644 --- a/network/main.c +++ b/network/main.c @@ -41,6 +41,17 @@ #define GN_IFACE "pan0" #define NAP_IFACE "pan1" +#define PANU_UUID "00001115-0000-1000-8000-00805f9b34fb" +#define NAP_UUID "00001116-0000-1000-8000-00805f9b34fb" +#define GN_UUID "00001117-0000-1000-8000-00805f9b34fb" + +static const char *uuids[] = { + PANU_UUID, + NAP_UUID, + GN_UUID, + NULL +}; + static struct network_conf conf = { .connection_enabled = TRUE, .server_enabled = TRUE, @@ -170,6 +181,8 @@ static int network_init(void) return -EIO; } + register_uuids("network", &uuids); + register_external_service(conn, "network", "Network service", ""); return 0; -- cgit From 3f8860031e5241fbb145fdd71e1a46c2c28f393e Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Thu, 1 May 2008 01:23:02 +0000 Subject: fixed build warnings --- network/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'network') diff --git a/network/main.c b/network/main.c index 2dfd6696..576ead8e 100644 --- a/network/main.c +++ b/network/main.c @@ -33,6 +33,7 @@ #include #include "plugin.h" +#include "dbus-service.h" #include "dbus.h" #include "logging.h" #include "manager.h" @@ -181,7 +182,7 @@ static int network_init(void) return -EIO; } - register_uuids("network", &uuids); + register_uuids("network", uuids); register_external_service(conn, "network", "Network service", ""); -- 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/main.c | 4 +--- network/server.c | 6 +++--- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'network') diff --git a/network/main.c b/network/main.c index 576ead8e..037ee062 100644 --- a/network/main.c +++ b/network/main.c @@ -29,12 +29,10 @@ #include #include -#include -#include +#include "dbus.h" #include "plugin.h" #include "dbus-service.h" -#include "dbus.h" #include "logging.h" #include "manager.h" 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') 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 0adb4e98f284a3d6c4b6bc11599a8fe0be980126 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 6 May 2008 18:40:54 +0000 Subject: Add some useful info calls for debugging. --- network/bridge.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'network') diff --git a/network/bridge.c b/network/bridge.c index 2c8570e4..b2e61b65 100644 --- a/network/bridge.c +++ b/network/bridge.c @@ -54,7 +54,6 @@ int bridge_init(const char *gn_iface, const char *nap_iface) if (stat("/sys/module/bridge", &st) < 0) return -EOPNOTSUPP; #endif - bridge_socket = socket(AF_INET, SOCK_STREAM, 0); if (bridge_socket < 0) { error("Failed to open bridge socket: %s (%d)", @@ -64,6 +63,7 @@ int bridge_init(const char *gn_iface, const char *nap_iface) gn_bridge = gn_iface; nap_bridge = nap_iface; + return 0; } @@ -83,6 +83,8 @@ int bridge_create(int id) if (err < 0) return -errno; + info("bridge %s created", name); + return 0; } @@ -99,6 +101,8 @@ int bridge_remove(int id) if (err < 0) return -errno; + info("bridge %s removed", name); + return 0; } @@ -122,9 +126,7 @@ int bridge_add_interface(int id, const char *dev) if (err < 0) return err; - /* Only run scripts in GN bridges */ - if (id != BNEP_SVC_GN) - return 0; + info("bridge %s: interface %s added", name, dev); err = bnep_if_up(name, id); if (err < 0) -- cgit From d6f0804e827a829edb7faef9ddbd53332c1ad8cb Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 6 May 2008 21:46:05 +0000 Subject: Fix bug that prevent bnep interfaces to come up on reconnection. --- network/bridge.c | 1 + network/common.c | 64 ++++++++++++++++++++++++++++------------------------ network/connection.c | 1 + 3 files changed, 36 insertions(+), 30 deletions(-) (limited to 'network') diff --git a/network/bridge.c b/network/bridge.c index b2e61b65..ba59f380 100644 --- a/network/bridge.c +++ b/network/bridge.c @@ -119,6 +119,7 @@ int bridge_add_interface(int id, const char *dev) if (ifindex == 0) return -ENODEV; + memset(&ifr, 0, sizeof(ifr)); strncpy(ifr.ifr_name, name, IFNAMSIZ); ifr.ifr_ifindex = ifindex; diff --git a/network/common.c b/network/common.c index 50105272..3d0fefb7 100644 --- a/network/common.c +++ b/network/common.c @@ -164,6 +164,7 @@ int bnep_kill_connection(bdaddr_t *dst) { struct bnep_conndel_req req; + memset(&req, 0, sizeof(req)); baswap((bdaddr_t *)&req.dst, dst); req.flags = 0; if (ioctl(ctl, BNEPCONNDEL, &req)) { @@ -192,10 +193,12 @@ int bnep_kill_all_connections(void) } for (i=0; i < req.cnum; i++) { - struct bnep_conndel_req req; - memcpy(req.dst, ci[i].dst, ETH_ALEN); - req.flags = 0; - ioctl(ctl, BNEPCONNDEL, &req); + struct bnep_conndel_req del; + + memset(&del, 0, sizeof(del)); + memcpy(del.dst, ci[i].dst, ETH_ALEN); + del.flags = 0; + ioctl(ctl, BNEPCONNDEL, &del); } return 0; } @@ -204,6 +207,7 @@ int bnep_connadd(int sk, uint16_t role, char *dev) { struct bnep_connadd_req req; + memset(&req, 0, sizeof(req)); strncpy(req.device, dev, 16); req.device[15] = '\0'; req.sock = sk; @@ -223,17 +227,31 @@ static void bnep_setup(gpointer data) { } +static int bnep_exec(const char **argv) +{ + int pid; + GSpawnFlags flags = G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH; + + if (!g_spawn_async(NULL, (char **) argv, NULL, flags, bnep_setup, NULL, + &pid, NULL)) { + error("Unable to execute %s %s", *argv[0], *argv[1]); + return -EINVAL; + } + + return pid; +} + int bnep_if_up(const char *devname, uint16_t id) { - int sd, err, pid; + int sd, err; struct ifreq ifr; const char *argv[5]; - struct bnep_data *bnep; - GSpawnFlags flags; + struct bnep_data *bnep = NULL; GSList *l; /* Check if a script is running */ - if ((l = g_slist_find_custom(pids, devname, find_devname))) { + l = g_slist_find_custom(pids, devname, find_devname); + if (l) { bnep = l->data; if (bnep->script && !strcmp(bnep->script, "avahi-autoipd")) { @@ -242,13 +260,8 @@ int bnep_if_up(const char *devname, uint16_t id) argv[2] = "--refresh"; argv[3] = NULL; - flags = G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH; - g_spawn_async(NULL, (char **) argv, NULL, flags, - bnep_setup, (gpointer) devname, &pid, - NULL); + bnep->pid = bnep_exec(argv); } - - return bnep->pid; } sd = socket(AF_INET6, SOCK_DGRAM, 0); @@ -265,6 +278,9 @@ int bnep_if_up(const char *devname, uint16_t id) return -err; } + if (bnep) + return bnep->pid; + bnep = g_new0(struct bnep_data, 1); bnep->devname = g_strdup(devname); @@ -291,15 +307,8 @@ int bnep_if_up(const char *devname, uint16_t id) } else argv[2] = NULL; - flags = G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH; - if (!g_spawn_async(NULL, (char **) argv, NULL, flags, bnep_setup, - (gpointer) devname, &pid, NULL)) { - error("Unable to execute %s", argv[0]); - return -EINVAL; - } - - bnep->pid = pid; - g_child_watch_add(pid, script_exited, bnep); + bnep->pid = bnep_exec(argv); + g_child_watch_add(bnep->pid, script_exited, bnep); done: pids = g_slist_append(pids, bnep); @@ -325,7 +334,7 @@ int bnep_if_down(const char *devname) if (!bnep->pid) goto done; - if (bnep->script && !strcmp (bnep->script, "avahi-autoipd")) { + if (bnep->script && !strcmp(bnep->script, "avahi-autoipd")) { argv[0] = bnep->script; argv[1] = devname; argv[2] = "--kill"; @@ -352,12 +361,7 @@ done: ifr.ifr_flags &= ~IFF_UP; /* Bring down the interface */ - if ((ioctl(sd, SIOCSIFFLAGS, (caddr_t) &ifr)) < 0) { - err = errno; - error("Could not bring down %d. %s(%d)", devname, strerror(err), - err); - return -err; - } + ioctl(sd, SIOCSIFFLAGS, (caddr_t) &ifr); pids = g_slist_remove(pids, bnep); diff --git a/network/connection.c b/network/connection.c index 6025984d..18f79130 100644 --- a/network/connection.c +++ b/network/connection.c @@ -90,6 +90,7 @@ static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond, DBUS_TYPE_INVALID); } info("%s disconnected", nc->dev); + bnep_if_down(nc->dev); nc->state = DISCONNECTED; memset(nc->dev, 0, 16); strncpy(nc->dev, prefix, strlen(prefix)); -- cgit From f85b9560ece47c94ec82466cba9c44da715591d9 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 7 May 2008 18:39:36 +0000 Subject: Make bt_l2cap_connect to take mtu as paramter. --- network/connection.c | 111 +++++++++------------------------------------------ 1 file changed, 19 insertions(+), 92 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 18f79130..b5ef61ba 100644 --- a/network/connection.c +++ b/network/connection.c @@ -36,6 +36,7 @@ #include #include #include +#include #include @@ -43,6 +44,7 @@ #include "dbus.h" #include "dbus-helper.h" #include "textfile.h" +#include "glib-helper.h" #include "error.h" #include "common.h" @@ -221,102 +223,30 @@ out: return err; } -static gboolean l2cap_connect_cb(GIOChannel *chan, - GIOCondition cond, gpointer data) +static void connect_cb(GIOChannel *chan, int err, gpointer data) { struct network_conn *nc = data; - socklen_t len; - int sk, ret; - if (cond & G_IO_NVAL) - return FALSE; - - if (cond & (G_IO_ERR | G_IO_HUP)) - goto failed; - - sk = g_io_channel_unix_get_fd(chan); - - len = sizeof(ret); - if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) { - error("getsockopt(SO_ERROR): %s (%d)", strerror(errno), errno); + if (err < 0) { + error("l2cap connect(): %s (%d)", strerror(-err), -err); goto failed; } - if (ret != 0) { - error("connect(): %s (%d)", strerror(errno), errno); - goto failed; - } + nc->sk = g_io_channel_unix_get_fd(chan); - if (bnep_connect(nc)) { - error("connect(): %s (%d)", strerror(errno), errno); + err = bnep_connect(nc); + if (err < 0) { + error("bnep connect(): %s (%d)", strerror(-err), -err); + g_io_channel_close(chan); + g_io_channel_unref(chan); goto failed; } - return FALSE; + return; + failed: nc->state = DISCONNECTED; - error_connection_attempt_failed(connection, nc->msg, errno); - g_io_channel_close(chan); - return FALSE; -} - -static int l2cap_connect(struct network_conn *nc) -{ - struct l2cap_options l2o; - struct sockaddr_l2 l2a; - socklen_t olen; - char addr[18]; - GIOChannel *io; - - ba2str(&nc->dst, addr); - info("Connecting to %s", addr); - - /* Setup L2CAP options according to BNEP spec */ - memset(&l2o, 0, sizeof(l2o)); - olen = sizeof(l2o); - getsockopt(nc->sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen); - l2o.imtu = l2o.omtu = BNEP_MTU; - setsockopt(nc->sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)); - - memset(&l2a, 0, sizeof(l2a)); - l2a.l2_family = AF_BLUETOOTH; - bacpy(&l2a.l2_bdaddr, &nc->src); - - if (bind(nc->sk, (struct sockaddr *) &l2a, sizeof(l2a)) < 0) { - error("Bind failed. %s(%d)", strerror(errno), errno); - return -errno; - } - - memset(&l2a, 0, sizeof(l2a)); - l2a.l2_family = AF_BLUETOOTH; - bacpy(&l2a.l2_bdaddr, &nc->dst); - l2a.l2_psm = htobs(BNEP_PSM); - - if (set_nonblocking(nc->sk) < 0) { - error("Set non blocking: %s (%d)", strerror(errno), errno); - return -errno; - } - - io = g_io_channel_unix_new(nc->sk); - g_io_channel_set_close_on_unref(io, FALSE); - - if (connect(nc->sk, (struct sockaddr *) &l2a, sizeof(l2a))) { - if (!(errno == EAGAIN || errno == EINPROGRESS)) { - error("Connect failed. %s(%d)", strerror(errno), - errno); - g_io_channel_close(io); - g_io_channel_unref(io); - return -errno; - } - g_io_add_watch(io, G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL, - (GIOFunc) l2cap_connect_cb, nc); - - } else { - l2cap_connect_cb(io, G_IO_OUT, nc); - } - - g_io_channel_unref(io); - return 0; + error_connection_attempt_failed(connection, nc->msg, -err); } static DBusHandlerResult get_adapter(DBusConnection *conn, DBusMessage *msg, @@ -448,6 +378,7 @@ static DBusHandlerResult connection_connect(DBusConnection *conn, { struct network_conn *nc = data; DBusError derr; + int err; if (nc->state != DISCONNECTED) { error_failed(conn, msg, "Device already connected"); @@ -462,16 +393,12 @@ static DBusHandlerResult connection_connect(DBusConnection *conn, return DBUS_HANDLER_RESULT_HANDLED; } - nc->sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); nc->state = CONNECTING; - if (nc->sk < 0) { - error("Cannot create L2CAP socket. %s(%d)", strerror(errno), - errno); - goto fail; - } - nc->msg = dbus_message_ref(msg); - if (l2cap_connect(nc) < 0) { + + err = bt_l2cap_connect(&nc->src, &nc->dst, BNEP_PSM, BNEP_MTU, + connect_cb, nc); + if (err < 0) { error("Connect failed. %s(%d)", strerror(errno), errno); goto fail; } -- cgit From ca1711891647c07d70fbcce29ef7e7576e45c016 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 7 May 2008 21:58:19 +0000 Subject: Fix dbus internals calls. --- network/manager.c | 163 +++++++----------------------------------------------- 1 file changed, 19 insertions(+), 144 deletions(-) (limited to 'network') diff --git a/network/manager.c b/network/manager.c index a65f56a5..2ad0a97d 100644 --- a/network/manager.c +++ b/network/manager.c @@ -44,6 +44,7 @@ #include "dbus-helper.h" #include "logging.h" #include "textfile.h" +#include "glib-helper.h" #define NETWORK_MANAGER_INTERFACE "org.bluez.network.Manager" @@ -213,47 +214,26 @@ static DBusHandlerResult remove_path(DBusConnection *conn, return send_message_and_unref(conn, reply); } -static void pan_record_reply(DBusPendingCall *call, void *data) +static void records_cb(sdp_list_t *recs, int err, gpointer data) { struct pending_reply *pr = data; - DBusMessage *reply = dbus_pending_call_steal_reply(call); - DBusError derr; - int len, scanned; - uint8_t *rec_bin; + int len; sdp_data_t *d; sdp_record_t *rec = NULL; char name[MAX_NAME_SIZE], *desc = NULL; - dbus_error_init(&derr); - if (dbus_set_error_from_message(&derr, reply)) { - /* FIXME: forward error as is */ - if (dbus_error_has_name(&derr, - "org.bluez.Error.ConnectionAttemptFailed")) - error_connection_attempt_failed(pr->conn, pr->msg, - EINVAL); - else - error_not_supported(pr->conn, pr->msg); - - error("GetRemoteServiceRecord failed: %s(%s)", derr.name, - derr.message); + if (err < 0) { + error_connection_attempt_failed(pr->conn, pr->msg, -err); goto fail; } - if (!dbus_message_get_args(reply, &derr, - DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &rec_bin, &len, - DBUS_TYPE_INVALID)) { + if (!recs || !recs->data) { error_not_supported(pr->conn, pr->msg); - error("%s: %s", derr.name, derr.message); + error("Invalid PAN service record"); goto fail; } - if (len == 0) { - error_not_supported(pr->conn, pr->msg); - error("Invalid PAN service record length"); - goto fail; - } - - rec = sdp_extract_pdu(rec_bin, &scanned); + rec = recs->data; /* Concat remote name and service name */ memset(name, 0, MAX_NAME_SIZE); @@ -276,6 +256,8 @@ static void pan_record_reply(DBusPendingCall *call, void *data) d->unitSize, d->val.str); } + sdp_list_free(recs, (sdp_free_func_t) sdp_record_free); + if (connection_register(pr->path, &pr->src, &pr->dst, pr->id, name, desc) < 0) { error_failed(pr->conn, pr->msg, "D-Bus path registration failed"); @@ -286,125 +268,12 @@ static void pan_record_reply(DBusPendingCall *call, void *data) connection_paths = g_slist_append(connection_paths, g_strdup(pr->path)); create_path(pr->conn, pr->msg, pr->path, "ConnectionCreated"); -fail: - - if (desc) - g_free(desc); - - sdp_record_free(rec); - dbus_error_free(&derr); - pending_reply_free(pr); - dbus_message_unref(reply); -} - -static int get_record(struct pending_reply *pr, uint32_t handle, - DBusPendingCallNotifyFunction cb) -{ - DBusMessage *msg; - DBusPendingCall *pending; - - msg = dbus_message_new_method_call("org.bluez", pr->adapter_path, - "org.bluez.Adapter", "GetRemoteServiceRecord"); - if (!msg) - return -1; - - dbus_message_append_args(msg, - DBUS_TYPE_STRING, &pr->addr, - DBUS_TYPE_UINT32, &handle, - DBUS_TYPE_INVALID); - - if (dbus_connection_send_with_reply(pr->conn, msg, &pending, -1) == FALSE) { - error("Can't send D-Bus message."); - dbus_message_unref(msg); - return -1; - } - - dbus_pending_call_set_notify(pending, cb, pr, NULL); - dbus_message_unref(msg); - dbus_pending_call_unref(pending); - - return 0; -} - -static void pan_handle_reply(DBusPendingCall *call, void *data) -{ - struct pending_reply *pr = data; - DBusMessage *reply = dbus_pending_call_steal_reply(call); - DBusError derr; - uint32_t *phandle; - int len; - dbus_error_init(&derr); - if (dbus_set_error_from_message(&derr, reply)) { - /* FIXME : forward error as is */ - if (dbus_error_has_name(&derr, - "org.bluez.Error.ConnectionAttemptFailed")) - error_connection_attempt_failed(pr->conn, pr->msg, - EINVAL); - else - error_not_supported(pr->conn, pr->msg); - - error("GetRemoteServiceHandles: %s(%s)", derr.name, - derr.message); - goto fail; - } - - if (!dbus_message_get_args(reply, &derr, - DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &phandle, - &len, DBUS_TYPE_INVALID)) { - error_not_supported(pr->conn, pr->msg); - error("%s: %s", derr.name, derr.message); - goto fail; - } - - if (!len) { - error_not_supported(pr->conn, pr->msg); - goto fail; - } - - if (get_record(pr, *phandle, pan_record_reply) < 0) { - error_not_supported(pr->conn, pr->msg); - goto fail; - } - - dbus_message_unref(reply); - return; fail: - dbus_error_free(&derr); + g_free(desc); pending_reply_free(pr); } -static int get_handles(struct pending_reply *pr, - DBusPendingCallNotifyFunction cb) -{ - DBusMessage *msg; - DBusPendingCall *pending; - const char *uuid; - - msg = dbus_message_new_method_call("org.bluez", pr->adapter_path, - "org.bluez.Adapter", "GetRemoteServiceHandles"); - if (!msg) - return -1; - - uuid = bnep_uuid(pr->id); - dbus_message_append_args(msg, - DBUS_TYPE_STRING, &pr->addr, - DBUS_TYPE_STRING, &uuid, - DBUS_TYPE_INVALID); - - if (dbus_connection_send_with_reply(pr->conn, msg, &pending, -1) == FALSE) { - error("Can't send D-Bus message."); - dbus_message_unref(msg); - return -1; - } - - dbus_pending_call_set_notify(pending, cb, pr, NULL); - dbus_message_unref(msg); - dbus_pending_call_unref(pending); - - return 0; -} - static DBusHandlerResult list_servers(DBusConnection *conn, DBusMessage *msg, void *data) { @@ -520,9 +389,10 @@ static DBusHandlerResult create_connection(DBusConnection *conn, const char *str; bdaddr_t src; uint16_t id; - int dev_id; + int dev_id, err; char key[32]; GSList *l; + uuid_t uuid; dbus_error_init(&derr); if (!dbus_message_get_args(msg, &derr, @@ -573,8 +443,13 @@ static DBusHandlerResult create_connection(DBusConnection *conn, snprintf(pr->path, MAX_PATH_LENGTH, NETWORK_PATH"/connection%d", net_uid++); - if (get_handles(pr, pan_handle_reply) < 0) + sdp_uuid16_create(&uuid, pr->id); + err = bt_search_service(&pr->src, &pr->dst, &uuid, records_cb, pr, + NULL); + if (err < 0) { + pending_reply_free(pr); return error_not_supported(conn, msg); + } return DBUS_HANDLER_RESULT_HANDLED; } -- cgit From 2af3c3a7ddc43577c067892cdfdc06dc4e63386c Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 8 May 2008 17:24:48 +0000 Subject: Remove service daemon activation handling --- network/main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'network') diff --git a/network/main.c b/network/main.c index 037ee062..54bdf3d6 100644 --- a/network/main.c +++ b/network/main.c @@ -180,15 +180,19 @@ static int network_init(void) return -EIO; } - register_uuids("network", uuids); + register_service("network"); - register_external_service(conn, "network", "Network service", ""); + register_uuids("network", uuids); return 0; } static void network_exit(void) { + unregister_uuids("network"); + + unregister_service("network"); + network_manager_exit(); dbus_connection_unref(conn); -- cgit From b5514e6c7f0258da455bbde02482fbcdb29d4442 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 8 May 2008 18:37:09 +0000 Subject: Register service and UUIDs in one step --- network/main.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'network') diff --git a/network/main.c b/network/main.c index 54bdf3d6..c84ba59b 100644 --- a/network/main.c +++ b/network/main.c @@ -180,17 +180,13 @@ static int network_init(void) return -EIO; } - register_service("network"); - - register_uuids("network", uuids); + register_service("network", uuids); return 0; } static void network_exit(void) { - unregister_uuids("network"); - unregister_service("network"); network_manager_exit(); -- 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/Makefile.am | 4 ++-- network/connection.c | 1 - network/main.c | 3 ++- network/manager.c | 1 - network/server.c | 1 - 5 files changed, 4 insertions(+), 6 deletions(-) (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index 5218ce6f..e4b5b317 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -10,12 +10,12 @@ libnetwork_la_SOURCES = main.c \ connection.h connection.c common.h common.c LDADD = $(top_builddir)/common/libhelper.a \ - @GLIB_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@ + @GDBUS_LIBS@ @GLIB_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@ endif AM_LDFLAGS = -module -avoid-version -export-symbols-regex bluetooth_plugin_desc -AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ @GLIB_CFLAGS@ +AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ @GLIB_CFLAGS@ @GDBUS_CFLAGS@ INCLUDES = -I$(top_srcdir)/common -I$(top_srcdir)/hcid -I$(top_srcdir)/sdpd diff --git a/network/connection.c b/network/connection.c index b5ef61ba..466dd203 100644 --- a/network/connection.c +++ b/network/connection.c @@ -41,7 +41,6 @@ #include #include "logging.h" -#include "dbus.h" #include "dbus-helper.h" #include "textfile.h" #include "glib-helper.h" diff --git a/network/main.c b/network/main.c index c84ba59b..f710080f 100644 --- a/network/main.c +++ b/network/main.c @@ -29,7 +29,8 @@ #include #include -#include "dbus.h" +#include +#include #include "plugin.h" #include "dbus-service.h" diff --git a/network/manager.c b/network/manager.c index 2ad0a97d..14bea175 100644 --- a/network/manager.c +++ b/network/manager.c @@ -40,7 +40,6 @@ #include -#include "dbus.h" #include "dbus-helper.h" #include "logging.h" #include "textfile.h" 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/connection.c | 2 +- network/manager.c | 2 +- network/server.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 466dd203..e5ed6d9c 100644 --- a/network/connection.c +++ b/network/connection.c @@ -39,9 +39,9 @@ #include #include +#include #include "logging.h" -#include "dbus-helper.h" #include "textfile.h" #include "glib-helper.h" diff --git a/network/manager.c b/network/manager.c index 14bea175..39aaa6e0 100644 --- a/network/manager.c +++ b/network/manager.c @@ -39,8 +39,8 @@ #include #include +#include -#include "dbus-helper.h" #include "logging.h" #include "textfile.h" #include "glib-helper.h" 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 f3c0a1a49b0b505b8543b5b3405bd62126be1a24 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 9 May 2008 09:16:32 +0000 Subject: Use -no-undefined for linking plugins --- network/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index e4b5b317..a60fcde0 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -13,7 +13,8 @@ LDADD = $(top_builddir)/common/libhelper.a \ @GDBUS_LIBS@ @GLIB_LIBS@ @DBUS_LIBS@ @BLUEZ_LIBS@ endif -AM_LDFLAGS = -module -avoid-version -export-symbols-regex bluetooth_plugin_desc +AM_LDFLAGS = -module -avoid-version -no-undefined \ + -export-symbols-regex bluetooth_plugin_desc AM_CFLAGS = @BLUEZ_CFLAGS@ @DBUS_CFLAGS@ @GLIB_CFLAGS@ @GDBUS_CFLAGS@ -- cgit From 0094809955895c974fbe95f2d3ed13f420a6a6ed Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Wed, 14 May 2008 22:16:16 +0000 Subject: Make bt_io_callback_t to take both source and destination. --- network/connection.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index e5ed6d9c..057fbba6 100644 --- a/network/connection.c +++ b/network/connection.c @@ -222,7 +222,8 @@ out: return err; } -static void connect_cb(GIOChannel *chan, int err, gpointer data) +static void connect_cb(GIOChannel *chan, int err, const bdaddr_t *src, + const bdaddr_t *dst, gpointer data) { struct network_conn *nc = data; -- 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') 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 86ca72eb302bc00c6c58b56d20ba06f1d7000214 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 16 May 2008 12:49:57 +0000 Subject: Use g_key_file_get_string_list instead of g_key_file_get_string --- network/main.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'network') diff --git a/network/main.c b/network/main.c index f710080f..02c3fcc8 100644 --- a/network/main.c +++ b/network/main.c @@ -68,7 +68,7 @@ static void read_config(const char *file) { GKeyFile *keyfile; GError *err = NULL; - char *disabled; + char **disabled; keyfile = g_key_file_new(); @@ -78,19 +78,22 @@ static void read_config(const char *file) goto done; } - disabled = g_key_file_get_string(keyfile, "General", - "Disable", &err); + disabled = g_key_file_get_string_list(keyfile, "General", + "Disable", NULL, &err); if (err) { debug("%s: %s", file, err->message); g_error_free(err); err = NULL; } else { - if (strstr(disabled, "Connection")) - conf.connection_enabled = FALSE; - if (strstr(disabled, "Server")) - conf.server_enabled = FALSE; + int i; + for (i = 0; disabled[i] != NULL; i++) { + if (g_str_equal(disabled[i], "Connection")) + conf.connection_enabled = FALSE; + else if (g_str_equal(disabled[i], "Server")) + conf.server_enabled = FALSE; + } + g_strfreev(disabled); } - g_free(disabled); conf.security = !g_key_file_get_boolean(keyfile, "General", "DisableSecurity", &err); -- 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/common.c | 1 + network/connection.c | 1 + network/server.c | 1 + 3 files changed, 3 insertions(+) (limited to 'network') diff --git a/network/common.c b/network/common.c index 3d0fefb7..f1dbe1c5 100644 --- a/network/common.c +++ b/network/common.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/network/connection.c b/network/connection.c index 057fbba6..6a4dce62 100644 --- a/network/connection.c +++ b/network/connection.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include 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 af457e55d1a46fbf3ecef32fc29e299ee4be21cf Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 May 2008 20:41:14 +0000 Subject: Convert network manager interface to use gdbus API --- network/connection.c | 2 - network/connection.h | 2 + network/manager.c | 378 +++++++++++++++++++++------------------------------ 3 files changed, 155 insertions(+), 227 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 6a4dce62..787d4b4f 100644 --- a/network/connection.c +++ b/network/connection.c @@ -50,8 +50,6 @@ #include "common.h" #include "connection.h" -#define NETWORK_CONNECTION_INTERFACE "org.bluez.network.Connection" - typedef enum { CONNECTED, CONNECTING, diff --git a/network/connection.h b/network/connection.h index b2d3641d..fd15e816 100644 --- a/network/connection.h +++ b/network/connection.h @@ -21,6 +21,8 @@ * */ +#define NETWORK_CONNECTION_INTERFACE "org.bluez.network.Connection" + int connection_init(DBusConnection *conn, const char *iface_prefix); void connection_exit(); int connection_register(const char *path, bdaddr_t *src, bdaddr_t *dst, diff --git a/network/manager.c b/network/manager.c index 39aaa6e0..5005f0e8 100644 --- a/network/manager.c +++ b/network/manager.c @@ -75,7 +75,6 @@ static DBusConnection *connection = NULL; static void pending_reply_free(struct pending_reply *pr) { - if (pr->addr) g_free(pr->addr); if (pr->path) @@ -88,12 +87,39 @@ static void pending_reply_free(struct pending_reply *pr) dbus_connection_unref(pr->conn); } -static DBusHandlerResult create_path(DBusConnection *conn, - DBusMessage *msg, const char *path, - const char *sname) +static inline DBusMessage *does_not_exist(DBusMessage *msg) { - DBusMessage *reply; + return g_dbus_create_error(msg, ERROR_INTERFACE ".AlreadyExists", + "No such connection"); +} +static inline DBusMessage *already_exists(DBusMessage *msg) +{ + return g_dbus_create_error(msg, ERROR_INTERFACE ".AlreadyExists", + "Connection already exists"); +} + +static inline DBusMessage *not_supported(DBusMessage *msg) +{ + return g_dbus_create_error(msg, ERROR_INTERFACE ".NotSupported", + "Not supported"); +} + +static inline DBusMessage *connection_is_busy(DBusMessage *msg) +{ + return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", + "Connection is Busy"); +} + +static inline DBusMessage *adapter_not_available(DBusMessage *msg) +{ + return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", + "Adapter not available"); +} + +static void create_path(DBusConnection *conn, DBusMessage *msg, + const char *path, const char *sname) +{ /* emit signal when it is a new path */ if (sname) { dbus_connection_emit_signal(conn, NETWORK_PATH, @@ -102,17 +128,11 @@ static DBusHandlerResult create_path(DBusConnection *conn, DBUS_TYPE_INVALID); } - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); - - return send_message_and_unref(conn, reply); + g_dbus_send_reply(conn, msg, DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); } -static DBusHandlerResult list_paths(DBusConnection *conn, DBusMessage *msg, +static DBusMessage *list_paths(DBusConnection *conn, DBusMessage *msg, GSList *list) { DBusMessage *reply; @@ -120,8 +140,8 @@ static DBusHandlerResult list_paths(DBusConnection *conn, DBusMessage *msg, DBusMessageIter array_iter; reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + if (reply == NULL) + return NULL; dbus_message_iter_init_append(reply, &iter); dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, @@ -132,12 +152,13 @@ static DBusHandlerResult list_paths(DBusConnection *conn, DBusMessage *msg, DBUS_TYPE_STRING, &list->data); } + dbus_message_iter_close_container(&iter, &array_iter); - return send_message_and_unref(conn, reply); + return reply; } -static const char * last_connection_used(DBusConnection *conn) +static const char *last_connection_used(DBusConnection *conn) { const char *path = NULL; GSList *l; @@ -158,32 +179,25 @@ static const char * last_connection_used(DBusConnection *conn) return path; } -static DBusHandlerResult remove_path(DBusConnection *conn, +static DBusMessage *remove_path(DBusConnection *conn, DBusMessage *msg, GSList **list, const char *sname) { const char *path; - DBusMessage *reply; - DBusError derr; GSList *l; - dbus_error_init(&derr); - if (!dbus_message_get_args(msg, &derr, - DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID)) { - error_invalid_arguments(conn, msg, derr.message); - dbus_error_free(&derr); - return DBUS_HANDLER_RESULT_HANDLED; - } + if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID) == FALSE) + return NULL; l = g_slist_find_custom(*list, path, (GCompareFunc) strcmp); if (!l) - return error_does_not_exist(conn, msg, "Path doesn't exist"); + return does_not_exist(msg); /* Remove references from the storage */ if (*list == connection_paths) { if (connection_has_pending(path)) - return error_failed(conn, msg, "Connection is Busy"); + return connection_is_busy(msg); connection_remove_stored(path); /* Reset default connection */ @@ -198,19 +212,14 @@ static DBusHandlerResult remove_path(DBusConnection *conn, g_free(l->data); *list = g_slist_remove(*list, l->data); - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - if (!dbus_connection_destroy_object_path(conn, path)) - error("Network path unregister failed"); - dbus_connection_emit_signal(conn, NETWORK_PATH, NETWORK_MANAGER_INTERFACE, sname, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID); - return send_message_and_unref(conn, reply); + g_dbus_unregister_interface(conn, path, NETWORK_CONNECTION_INTERFACE); + + return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); } static void records_cb(sdp_list_t *recs, int err, gpointer data) @@ -273,29 +282,22 @@ fail: pending_reply_free(pr); } -static DBusHandlerResult list_servers(DBusConnection *conn, DBusMessage *msg, - void *data) +static DBusMessage *list_servers(DBusConnection *conn, + DBusMessage *msg, void *data) { return list_paths(conn, msg, server_paths); } -static DBusHandlerResult find_server(DBusConnection *conn, - DBusMessage *msg, void *data) +static DBusMessage *find_server(DBusConnection *conn, + DBusMessage *msg, void *data) { - DBusError derr; const char *pattern; const char *path; GSList *list; - DBusMessage *reply; - dbus_error_init(&derr); - if (!dbus_message_get_args(msg, &derr, - DBUS_TYPE_STRING, &pattern, - DBUS_TYPE_INVALID)) { - error_invalid_arguments(conn, msg, derr.message); - dbus_error_free(&derr); - return DBUS_HANDLER_RESULT_HANDLED; - } + if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, + DBUS_TYPE_INVALID) == FALSE) + return NULL; for (list = server_paths; list; list = list->next) { path = (const char *) list->data; @@ -303,29 +305,21 @@ static DBusHandlerResult find_server(DBusConnection *conn, break; } - if (list == NULL) { - error_does_not_exist(conn, msg, "No such server"); - return DBUS_HANDLER_RESULT_HANDLED; - } - - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + if (list == NULL) + return does_not_exist(msg); - dbus_message_append_args(reply, DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); - - return send_message_and_unref(conn, reply); + return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); } -static DBusHandlerResult list_connections(DBusConnection *conn, +static DBusMessage *list_connections(DBusConnection *conn, DBusMessage *msg, void *data) { return list_paths(conn, msg, connection_paths); } -static GSList * find_connection_pattern(DBusConnection *conn, - const char *pattern) +static GSList *find_connection_pattern(DBusConnection *conn, + const char *pattern) { const char *path; GSList *list; @@ -342,48 +336,31 @@ static GSList * find_connection_pattern(DBusConnection *conn, return list; } -static DBusHandlerResult find_connection(DBusConnection *conn, +static DBusMessage *find_connection(DBusConnection *conn, DBusMessage *msg, void *data) { - DBusError derr; const char *pattern; const char *path; GSList *list; - DBusMessage *reply; - dbus_error_init(&derr); - if (!dbus_message_get_args(msg, &derr, - DBUS_TYPE_STRING, &pattern, - DBUS_TYPE_INVALID)) { - error_invalid_arguments(conn, msg, derr.message); - dbus_error_free(&derr); - return DBUS_HANDLER_RESULT_HANDLED; - } + if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, + DBUS_TYPE_INVALID) == FALSE) + return NULL; list = find_connection_pattern(conn, pattern); - - if (list == NULL) { - error_does_not_exist(conn, msg, "No such connection"); - return DBUS_HANDLER_RESULT_HANDLED; - } + if (list == NULL) + return does_not_exist(msg); path = list->data; - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); - - return send_message_and_unref(conn, reply); + return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); } -static DBusHandlerResult create_connection(DBusConnection *conn, +static DBusMessage *create_connection(DBusConnection *conn, DBusMessage *msg, void *data) { struct pending_reply *pr; - DBusError derr; const char *addr; const char *str; bdaddr_t src; @@ -393,35 +370,26 @@ static DBusHandlerResult create_connection(DBusConnection *conn, GSList *l; uuid_t uuid; - dbus_error_init(&derr); - if (!dbus_message_get_args(msg, &derr, - DBUS_TYPE_STRING, &addr, - DBUS_TYPE_STRING, &str, - DBUS_TYPE_INVALID)) { - error_invalid_arguments(conn, msg, derr.message); - dbus_error_free(&derr); - return DBUS_HANDLER_RESULT_HANDLED; - } + if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr, + DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID) == FALSE) + return NULL; id = bnep_service_id(str); if (id != BNEP_SVC_GN && id != BNEP_SVC_NAP && id != BNEP_SVC_PANU) - return error_invalid_arguments(conn, msg, "Not supported"); + return not_supported(msg); snprintf(key, 32, "%s#%s", addr, bnep_name(id)); /* Checks if the connection was already been made */ for (l = connection_paths; l; l = l->next) { - if (connection_find_data(l->data, key) == 0) { - error_already_exists(conn, msg, - "Connection Already exists"); - return DBUS_HANDLER_RESULT_HANDLED; - } + if (connection_find_data(l->data, key) == 0) + return already_exists(msg); } bacpy(&src, BDADDR_ANY); dev_id = hci_get_route(&src); if (dev_id < 0 || hci_devba(dev_id, &src) < 0) - return error_failed(conn, msg, "Adapter not available"); + return adapter_not_available(msg); pr = g_new0(struct pending_reply, 1); @@ -429,7 +397,7 @@ static DBusHandlerResult create_connection(DBusConnection *conn, pr->adapter_path = g_strdup_printf("/org/bluez/hci%d", dev_id); if (!pr->adapter_path) { pending_reply_free (pr); - return error_failed(conn, msg, "Adapter not available"); + return adapter_not_available(msg); } pr->conn = dbus_connection_ref(conn); @@ -440,60 +408,48 @@ static DBusHandlerResult create_connection(DBusConnection *conn, pr->id = id; pr->path = g_new0(char, MAX_PATH_LENGTH); snprintf(pr->path, MAX_PATH_LENGTH, - NETWORK_PATH"/connection%d", net_uid++); + NETWORK_PATH "/connection%d", net_uid++); sdp_uuid16_create(&uuid, pr->id); err = bt_search_service(&pr->src, &pr->dst, &uuid, records_cb, pr, NULL); if (err < 0) { pending_reply_free(pr); - return error_not_supported(conn, msg); + return not_supported(msg); } - return DBUS_HANDLER_RESULT_HANDLED; + return NULL; } -static DBusHandlerResult remove_connection(DBusConnection *conn, +static DBusMessage *remove_connection(DBusConnection *conn, DBusMessage *msg, void *data) { return remove_path(conn, msg, &connection_paths, "ConnectionRemoved"); } -static DBusHandlerResult last_connection(DBusConnection *conn, +static DBusMessage *last_connection(DBusConnection *conn, DBusMessage *msg, void *data) { const char *path; - DBusMessage *reply; if (connection_paths == NULL || - g_slist_length (connection_paths) == 0) { - error_does_not_exist(conn, msg, "No such connection"); - return DBUS_HANDLER_RESULT_HANDLED; - } + g_slist_length(connection_paths) == 0) + return does_not_exist(msg); path = last_connection_used(conn); - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); - - return send_message_and_unref(conn, reply); + return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); } -static DBusHandlerResult default_connection(DBusConnection *conn, +static DBusMessage *default_connection(DBusConnection *conn, DBusMessage *msg, void *data) { const char *path; - DBusMessage *reply; if (connection_paths == NULL || - g_slist_length (connection_paths) == 0) { - error_does_not_exist(conn, msg, "No such connection"); - return DBUS_HANDLER_RESULT_HANDLED; - } + g_slist_length (connection_paths) == 0) + return does_not_exist(msg); path = g_slist_nth_data (connection_paths, default_index); @@ -502,57 +458,39 @@ static DBusHandlerResult default_connection(DBusConnection *conn, connection_store(path, TRUE); } - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); - - return send_message_and_unref(conn, reply); + return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); } -static DBusHandlerResult change_default_connection(DBusConnection *conn, +static DBusMessage *change_default_connection(DBusConnection *conn, DBusMessage *msg, void *data) { const char *path; const char *pattern; - DBusMessage *reply; - DBusError derr; GSList *list; - dbus_error_init(&derr); - if (!dbus_message_get_args(msg, &derr, - DBUS_TYPE_STRING, &pattern, - DBUS_TYPE_INVALID)) { - error_invalid_arguments(conn, msg, derr.message); - dbus_error_free(&derr); - return DBUS_HANDLER_RESULT_HANDLED; - } + if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, + DBUS_TYPE_INVALID) == FALSE) + return NULL; if (connection_paths == NULL || - g_slist_length (connection_paths) == 0) { - error_does_not_exist(conn, msg, "No such connection"); - return DBUS_HANDLER_RESULT_HANDLED; - } + g_slist_length(connection_paths) == 0) + return does_not_exist(msg); - list = g_slist_find_custom(connection_paths, pattern, (GCompareFunc) strcmp); + list = g_slist_find_custom(connection_paths, pattern, + (GCompareFunc) strcmp); /* Find object path via pattern */ if (list == NULL) { list = find_connection_pattern(conn, pattern); + if (list == NULL) + return does_not_exist(msg); - if (list == NULL) { - error_does_not_exist(conn, msg, "No such connection"); - return DBUS_HANDLER_RESULT_HANDLED; - } - else - path = list->data; - } - else + path = list->data; + } else path = list->data; - default_index = g_slist_position (connection_paths, list); + default_index = g_slist_position(connection_paths, list); connection_store(path, TRUE); dbus_connection_emit_signal(connection, NETWORK_PATH, @@ -561,28 +499,22 @@ static DBusHandlerResult change_default_connection(DBusConnection *conn, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID); - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID); - - return send_message_and_unref(conn, reply); + return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID); } -static void manager_unregister(DBusConnection *conn, void *data) +static void manager_unregister(void *data) { info("Unregistered manager path"); if (server_paths) { - g_slist_foreach(server_paths, (GFunc)g_free, NULL); + g_slist_foreach(server_paths, (GFunc) g_free, NULL); g_slist_free(server_paths); server_paths = NULL; } if (connection_paths) { - g_slist_foreach(connection_paths, (GFunc)g_free, NULL); + g_slist_foreach(connection_paths, (GFunc) g_free, NULL); g_slist_free(connection_paths); connection_paths = NULL; } @@ -626,7 +558,7 @@ static void parse_stored_connection(char *key, char *value, void *data) return; snprintf(path, MAX_PATH_LENGTH, - NETWORK_PATH"/connection%d", net_uid++); + NETWORK_PATH "/connection%d", net_uid++); /* Parsing the value: name and description */ ptr = strchr(value, ':'); @@ -703,7 +635,7 @@ static void register_server(uint16_t id) if (!conf->server_enabled) return; - snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH"/%s", bnep_name(id)); + snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH "/%s", bnep_name(id)); if (g_slist_find_custom(server_paths, path, (GCompareFunc) strcmp)) @@ -742,8 +674,7 @@ static void register_servers_stored(const char *adapter, const char *profile) str2ba(adapter, &src); if (stat (filename, &s) == 0 && (s.st_mode & __S_IFREG)) { - snprintf(path, MAX_PATH_LENGTH, - NETWORK_PATH"/%s", profile); + snprintf(path, MAX_PATH_LENGTH, NETWORK_PATH "/%s", profile); if (server_register_from_file(path, &src, id, filename) == 0) { server_paths = g_slist_append(server_paths, g_strdup(path)); @@ -787,47 +718,49 @@ static void register_stored(void) closedir(dir); } -static DBusMethodVTable connection_methods[] = { - { "ListConnections", list_connections, "", "as" }, - { "FindConnection", find_connection, "s", "s" }, - { "CreateConnection", create_connection, "ss", "s" }, - { "RemoveConnection", remove_connection, "s", "" }, - { "LastConnection", last_connection, "", "s" }, - { "DefaultConnection", default_connection, "", "s" }, - { "ChangeDefaultConnection", change_default_connection, "s", "s"}, - { NULL, NULL, NULL, NULL } +static GDBusMethodTable connection_methods[] = { + { "ListConnections", "", "as", list_connections }, + { "FindConnection", "s", "s", find_connection }, + { "CreateConnection", "ss", "s", create_connection, + G_DBUS_METHOD_FLAG_ASYNC }, + { "RemoveConnection", "s", "", remove_connection }, + { "LastConnection", "", "s", last_connection }, + { "DefaultConnection", "", "s", default_connection }, + { "ChangeDefaultConnection", "s", "s", change_default_connection }, + { } }; -static DBusSignalVTable connection_signals[] = { - { "ConnectionCreated", "s" }, - { "ConnectionRemoved", "s" }, - { "DefaultConnectionChanged", "s" }, - { NULL, NULL } +static GDBusSignalTable connection_signals[] = { + { "ConnectionCreated", "s" }, + { "ConnectionRemoved", "s" }, + { "DefaultConnectionChanged", "s" }, + { } }; -static DBusMethodVTable server_methods[] = { - { "ListServers", list_servers, "", "as" }, - { "FindServer", find_server, "s", "s" }, - { NULL, NULL, NULL, NULL } +static GDBusMethodTable server_methods[] = { + { "ListServers", "", "as", list_servers }, + { "FindServer", "s", "s", find_server }, + { } }; -static DBusMethodVTable manager_methods[] = { - { "ListServers", list_servers, "", "as" }, - { "FindServer", find_server, "s", "s" }, - { "ListConnections", list_connections, "", "as" }, - { "FindConnection", find_connection, "s", "s" }, - { "CreateConnection", create_connection, "ss", "s" }, - { "RemoveConnection", remove_connection, "s", "" }, - { "LastConnection", last_connection, "", "s" }, - { "DefaultConnection", default_connection, "", "s" }, - { "ChangeDefaultConnection", change_default_connection, "s", "s"}, - { NULL, NULL, NULL, NULL } +static GDBusMethodTable manager_methods[] = { + { "ListServers", "", "as", list_servers }, + { "FindServer", "s", "s", find_server }, + { "ListConnections", "", "as", list_connections }, + { "FindConnection", "s", "s", find_connection }, + { "CreateConnection", "ss", "s", create_connection, + G_DBUS_METHOD_FLAG_ASYNC }, + { "RemoveConnection", "s", "", remove_connection }, + { "LastConnection", "", "s", last_connection }, + { "DefaultConnection", "", "s", default_connection }, + { "ChangeDefaultConnection", "s", "s", change_default_connection }, + { } }; int network_manager_init(DBusConnection *conn, struct network_conf *service_conf) { - DBusMethodVTable *methods = NULL; - DBusSignalVTable *signals = NULL; + GDBusMethodTable *methods = NULL; + GDBusSignalTable *signals = NULL; conf = service_conf; @@ -870,18 +803,12 @@ int network_manager_init(DBusConnection *conn, struct network_conf *service_conf return -1; } - if (!dbus_connection_create_object_path(conn, NETWORK_PATH, - NULL, manager_unregister)) { - error("D-Bus failed to create %s path", NETWORK_PATH); - return -1; - } - - if (!dbus_connection_register_interface(conn, NETWORK_PATH, - NETWORK_MANAGER_INTERFACE, - methods, signals, NULL)) { + if (g_dbus_register_interface(conn, NETWORK_PATH, + NETWORK_MANAGER_INTERFACE, + methods, signals, NULL, + NULL, manager_unregister) == FALSE) { error("Failed to register %s interface to %s", NETWORK_MANAGER_INTERFACE, NETWORK_PATH); - dbus_connection_destroy_object_path(connection, NETWORK_PATH); return -1; } @@ -907,7 +834,8 @@ void network_manager_exit(void) if (conf->connection_enabled) connection_exit(); - dbus_connection_destroy_object_path(connection, NETWORK_PATH); + g_dbus_unregister_interface(connection, NETWORK_PATH, + NETWORK_MANAGER_INTERFACE); dbus_connection_unref(connection); connection = NULL; -- cgit From 617faeead1ffd6674cc1ab174815ff1395aec311 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 May 2008 22:16:11 +0000 Subject: Convert network connection handling to gdbus API --- network/connection.c | 294 +++++++++++++++++++++------------------------------ 1 file changed, 121 insertions(+), 173 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 787d4b4f..4d96845d 100644 --- a/network/connection.c +++ b/network/connection.c @@ -78,6 +78,36 @@ struct __service_16 { static DBusConnection *connection = NULL; static const char *prefix = NULL; +static inline DBusMessage *not_supported(DBusMessage *msg) +{ + return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", + "Not suported"); +} + +static inline DBusMessage *already_connected(DBusMessage *msg) +{ + return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", + "Device already connected"); +} + +static inline DBusMessage *not_connected(DBusMessage *msg) +{ + return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", + "Device not connected"); +} + +static inline DBusMessage *no_pending_connect(DBusMessage *msg) +{ + return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", + "Device has no pending connect"); +} + +static inline DBusMessage *connection_attempt_failed(DBusMessage *msg, int err) +{ + return g_dbus_create_error(msg, ERROR_INTERFACE ".ConnectionAttemptFailed", + err ? strerror(err) : "Connection attempt failed"); +} + static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond, gpointer data) { @@ -89,17 +119,20 @@ static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond, "Disconnected", DBUS_TYPE_INVALID); } + info("%s disconnected", nc->dev); + bnep_if_down(nc->dev); nc->state = DISCONNECTED; memset(nc->dev, 0, 16); strncpy(nc->dev, prefix, strlen(prefix)); g_io_channel_close(chan); + return FALSE; } static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, - gpointer data) + gpointer data) { struct network_conn *nc = data; struct bnep_control_rsp *rsp; @@ -165,12 +198,11 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, "Connected", DBUS_TYPE_INVALID); - reply = dbus_message_new_method_return(nc->msg); - pdev = nc->dev; - dbus_message_append_args(reply, DBUS_TYPE_STRING, &pdev, - DBUS_TYPE_INVALID); - send_message_and_unref(connection, reply); + + reply = g_dbus_create_reply(nc->msg, DBUS_TYPE_STRING, &pdev, + DBUS_TYPE_INVALID); + g_dbus_send_message(connection, reply); nc->state = CONNECTED; @@ -179,12 +211,15 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL, (GIOFunc) bnep_watchdog_cb, nc); return FALSE; + failed: if (nc->state != DISCONNECTED) { nc->state = DISCONNECTED; - error_connection_attempt_failed(connection, nc->msg, EIO); + reply = connection_attempt_failed(nc->msg, EIO); + g_dbus_send_message(connection, reply); g_io_channel_close(chan); } + return FALSE; } @@ -225,6 +260,7 @@ static void connect_cb(GIOChannel *chan, int err, const bdaddr_t *src, const bdaddr_t *dst, gpointer data) { struct network_conn *nc = data; + DBusMessage *reply; if (err < 0) { error("l2cap connect(): %s (%d)", strerror(-err), -err); @@ -245,233 +281,151 @@ static void connect_cb(GIOChannel *chan, int err, const bdaddr_t *src, failed: nc->state = DISCONNECTED; - error_connection_attempt_failed(connection, nc->msg, -err); + + reply = connection_attempt_failed(nc->msg, -err); + g_dbus_send_message(connection, reply); } -static DBusHandlerResult get_adapter(DBusConnection *conn, DBusMessage *msg, +static DBusMessage *get_adapter(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_conn *nc = data; - DBusMessage *reply; char addr[18]; const char *paddr = addr; ba2str(&nc->src, addr); - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &paddr, - DBUS_TYPE_INVALID); - - return send_message_and_unref(conn, reply); + return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &paddr, + DBUS_TYPE_INVALID); } -static DBusHandlerResult get_address(DBusConnection *conn, DBusMessage *msg, +static DBusMessage *get_address(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_conn *nc = data; - DBusMessage *reply; char addr[18]; const char *paddr = addr; ba2str(&nc->dst, addr); - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &paddr, - DBUS_TYPE_INVALID); - - return send_message_and_unref(conn, reply); + return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &paddr, + DBUS_TYPE_INVALID); } -static DBusHandlerResult get_uuid(DBusConnection *conn, DBusMessage *msg, - void *data) +static DBusMessage *get_uuid(DBusConnection *conn, + DBusMessage *msg, void *data) { struct network_conn *nc = data; const char *uuid; - DBusMessage *reply; uuid = bnep_uuid(nc->id); - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &uuid, - DBUS_TYPE_INVALID); - return send_message_and_unref(conn, reply); + return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &uuid, + DBUS_TYPE_INVALID); } -static DBusHandlerResult get_name(DBusConnection *conn, DBusMessage *msg, - void *data) +static DBusMessage *get_name(DBusConnection *conn, + DBusMessage *msg, void *data) { struct network_conn *nc = data; - DBusMessage *reply; - - if (!nc->name) { - error_failed(conn, msg, "Cannot find service name"); - return DBUS_HANDLER_RESULT_HANDLED; - } - - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &nc->name, - DBUS_TYPE_INVALID); - return send_message_and_unref(conn, reply); + if (!nc->name) + return not_supported(msg); + return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &nc->name, + DBUS_TYPE_INVALID); } -static DBusHandlerResult get_description(DBusConnection *conn, +static DBusMessage *get_description(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_conn *nc = data; - DBusMessage *reply; - - if (!nc->desc) { - error_failed(conn, msg, "Cannot find service description"); - return DBUS_HANDLER_RESULT_HANDLED; - } - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &nc->desc, - DBUS_TYPE_INVALID); + if (!nc->desc) + return not_supported(msg); - return send_message_and_unref(conn, reply); + return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &nc->desc, + DBUS_TYPE_INVALID); } -static DBusHandlerResult get_interface(DBusConnection *conn, DBusMessage *msg, - void *data) +static DBusMessage *get_interface(DBusConnection *conn, + DBusMessage *msg, void *data) { struct network_conn *nc = data; const char *pdev = nc->dev; - DBusMessage *reply; - if (nc->state != CONNECTED) { - error_failed(conn, msg, "Device not connected"); - return DBUS_HANDLER_RESULT_HANDLED; - } - - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + if (nc->state != CONNECTED) + return not_connected(msg); - dbus_message_append_args(reply, DBUS_TYPE_STRING, &pdev, - DBUS_TYPE_INVALID); - - return send_message_and_unref(conn, reply); + return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &pdev, + DBUS_TYPE_INVALID); } /* Connect and initiate BNEP session */ -static DBusHandlerResult connection_connect(DBusConnection *conn, +static DBusMessage *connection_connect(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_conn *nc = data; - DBusError derr; int err; - if (nc->state != DISCONNECTED) { - error_failed(conn, msg, "Device already connected"); - return DBUS_HANDLER_RESULT_HANDLED; - } - - dbus_error_init(&derr); - if (!dbus_message_get_args(msg, &derr, - DBUS_TYPE_INVALID)) { - error_invalid_arguments(conn, msg, derr.message); - dbus_error_free(&derr); - return DBUS_HANDLER_RESULT_HANDLED; - } + if (nc->state != DISCONNECTED) + return already_connected(msg); nc->state = CONNECTING; nc->msg = dbus_message_ref(msg); err = bt_l2cap_connect(&nc->src, &nc->dst, BNEP_PSM, BNEP_MTU, - connect_cb, nc); + connect_cb, nc); if (err < 0) { error("Connect failed. %s(%d)", strerror(errno), errno); - goto fail; - } - - return DBUS_HANDLER_RESULT_HANDLED; -fail: - if (nc->msg) { dbus_message_unref(nc->msg); nc->msg = NULL; + nc->state = DISCONNECTED; + return connection_attempt_failed(msg, -err); } - nc->state = DISCONNECTED; - error_connection_attempt_failed(conn, msg, errno); - return DBUS_HANDLER_RESULT_HANDLED; + + return NULL; } -static DBusHandlerResult connection_cancel(DBusConnection *conn, +static DBusMessage *connection_cancel(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_conn *nc = data; - DBusMessage *reply; - if (nc->state != CONNECTING) { - error_failed(conn, msg, "Device has no pending connect"); - return DBUS_HANDLER_RESULT_HANDLED; - } + if (nc->state != CONNECTING) + return no_pending_connect(msg); close(nc->sk); nc->state = DISCONNECTED; - reply = dbus_message_new_method_return(msg); - - return send_message_and_unref(conn, reply); + return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); } -static DBusHandlerResult connection_disconnect(DBusConnection *conn, +static DBusMessage *connection_disconnect(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_conn *nc = data; - DBusMessage *reply; - if (nc->state != CONNECTED) { - error_failed(conn, msg, "Device not connected"); - return DBUS_HANDLER_RESULT_HANDLED; - } + if (nc->state != CONNECTED) + return not_connected(msg); bnep_if_down(nc->dev); bnep_kill_connection(&nc->dst); - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - return send_message_and_unref(conn, reply); + return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); } -static DBusHandlerResult is_connected(DBusConnection *conn, DBusMessage *msg, - void *data) +static DBusMessage *is_connected(DBusConnection *conn, + DBusMessage *msg, void *data) { struct network_conn *nc = data; - DBusMessage *reply; - gboolean up; - - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + gboolean up = (nc->state == CONNECTED); - up = (nc->state == CONNECTED); - dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &up, - DBUS_TYPE_INVALID); - - return send_message_and_unref(conn, reply); + return g_dbus_create_reply(msg, DBUS_TYPE_BOOLEAN, &up, + DBUS_TYPE_INVALID); } -static DBusHandlerResult get_info(DBusConnection *conn, +static DBusMessage *get_info(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_conn *nc = data; @@ -483,8 +437,8 @@ static DBusHandlerResult get_info(DBusConnection *conn, const char *paddr = raddr; reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + if (reply == NULL) + return NULL; dbus_message_iter_init_append(reply, &iter); @@ -506,7 +460,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 connection_free(struct network_conn *nc) @@ -527,12 +481,12 @@ static void connection_free(struct network_conn *nc) if (nc->desc) g_free(nc->desc); - + g_free(nc); nc = NULL; } -static void connection_unregister(DBusConnection *conn, void *data) +static void connection_unregister(void *data) { struct network_conn *nc = data; @@ -541,25 +495,26 @@ static void connection_unregister(DBusConnection *conn, void *data) connection_free(nc); } -static DBusMethodVTable connection_methods[] = { - { "GetAdapter", get_adapter, "", "s" }, - { "GetAddress", get_address, "", "s" }, - { "GetUUID", get_uuid, "", "s" }, - { "GetName", get_name, "", "s" }, - { "GetDescription", get_description, "", "s" }, - { "GetInterface", get_interface, "", "s" }, - { "Connect", connection_connect, "", "s" }, - { "CancelConnect", connection_cancel, "", "" }, - { "Disconnect", connection_disconnect, "", "" }, - { "IsConnected", is_connected, "", "b" }, - { "GetInfo", get_info, "", "a{sv}" }, - { NULL, NULL, NULL, NULL } +static GDBusMethodTable connection_methods[] = { + { "GetAdapter", "", "s", get_adapter }, + { "GetAddress", "", "s", get_address }, + { "GetUUID", "", "s", get_uuid }, + { "GetName", "", "s", get_name }, + { "GetDescription", "", "s", get_description }, + { "GetInterface", "", "s", get_interface }, + { "Connect", "", "s", connection_connect, + G_DBUS_METHOD_FLAG_ASYNC }, + { "CancelConnect", "", "", connection_cancel }, + { "Disconnect", "", "", connection_disconnect }, + { "IsConnected", "", "b", is_connected }, + { "GetInfo", "", "a{sv}",get_info }, + { } }; -static DBusSignalVTable connection_signals[] = { +static GDBusSignalTable connection_signals[] = { { "Connected", "" }, { "Disconnected", "" }, - { NULL, NULL } + { } }; int connection_register(const char *path, bdaddr_t *src, bdaddr_t *dst, @@ -579,20 +534,13 @@ int connection_register(const char *path, bdaddr_t *src, bdaddr_t *dst, nc = g_new0(struct network_conn, 1); - /* register path */ - if (!dbus_connection_create_object_path(connection, path, nc, - connection_unregister)) { - connection_free(nc); - return -1; - } - - if (!dbus_connection_register_interface(connection, path, - NETWORK_CONNECTION_INTERFACE, - connection_methods, - connection_signals, NULL)) { + if (g_dbus_register_interface(connection, path, + NETWORK_CONNECTION_INTERFACE, + connection_methods, + connection_signals, NULL, + nc, connection_unregister) == FALSE) { error("D-Bus failed to register %s interface", NETWORK_CONNECTION_INTERFACE); - dbus_connection_destroy_object_path(connection, path); return -1; } -- cgit From 2d6bcaff198acfb9453416fd73df2358dec96108 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Thu, 29 May 2008 08:35:54 +0000 Subject: Register network service as network driver --- network/main.c | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) (limited to 'network') diff --git a/network/main.c b/network/main.c index 02c3fcc8..dd53c1d1 100644 --- a/network/main.c +++ b/network/main.c @@ -26,30 +26,43 @@ #endif #include -#include + #include -#include -#include +#include #include "plugin.h" -#include "dbus-service.h" +#include "device.h" #include "logging.h" #include "manager.h" #define IFACE_PREFIX "bnep%d" -#define GN_IFACE "pan0" +#define GN_IFACE "pan0" #define NAP_IFACE "pan1" #define PANU_UUID "00001115-0000-1000-8000-00805f9b34fb" -#define NAP_UUID "00001116-0000-1000-8000-00805f9b34fb" -#define GN_UUID "00001117-0000-1000-8000-00805f9b34fb" - -static const char *uuids[] = { - PANU_UUID, - NAP_UUID, - GN_UUID, - NULL +#define NAP_UUID "00001116-0000-1000-8000-00805f9b34fb" +#define GN_UUID "00001117-0000-1000-8000-00805f9b34fb" + +static DBusConnection *conn; + +static int network_probe(const char *path) +{ + debug("path %s", path); + + return 0; +} + +static void network_remove(const char *path) +{ + debug("path %s", path); +} + +static struct btd_device_driver network_driver = { + .name = "network", + .uuids = BTD_UUIDS(PANU_UUID, NAP_UUID, GN_UUID), + .probe = network_probe, + .remove = network_remove, }; static struct network_conf conf = { @@ -169,8 +182,6 @@ done: conf.security ? "true" : "false"); } -static DBusConnection *conn; - static int network_init(void) { conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); @@ -184,14 +195,14 @@ static int network_init(void) return -EIO; } - register_service("network", uuids); + btd_register_device_driver(&network_driver); return 0; } static void network_exit(void) { - unregister_service("network"); + btd_unregister_device_driver(&network_driver); network_manager_exit(); -- 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/connection.c | 24 +++++- network/server.c | 202 +++++++++++++++++++++++++-------------------------- 2 files changed, 120 insertions(+), 106 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 4d96845d..c57623b0 100644 --- a/network/connection.c +++ b/network/connection.c @@ -77,6 +77,15 @@ struct __service_16 { static DBusConnection *connection = NULL; static const char *prefix = NULL; +static GSList *connections = NULL; + +gint find_connection(gconstpointer a, gconstpointer b) +{ + const struct network_conn *nc = a; + const char *path = b; + + return strcmp(nc->path, path); +} static inline DBusMessage *not_supported(DBusMessage *msg) { @@ -492,6 +501,7 @@ static void connection_unregister(void *data) info("Unregistered connection path:%s", nc->path); + connections = g_slist_remove(connections, nc); connection_free(nc); } @@ -555,6 +565,8 @@ int connection_register(const char *path, bdaddr_t *src, bdaddr_t *dst, strncpy(nc->dev, prefix, strlen(prefix)); nc->state = DISCONNECTED; + connections = g_slist_append(connections, nc); + info("Registered connection path:%s", path); return 0; @@ -568,11 +580,13 @@ int connection_store(const char *path, gboolean default_path) char filename[PATH_MAX + 1]; char src_addr[18], dst_addr[18]; int len, err; + GSList *l; - if (!dbus_connection_get_object_user_data(connection, - path, (void *) &nc)) + l = g_slist_find_custom(connections, path, find_connection); + if (!l) return -ENOENT; + nc = l->data; if (!nc->name || !nc->desc) return -EINVAL; @@ -604,11 +618,13 @@ int connection_find_data(const char *path, const char *pattern) struct network_conn *nc; char addr[18], key[32]; const char *role; + GSList *l; - if (!dbus_connection_get_object_user_data(connection, - path, (void *) &nc)) + l = g_slist_find_custom(connections, path, find_connection); + if (!l) return -1; + nc = l->data; if (strcasecmp(pattern, nc->dev) == 0) return 0; 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 2aab870f593da0b3ec83095e5ded93b900e4b600 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 3 Jun 2008 20:07:34 +0000 Subject: Update autoconf/automake options --- network/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index a60fcde0..704a0c8c 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -1,5 +1,5 @@ -if NETWORKSERVICE +if NETWORKPLUGIN plugindir = $(libdir)/bluetooth/plugins plugin_LTLIBRARIES = libnetwork.la -- 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') 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 295bd4a9d96be39cad5bb85e50b3b682c89d65aa Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Fri, 6 Jun 2008 17:55:02 +0000 Subject: Remove use of dbus_connection_get_object_user_data from network. --- network/connection.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index c57623b0..55c9c529 100644 --- a/network/connection.c +++ b/network/connection.c @@ -648,11 +648,14 @@ int connection_find_data(const char *path, const char *pattern) gboolean connection_has_pending(const char *path) { struct network_conn *nc; + GSList *l; - if (!dbus_connection_get_object_user_data(connection, - path, (void *) &nc)) + l = g_slist_find_custom(connections, path, find_connection); + if (!l) return FALSE; + nc = l->data; + return (nc->state == CONNECTING); } @@ -664,11 +667,14 @@ int connection_remove_stored(const char *path) char filename[PATH_MAX + 1]; char src_addr[18], dst_addr[18]; int err; + GSList *l; - if (!dbus_connection_get_object_user_data(connection, - path, (void *) &nc)) + l = g_slist_find_custom(connections, path, find_connection); + if (!l) return -ENOENT; + nc = l->data; + ba2str(&nc->dst, dst_addr); role = bnep_name(nc->id); snprintf(key, 32, "%s#%s", dst_addr, role); @@ -684,11 +690,14 @@ int connection_remove_stored(const char *path) gboolean connection_is_connected(const char *path) { struct network_conn *nc; + GSList *l; - if (!dbus_connection_get_object_user_data(connection, - path, (void *) &nc)) + l = g_slist_find_custom(connections, path, find_connection); + if (!l) return FALSE; + nc = l->data; + return (nc->state == CONNECTED); } -- 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/connection.c | 4 ++-- network/manager.c | 6 +++--- network/server.c | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 55c9c529..1ddfc4cf 100644 --- a/network/connection.c +++ b/network/connection.c @@ -123,7 +123,7 @@ static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond, struct network_conn *nc = data; if (connection != NULL) { - dbus_connection_emit_signal(connection, nc->path, + g_dbus_emit_signal(connection, nc->path, NETWORK_CONNECTION_INTERFACE, "Disconnected", DBUS_TYPE_INVALID); @@ -202,7 +202,7 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, } bnep_if_up(nc->dev, nc->id); - dbus_connection_emit_signal(connection, nc->path, + g_dbus_emit_signal(connection, nc->path, NETWORK_CONNECTION_INTERFACE, "Connected", DBUS_TYPE_INVALID); diff --git a/network/manager.c b/network/manager.c index 5005f0e8..dd23b58d 100644 --- a/network/manager.c +++ b/network/manager.c @@ -122,7 +122,7 @@ static void create_path(DBusConnection *conn, DBusMessage *msg, { /* emit signal when it is a new path */ if (sname) { - dbus_connection_emit_signal(conn, NETWORK_PATH, + g_dbus_emit_signal(conn, NETWORK_PATH, NETWORK_MANAGER_INTERFACE, sname, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID); @@ -212,7 +212,7 @@ static DBusMessage *remove_path(DBusConnection *conn, g_free(l->data); *list = g_slist_remove(*list, l->data); - dbus_connection_emit_signal(conn, NETWORK_PATH, + g_dbus_emit_signal(conn, NETWORK_PATH, NETWORK_MANAGER_INTERFACE, sname, DBUS_TYPE_STRING, &path, DBUS_TYPE_INVALID); @@ -493,7 +493,7 @@ static DBusMessage *change_default_connection(DBusConnection *conn, default_index = g_slist_position(connection_paths, list); connection_store(path, TRUE); - dbus_connection_emit_signal(connection, NETWORK_PATH, + g_dbus_emit_signal(connection, NETWORK_PATH, NETWORK_MANAGER_INTERFACE, "DefaultConnectionChanged", DBUS_TYPE_STRING, &path, 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/connection.c | 2 ++ network/server.c | 2 ++ 2 files changed, 4 insertions(+) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 1ddfc4cf..d2fd85c2 100644 --- a/network/connection.c +++ b/network/connection.c @@ -42,6 +42,8 @@ #include #include +#include "../hcid/dbus-common.h" + #include "logging.h" #include "textfile.h" #include "glib-helper.h" 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 8bf636881f152a97727774f4f9ea2504c72dfb23 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 8 Jun 2008 20:54:55 +0000 Subject: Use DBG in plugin to show function names --- network/main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'network') diff --git a/network/main.c b/network/main.c index dd53c1d1..106c2a76 100644 --- a/network/main.c +++ b/network/main.c @@ -48,14 +48,14 @@ static DBusConnection *conn; static int network_probe(const char *path) { - debug("path %s", path); + DBG("path %s", path); return 0; } static void network_remove(const char *path) { - debug("path %s", path); + DBG("path %s", path); } static struct btd_device_driver network_driver = { -- cgit From 0f62b72c8564608f849b3bbe54bf48db07c45015 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 8 Jun 2008 21:21:54 +0000 Subject: Update plugin interface registration --- network/main.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'network') diff --git a/network/main.c b/network/main.c index 106c2a76..edfd0757 100644 --- a/network/main.c +++ b/network/main.c @@ -44,18 +44,61 @@ #define NAP_UUID "00001116-0000-1000-8000-00805f9b34fb" #define GN_UUID "00001117-0000-1000-8000-00805f9b34fb" +#define NETWORK_INTERFACE "org.bluez.Network" + +static DBusMessage *network_connect(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + const char *target, *device = "bnep0"; + + if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &target, + DBUS_TYPE_INVALID) == FALSE) + return NULL; + + return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &device, + DBUS_TYPE_INVALID); +} + +static DBusMessage *network_disconnect(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + if (dbus_message_get_args(msg, NULL, DBUS_TYPE_INVALID) == FALSE) + return NULL; + + return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); +} + +static GDBusMethodTable network_methods[] = { + { "Connect", "s", "s", network_connect }, + { "Disconnect", "", "", network_disconnect }, + { } +}; + +static GDBusSignalTable network_signals[] = { + { "Connected", "ss" }, + { "Disconnected", "s" }, + { } +}; + static DBusConnection *conn; static int network_probe(const char *path) { DBG("path %s", path); + if (g_dbus_register_interface(conn, path, NETWORK_INTERFACE, + network_methods, network_signals, NULL, + NULL, NULL) == FALSE) + return -1; + return 0; } static void network_remove(const char *path) { DBG("path %s", path); + + g_dbus_unregister_interface(conn, path, NETWORK_INTERFACE); } static struct btd_device_driver network_driver = { -- cgit From 5243ac4fd278b0176ece84cbcec537a92a9c7290 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Sun, 8 Jun 2008 22:57:11 +0000 Subject: Update probe/remove callback and implement serial API --- network/main.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'network') diff --git a/network/main.c b/network/main.c index edfd0757..8e18dd99 100644 --- a/network/main.c +++ b/network/main.c @@ -82,23 +82,23 @@ static GDBusSignalTable network_signals[] = { static DBusConnection *conn; -static int network_probe(const char *path) +static int network_probe(struct btd_device *device) { - DBG("path %s", path); + DBG("path %s", device->path); - if (g_dbus_register_interface(conn, path, NETWORK_INTERFACE, + if (g_dbus_register_interface(conn, device->path, NETWORK_INTERFACE, network_methods, network_signals, NULL, - NULL, NULL) == FALSE) + device, NULL) == FALSE) return -1; return 0; } -static void network_remove(const char *path) +static void network_remove(struct btd_device *device) { - DBG("path %s", path); + DBG("path %s", device->path); - g_dbus_unregister_interface(conn, path, NETWORK_INTERFACE); + g_dbus_unregister_interface(conn, device->path, NETWORK_INTERFACE); } static struct btd_device_driver network_driver = { -- 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') 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') 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 From a22a088109b664efdee397affed55b039cb0999b Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 30 Jun 2008 05:47:13 +0000 Subject: Don't use lib prefix for plugins --- network/Makefile.am | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'network') diff --git a/network/Makefile.am b/network/Makefile.am index 704a0c8c..15208f5a 100644 --- a/network/Makefile.am +++ b/network/Makefile.am @@ -2,10 +2,9 @@ if NETWORKPLUGIN plugindir = $(libdir)/bluetooth/plugins -plugin_LTLIBRARIES = libnetwork.la +plugin_LTLIBRARIES = network.la -libnetwork_la_SOURCES = main.c \ - manager.h manager.c \ +network_la_SOURCES = main.c manager.h manager.c \ server.h server.c bridge.h bridge.c \ connection.h connection.c common.h common.c -- cgit From c4139033616c53b1f790fe165d1a22fcce292e74 Mon Sep 17 00:00:00 2001 From: Claudio Takahasi Date: Mon, 30 Jun 2008 17:35:47 +0000 Subject: Fixed missing include --- network/main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'network') diff --git a/network/main.c b/network/main.c index 8e18dd99..f18223cc 100644 --- a/network/main.c +++ b/network/main.c @@ -28,6 +28,7 @@ #include #include +#include #include -- cgit