summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--serial/manager.c24
-rw-r--r--serial/port.c32
-rw-r--r--serial/port.h2
3 files changed, 46 insertions, 12 deletions
diff --git a/serial/manager.c b/serial/manager.c
index cf247a0f..6bce2d69 100644
--- a/serial/manager.c
+++ b/serial/manager.c
@@ -879,9 +879,8 @@ static DBusHandlerResult disconnect_service(DBusConnection *conn,
DBusMessage *msg, void *data)
{
DBusError derr;
- const char *name, *owner;
- int err;
- int id;
+ const char *name;
+ int err, id;
dbus_error_init(&derr);
if (!dbus_message_get_args(msg, &derr,
@@ -895,22 +894,23 @@ static DBusHandlerResult disconnect_service(DBusConnection *conn,
if (sscanf(name, "/dev/rfcomm%d", &id) != 1)
return err_invalid_args(conn, msg, "invalid RFCOMM node");
- /* FIXME: Remove the listener */
- owner = port_get_owner(conn, id);
- if (!owner)
+ err = port_remove_listener(dbus_message_get_sender(msg), name);
+ if (err < 0)
return err_does_not_exist(conn, msg, "Invalid RFCOMM node");
- if (strcmp(owner, dbus_message_get_sender(msg)) != 0)
- return err_not_authorized(conn, msg);
-
err = rfcomm_release(id);
if (err < 0)
return err_failed(conn, msg, strerror(-err));
- /* FIXME: Remove the node from the list */
-
- return send_message_and_unref(conn,
+ send_message_and_unref(conn,
dbus_message_new_method_return(msg));
+
+ dbus_connection_emit_signal(conn, SERIAL_MANAGER_PATH,
+ SERIAL_MANAGER_INTERFACE, "ServiceDisconnected" ,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_INVALID);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
}
static DBusHandlerResult cancel_connect_service(DBusConnection *conn,
diff --git a/serial/port.c b/serial/port.c
index 1ff26714..00bddab1 100644
--- a/serial/port.c
+++ b/serial/port.c
@@ -73,6 +73,19 @@ struct open_context {
static GSList *connected_nodes = NULL;
+static struct rfcomm_node *find_node_by_name(GSList *nodes, const char *name)
+{
+ GSList *l;
+
+ for (l = nodes; l != NULL; l = l->next) {
+ struct rfcomm_node *node = l->data;
+ if (!strcmp(node->name, name))
+ return node;
+ }
+
+ return NULL;
+}
+
static DBusHandlerResult port_connect(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -187,6 +200,25 @@ int port_add_listener(DBusConnection *conn, int id, int fd,
(name_cb_t) connection_owner_exited, node);
}
+int port_remove_listener(const char *owner, const char *name)
+{
+ struct rfcomm_node *node;
+
+ node = find_node_by_name(connected_nodes, name);
+ if (!node)
+ return -ENOENT;
+ if (strcmp(node->owner, owner) != 0)
+ return -EPERM;
+
+ name_listener_remove(node->conn, owner,
+ (name_cb_t) connection_owner_exited, node);
+
+ connected_nodes = g_slist_remove(connected_nodes, node);
+ rfcomm_node_free(node);
+
+ return 0;
+}
+
int port_register(DBusConnection *conn, int id, const char *name, char *ppath)
{
char path[MAX_PATH_LENGTH];
diff --git a/serial/port.h b/serial/port.h
index 1b17fb66..cb2ecf65 100644
--- a/serial/port.h
+++ b/serial/port.h
@@ -27,6 +27,8 @@ typedef void (*udata_free_t) (void *data);
int port_add_listener(DBusConnection *conn, int id, int fd,
const char *name, const char *owner);
+int port_remove_listener(const char *owner, const char *name);
+
int port_register(DBusConnection *conn, int id, const char *name, char *ppath);
const char *port_get_owner(DBusConnection *conn, int16_t id);