summaryrefslogtreecommitdiffstats
path: root/network/connection.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2008-05-27 22:16:11 +0000
committerMarcel Holtmann <marcel@holtmann.org>2008-05-27 22:16:11 +0000
commit617faeead1ffd6674cc1ab174815ff1395aec311 (patch)
tree9bfd78be0cad401429b92482adadf3e458802e04 /network/connection.c
parent27b076bdd6b65521f9e37fc6e088ea9396105d3b (diff)
Convert network connection handling to gdbus API
Diffstat (limited to 'network/connection.c')
-rw-r--r--network/connection.c294
1 files changed, 121 insertions, 173 deletions
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;
}