From 617faeead1ffd6674cc1ab174815ff1395aec311 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 27 May 2008 22:16:11 +0000 Subject: Convert network connection handling to gdbus API --- network/connection.c | 294 +++++++++++++++++++++------------------------------ 1 file changed, 121 insertions(+), 173 deletions(-) (limited to 'network') diff --git a/network/connection.c b/network/connection.c index 787d4b4f..4d96845d 100644 --- a/network/connection.c +++ b/network/connection.c @@ -78,6 +78,36 @@ struct __service_16 { static DBusConnection *connection = NULL; static const char *prefix = NULL; +static inline DBusMessage *not_supported(DBusMessage *msg) +{ + return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", + "Not suported"); +} + +static inline DBusMessage *already_connected(DBusMessage *msg) +{ + return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", + "Device already connected"); +} + +static inline DBusMessage *not_connected(DBusMessage *msg) +{ + return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", + "Device not connected"); +} + +static inline DBusMessage *no_pending_connect(DBusMessage *msg) +{ + return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", + "Device has no pending connect"); +} + +static inline DBusMessage *connection_attempt_failed(DBusMessage *msg, int err) +{ + return g_dbus_create_error(msg, ERROR_INTERFACE ".ConnectionAttemptFailed", + err ? strerror(err) : "Connection attempt failed"); +} + static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond, gpointer data) { @@ -89,17 +119,20 @@ static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond, "Disconnected", DBUS_TYPE_INVALID); } + info("%s disconnected", nc->dev); + bnep_if_down(nc->dev); nc->state = DISCONNECTED; memset(nc->dev, 0, 16); strncpy(nc->dev, prefix, strlen(prefix)); g_io_channel_close(chan); + return FALSE; } static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, - gpointer data) + gpointer data) { struct network_conn *nc = data; struct bnep_control_rsp *rsp; @@ -165,12 +198,11 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, "Connected", DBUS_TYPE_INVALID); - reply = dbus_message_new_method_return(nc->msg); - pdev = nc->dev; - dbus_message_append_args(reply, DBUS_TYPE_STRING, &pdev, - DBUS_TYPE_INVALID); - send_message_and_unref(connection, reply); + + reply = g_dbus_create_reply(nc->msg, DBUS_TYPE_STRING, &pdev, + DBUS_TYPE_INVALID); + g_dbus_send_message(connection, reply); nc->state = CONNECTED; @@ -179,12 +211,15 @@ static gboolean bnep_connect_cb(GIOChannel *chan, GIOCondition cond, g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL, (GIOFunc) bnep_watchdog_cb, nc); return FALSE; + failed: if (nc->state != DISCONNECTED) { nc->state = DISCONNECTED; - error_connection_attempt_failed(connection, nc->msg, EIO); + reply = connection_attempt_failed(nc->msg, EIO); + g_dbus_send_message(connection, reply); g_io_channel_close(chan); } + return FALSE; } @@ -225,6 +260,7 @@ static void connect_cb(GIOChannel *chan, int err, const bdaddr_t *src, const bdaddr_t *dst, gpointer data) { struct network_conn *nc = data; + DBusMessage *reply; if (err < 0) { error("l2cap connect(): %s (%d)", strerror(-err), -err); @@ -245,233 +281,151 @@ static void connect_cb(GIOChannel *chan, int err, const bdaddr_t *src, failed: nc->state = DISCONNECTED; - error_connection_attempt_failed(connection, nc->msg, -err); + + reply = connection_attempt_failed(nc->msg, -err); + g_dbus_send_message(connection, reply); } -static DBusHandlerResult get_adapter(DBusConnection *conn, DBusMessage *msg, +static DBusMessage *get_adapter(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_conn *nc = data; - DBusMessage *reply; char addr[18]; const char *paddr = addr; ba2str(&nc->src, addr); - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &paddr, - DBUS_TYPE_INVALID); - - return send_message_and_unref(conn, reply); + return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &paddr, + DBUS_TYPE_INVALID); } -static DBusHandlerResult get_address(DBusConnection *conn, DBusMessage *msg, +static DBusMessage *get_address(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_conn *nc = data; - DBusMessage *reply; char addr[18]; const char *paddr = addr; ba2str(&nc->dst, addr); - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &paddr, - DBUS_TYPE_INVALID); - - return send_message_and_unref(conn, reply); + return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &paddr, + DBUS_TYPE_INVALID); } -static DBusHandlerResult get_uuid(DBusConnection *conn, DBusMessage *msg, - void *data) +static DBusMessage *get_uuid(DBusConnection *conn, + DBusMessage *msg, void *data) { struct network_conn *nc = data; const char *uuid; - DBusMessage *reply; uuid = bnep_uuid(nc->id); - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &uuid, - DBUS_TYPE_INVALID); - return send_message_and_unref(conn, reply); + return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &uuid, + DBUS_TYPE_INVALID); } -static DBusHandlerResult get_name(DBusConnection *conn, DBusMessage *msg, - void *data) +static DBusMessage *get_name(DBusConnection *conn, + DBusMessage *msg, void *data) { struct network_conn *nc = data; - DBusMessage *reply; - - if (!nc->name) { - error_failed(conn, msg, "Cannot find service name"); - return DBUS_HANDLER_RESULT_HANDLED; - } - - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &nc->name, - DBUS_TYPE_INVALID); - return send_message_and_unref(conn, reply); + if (!nc->name) + return not_supported(msg); + return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &nc->name, + DBUS_TYPE_INVALID); } -static DBusHandlerResult get_description(DBusConnection *conn, +static DBusMessage *get_description(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_conn *nc = data; - DBusMessage *reply; - - if (!nc->desc) { - error_failed(conn, msg, "Cannot find service description"); - return DBUS_HANDLER_RESULT_HANDLED; - } - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - dbus_message_append_args(reply, DBUS_TYPE_STRING, &nc->desc, - DBUS_TYPE_INVALID); + if (!nc->desc) + return not_supported(msg); - return send_message_and_unref(conn, reply); + return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &nc->desc, + DBUS_TYPE_INVALID); } -static DBusHandlerResult get_interface(DBusConnection *conn, DBusMessage *msg, - void *data) +static DBusMessage *get_interface(DBusConnection *conn, + DBusMessage *msg, void *data) { struct network_conn *nc = data; const char *pdev = nc->dev; - DBusMessage *reply; - if (nc->state != CONNECTED) { - error_failed(conn, msg, "Device not connected"); - return DBUS_HANDLER_RESULT_HANDLED; - } - - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + if (nc->state != CONNECTED) + return not_connected(msg); - dbus_message_append_args(reply, DBUS_TYPE_STRING, &pdev, - DBUS_TYPE_INVALID); - - return send_message_and_unref(conn, reply); + return g_dbus_create_reply(msg, DBUS_TYPE_STRING, &pdev, + DBUS_TYPE_INVALID); } /* Connect and initiate BNEP session */ -static DBusHandlerResult connection_connect(DBusConnection *conn, +static DBusMessage *connection_connect(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_conn *nc = data; - DBusError derr; int err; - if (nc->state != DISCONNECTED) { - error_failed(conn, msg, "Device already connected"); - return DBUS_HANDLER_RESULT_HANDLED; - } - - dbus_error_init(&derr); - if (!dbus_message_get_args(msg, &derr, - DBUS_TYPE_INVALID)) { - error_invalid_arguments(conn, msg, derr.message); - dbus_error_free(&derr); - return DBUS_HANDLER_RESULT_HANDLED; - } + if (nc->state != DISCONNECTED) + return already_connected(msg); nc->state = CONNECTING; nc->msg = dbus_message_ref(msg); err = bt_l2cap_connect(&nc->src, &nc->dst, BNEP_PSM, BNEP_MTU, - connect_cb, nc); + connect_cb, nc); if (err < 0) { error("Connect failed. %s(%d)", strerror(errno), errno); - goto fail; - } - - return DBUS_HANDLER_RESULT_HANDLED; -fail: - if (nc->msg) { dbus_message_unref(nc->msg); nc->msg = NULL; + nc->state = DISCONNECTED; + return connection_attempt_failed(msg, -err); } - nc->state = DISCONNECTED; - error_connection_attempt_failed(conn, msg, errno); - return DBUS_HANDLER_RESULT_HANDLED; + + return NULL; } -static DBusHandlerResult connection_cancel(DBusConnection *conn, +static DBusMessage *connection_cancel(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_conn *nc = data; - DBusMessage *reply; - if (nc->state != CONNECTING) { - error_failed(conn, msg, "Device has no pending connect"); - return DBUS_HANDLER_RESULT_HANDLED; - } + if (nc->state != CONNECTING) + return no_pending_connect(msg); close(nc->sk); nc->state = DISCONNECTED; - reply = dbus_message_new_method_return(msg); - - return send_message_and_unref(conn, reply); + return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); } -static DBusHandlerResult connection_disconnect(DBusConnection *conn, +static DBusMessage *connection_disconnect(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_conn *nc = data; - DBusMessage *reply; - if (nc->state != CONNECTED) { - error_failed(conn, msg, "Device not connected"); - return DBUS_HANDLER_RESULT_HANDLED; - } + if (nc->state != CONNECTED) + return not_connected(msg); bnep_if_down(nc->dev); bnep_kill_connection(&nc->dst); - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; - - return send_message_and_unref(conn, reply); + return g_dbus_create_reply(msg, DBUS_TYPE_INVALID); } -static DBusHandlerResult is_connected(DBusConnection *conn, DBusMessage *msg, - void *data) +static DBusMessage *is_connected(DBusConnection *conn, + DBusMessage *msg, void *data) { struct network_conn *nc = data; - DBusMessage *reply; - gboolean up; - - reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + gboolean up = (nc->state == CONNECTED); - up = (nc->state == CONNECTED); - dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &up, - DBUS_TYPE_INVALID); - - return send_message_and_unref(conn, reply); + return g_dbus_create_reply(msg, DBUS_TYPE_BOOLEAN, &up, + DBUS_TYPE_INVALID); } -static DBusHandlerResult get_info(DBusConnection *conn, +static DBusMessage *get_info(DBusConnection *conn, DBusMessage *msg, void *data) { struct network_conn *nc = data; @@ -483,8 +437,8 @@ static DBusHandlerResult get_info(DBusConnection *conn, const char *paddr = raddr; reply = dbus_message_new_method_return(msg); - if (!reply) - return DBUS_HANDLER_RESULT_NEED_MEMORY; + if (reply == NULL) + return NULL; dbus_message_iter_init_append(reply, &iter); @@ -506,7 +460,7 @@ static DBusHandlerResult get_info(DBusConnection *conn, dbus_message_iter_close_container(&iter, &dict); - return send_message_and_unref(conn, reply); + return reply; } static void connection_free(struct network_conn *nc) @@ -527,12 +481,12 @@ static void connection_free(struct network_conn *nc) if (nc->desc) g_free(nc->desc); - + g_free(nc); nc = NULL; } -static void connection_unregister(DBusConnection *conn, void *data) +static void connection_unregister(void *data) { struct network_conn *nc = data; @@ -541,25 +495,26 @@ static void connection_unregister(DBusConnection *conn, void *data) connection_free(nc); } -static DBusMethodVTable connection_methods[] = { - { "GetAdapter", get_adapter, "", "s" }, - { "GetAddress", get_address, "", "s" }, - { "GetUUID", get_uuid, "", "s" }, - { "GetName", get_name, "", "s" }, - { "GetDescription", get_description, "", "s" }, - { "GetInterface", get_interface, "", "s" }, - { "Connect", connection_connect, "", "s" }, - { "CancelConnect", connection_cancel, "", "" }, - { "Disconnect", connection_disconnect, "", "" }, - { "IsConnected", is_connected, "", "b" }, - { "GetInfo", get_info, "", "a{sv}" }, - { NULL, NULL, NULL, NULL } +static GDBusMethodTable connection_methods[] = { + { "GetAdapter", "", "s", get_adapter }, + { "GetAddress", "", "s", get_address }, + { "GetUUID", "", "s", get_uuid }, + { "GetName", "", "s", get_name }, + { "GetDescription", "", "s", get_description }, + { "GetInterface", "", "s", get_interface }, + { "Connect", "", "s", connection_connect, + G_DBUS_METHOD_FLAG_ASYNC }, + { "CancelConnect", "", "", connection_cancel }, + { "Disconnect", "", "", connection_disconnect }, + { "IsConnected", "", "b", is_connected }, + { "GetInfo", "", "a{sv}",get_info }, + { } }; -static DBusSignalVTable connection_signals[] = { +static GDBusSignalTable connection_signals[] = { { "Connected", "" }, { "Disconnected", "" }, - { NULL, NULL } + { } }; int connection_register(const char *path, bdaddr_t *src, bdaddr_t *dst, @@ -579,20 +534,13 @@ int connection_register(const char *path, bdaddr_t *src, bdaddr_t *dst, nc = g_new0(struct network_conn, 1); - /* register path */ - if (!dbus_connection_create_object_path(connection, path, nc, - connection_unregister)) { - connection_free(nc); - return -1; - } - - if (!dbus_connection_register_interface(connection, path, - NETWORK_CONNECTION_INTERFACE, - connection_methods, - connection_signals, NULL)) { + if (g_dbus_register_interface(connection, path, + NETWORK_CONNECTION_INTERFACE, + connection_methods, + connection_signals, NULL, + nc, connection_unregister) == FALSE) { error("D-Bus failed to register %s interface", NETWORK_CONNECTION_INTERFACE); - dbus_connection_destroy_object_path(connection, path); return -1; } -- cgit