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/connection.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 network/connection.c (limited to 'network/connection.c') 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" -- 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/connection.c') 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 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 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'network/connection.c') 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; +} -- 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 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'network/connection.c') 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; -- 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 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'network/connection.c') 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); -- 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/connection.c') 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/connection.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'network/connection.c') 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++); -- 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 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'network/connection.c') 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++); -- 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/connection.c') 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 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/connection.c') 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 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/connection.c') 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 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/connection.c') 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/connection.c') 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 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/connection.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'network/connection.c') 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 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/connection.c') 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 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 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 66 insertions(+), 5 deletions(-) (limited to 'network/connection.c') 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; -- 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/connection.c') 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 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 - 1 file changed, 1 deletion(-) (limited to 'network/connection.c') 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); -- 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/connection.c') 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 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 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) (limited to 'network/connection.c') 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; +} -- 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/connection.c') 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/connection.c') 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/connection.c') 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 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 ++++++++----------------------------- 1 file changed, 8 insertions(+), 29 deletions(-) (limited to 'network/connection.c') 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; } -- 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 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) (limited to 'network/connection.c') 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) { -- 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/connection.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'network/connection.c') 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); -- 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/connection.c') 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 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/connection.c') 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 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 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'network/connection.c') 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); +} + -- 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 ++++ 1 file changed, 4 insertions(+) (limited to 'network/connection.c') 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; -- 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/connection.c') 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 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 ++++++++++++++++++++-------------------------------- 1 file changed, 32 insertions(+), 50 deletions(-) (limited to 'network/connection.c') 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); -- 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 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'network/connection.c') 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); -- 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 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'network/connection.c') 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); } - -- 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/connection.c') 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 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 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) (limited to 'network/connection.c') 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; +} -- 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 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) (limited to 'network/connection.c') 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); +} -- 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 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 35 deletions(-) (limited to 'network/connection.c') 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; +} -- 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/connection.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'network/connection.c') 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); } -- 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/connection.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'network/connection.c') 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; } -- 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/connection.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'network/connection.c') 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); -- 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network/connection.c') 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 } }; -- 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 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'network/connection.c') 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); -- 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/connection.c') 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 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/connection.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'network/connection.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; } -- 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/connection.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network/connection.c') 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 -- 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/connection.c | 1 + 1 file changed, 1 insertion(+) (limited to 'network/connection.c') 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/connection.c') 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 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/connection.c | 1 - 1 file changed, 1 deletion(-) (limited to 'network/connection.c') 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" -- 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'network/connection.c') 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" -- 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/connection.c') 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 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/connection.c | 1 + 1 file changed, 1 insertion(+) (limited to 'network/connection.c') 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 -- 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 -- 1 file changed, 2 deletions(-) (limited to 'network/connection.c') 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, -- 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/connection.c') 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 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 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'network/connection.c') 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; -- 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/connection.c') 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 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'network/connection.c') 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); -- 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 ++ 1 file changed, 2 insertions(+) (limited to 'network/connection.c') 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" -- cgit