summaryrefslogtreecommitdiffstats
path: root/hcid/dbus-rfcomm.c
diff options
context:
space:
mode:
authorUlisses Furquim <ulissesf@gmail.com>2006-09-12 19:41:45 +0000
committerUlisses Furquim <ulissesf@gmail.com>2006-09-12 19:41:45 +0000
commitb10bad4361a0f420e39484e6ff30125e4a40d281 (patch)
tree48fb3fec3ea60b524a4dcdd87aecca892dac9917 /hcid/dbus-rfcomm.c
parentb809f2edd68ddd472249998ad54e0fdaa4e51c2e (diff)
Add name listener for RFCOMM.Connect() requestor
Diffstat (limited to 'hcid/dbus-rfcomm.c')
-rw-r--r--hcid/dbus-rfcomm.c46
1 files changed, 34 insertions, 12 deletions
diff --git a/hcid/dbus-rfcomm.c b/hcid/dbus-rfcomm.c
index a430a543..1258f337 100644
--- a/hcid/dbus-rfcomm.c
+++ b/hcid/dbus-rfcomm.c
@@ -59,6 +59,8 @@ struct rfcomm_node {
int16_t id; /* Device id */
char name[16]; /* Node filename */
+ DBusConnection *conn; /* for name listener handling */
+
/* The following members are only valid for connected nodes */
GIOChannel *io; /* IO Channel for the connection */
guint io_id; /* ID for IO channel */
@@ -93,6 +95,12 @@ static void rfcomm_node_free(struct rfcomm_node *node)
{
if (node->owner)
free(node->owner);
+ if (node->io) {
+ g_io_remove_watch(node->io_id);
+ g_io_channel_unref(node->io);
+ }
+ if (node->conn)
+ dbus_connection_unref(node->conn);
free(node);
}
@@ -173,12 +181,6 @@ static int rfcomm_release(struct rfcomm_node *node, int *err)
debug("rfcomm_release(%s)", node->name);
- if (node->io) {
- g_io_remove_watch(node->io_id);
- g_io_channel_unref(node->io);
- node->io = NULL;
- }
-
memset(&req, 0, sizeof(req));
req.dev_id = node->id;
req.flags = (1 << RFCOMM_HANGUP_NOW);
@@ -194,12 +196,23 @@ static int rfcomm_release(struct rfcomm_node *node, int *err)
return 0;
}
+static void rfcomm_connect_req_exit(const char *name, void *data)
+{
+ struct rfcomm_node *node = data;
+ debug("RFCOMM.Connect() requestor %s exited. Releasing %s node",
+ name, node->name);
+ rfcomm_release(node, NULL);
+ connected_nodes = slist_remove(connected_nodes, node);
+ rfcomm_node_free(node);
+}
+
static gboolean rfcomm_disconnect_cb(GIOChannel *io, GIOCondition cond,
- struct rfcomm_node *node)
+ struct rfcomm_node *node)
{
debug("RFCOMM node %s was disconnected", node->name);
+ name_listener_remove(node->conn, node->owner,
+ rfcomm_connect_req_exit, node);
connected_nodes = slist_remove(connected_nodes, node);
- g_io_channel_unref(node->io);
rfcomm_node_free(node);
return FALSE;
}
@@ -240,6 +253,10 @@ static void rfcomm_connect_cb_devnode_opened(int fd,
connected_nodes = slist_append(connected_nodes, node);
+ node->conn = dbus_connection_ref(c->conn);
+ name_listener_add(node->conn, node->owner,
+ rfcomm_connect_req_exit, node);
+
goto done;
failed:
@@ -683,22 +700,25 @@ static DBusHandlerResult rfcomm_cancel_connect_by_ch_req(DBusConnection *conn,
}
static DBusHandlerResult rfcomm_disconnect_req(DBusConnection *conn,
- DBusMessage *msg, void *data)
+ DBusMessage *msg, void *data)
{
+ struct rfcomm_node *node;
DBusMessage *reply;
const char *name;
- struct rfcomm_node *node;
int err;
if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_STRING, &name,
- DBUS_TYPE_INVALID))
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_INVALID))
return error_invalid_arguments(conn, msg);
node = find_node_by_name(connected_nodes, name);
if (!node)
return error_not_connected(conn, msg);
+ if (strcmp(node->owner, dbus_message_get_sender(msg)))
+ return error_not_authorized(conn, msg);
+
reply = dbus_message_new_method_return(msg);
if (!reply)
return DBUS_HANDLER_RESULT_NEED_MEMORY;
@@ -708,6 +728,8 @@ static DBusHandlerResult rfcomm_disconnect_req(DBusConnection *conn,
return error_failed(conn, msg, err);
}
+ name_listener_remove(node->conn, node->owner,
+ rfcomm_connect_req_exit, node);
connected_nodes = slist_remove(connected_nodes, node);
rfcomm_node_free(node);