summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--serial/manager.c18
-rw-r--r--serial/port.c27
-rw-r--r--serial/port.h2
3 files changed, 44 insertions, 3 deletions
diff --git a/serial/manager.c b/serial/manager.c
index 6bce2d69..9a6972da 100644
--- a/serial/manager.c
+++ b/serial/manager.c
@@ -777,7 +777,23 @@ done:
static DBusHandlerResult remove_port(DBusConnection *conn,
DBusMessage *msg, void *data)
{
- return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+ DBusError derr;
+ const char *path;
+
+ dbus_error_init(&derr);
+ if (!dbus_message_get_args(msg, &derr,
+ DBUS_TYPE_STRING, &path,
+ DBUS_TYPE_INVALID)) {
+ err_invalid_args(conn, msg, derr.message);
+ dbus_error_free(&derr);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+
+ if (port_unregister(path) < 0)
+ return err_does_not_exist(conn, msg, "path doesn't exist");
+
+ return send_message_and_unref(conn,
+ dbus_message_new_method_return(msg));
}
static DBusHandlerResult connect_service(DBusConnection *conn,
diff --git a/serial/port.c b/serial/port.c
index 00bddab1..76e00e01 100644
--- a/serial/port.c
+++ b/serial/port.c
@@ -72,6 +72,7 @@ struct open_context {
};
static GSList *connected_nodes = NULL;
+static GSList *bound_nodes = NULL;
static struct rfcomm_node *find_node_by_name(GSList *nodes, const char *name)
{
@@ -170,12 +171,13 @@ static gboolean rfcomm_disconnect_cb(GIOChannel *io,
return FALSE;
}
-static void port_unregister(DBusConnection *conn, void *data)
+static void port_handler_unregister(DBusConnection *conn, void *data)
{
struct rfcomm_node *node = data;
debug("Unregistered serial port: %s", node->name);
+ bound_nodes = g_slist_remove(bound_nodes, node);
rfcomm_node_free(node);
}
@@ -232,7 +234,7 @@ int port_register(DBusConnection *conn, int id, const char *name, char *ppath)
snprintf(path, MAX_PATH_LENGTH, "%s/rfcomm%d", SERIAL_MANAGER_PATH, id);
if (!dbus_connection_create_object_path(conn, path, node,
- port_unregister)) {
+ port_handler_unregister)) {
error("D-Bus failed to register %s path", path);
rfcomm_node_free(node);
return -1;
@@ -253,6 +255,27 @@ int port_register(DBusConnection *conn, int id, const char *name, char *ppath)
if (ppath)
strcpy(ppath, path);
+ bound_nodes = g_slist_append(bound_nodes, node);
+
+ return 0;
+}
+
+int port_unregister(const char *path)
+{
+ struct rfcomm_node *node;
+ char name[16];
+ int id;
+
+ if (sscanf(path, SERIAL_MANAGER_PATH"/rfcomm%d", &id) != 1)
+ return -ENOENT;
+
+ snprintf(name, sizeof(name), "/dev/rfcomm%d", id);
+ node = find_node_by_name(bound_nodes, name);
+ if (!node)
+ return -ENOENT;
+
+ dbus_connection_destroy_object_path(node->conn, path);
+
return 0;
}
diff --git a/serial/port.h b/serial/port.h
index cb2ecf65..c6a74548 100644
--- a/serial/port.h
+++ b/serial/port.h
@@ -31,6 +31,8 @@ int port_remove_listener(const char *owner, const char *name);
int port_register(DBusConnection *conn, int id, const char *name, char *ppath);
+int port_unregister(const char *path);
+
const char *port_get_owner(DBusConnection *conn, int16_t id);
int port_open(const char *dev, open_notify_t notify,