summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--serial/manager.c33
-rw-r--r--serial/port.c42
-rw-r--r--serial/port.h6
3 files changed, 51 insertions, 30 deletions
diff --git a/serial/manager.c b/serial/manager.c
index c33f51cb..538931a9 100644
--- a/serial/manager.c
+++ b/serial/manager.c
@@ -189,9 +189,7 @@ static int rfcomm_bind(bdaddr_t *src, bdaddr_t *dst, uint8_t ch)
static void open_notify(int fd, int err, void *data)
{
char port_name[16];
- char path[MAX_PATH_LENGTH];
const char *pname = port_name;
- const char *ppath = path;
const char *owner;
DBusMessage *reply;
struct pending_connect *pc = data;
@@ -208,7 +206,7 @@ static void open_notify(int fd, int err, void *data)
return;
}
- /* Check if the caller is still present */
+ /* FIXME: it must be a per request listener */
owner = dbus_message_get_sender(pc->msg);
if (!dbus_bus_name_has_owner(pc->conn, owner, NULL)) {
error("Connect requestor %s exited", owner);
@@ -226,17 +224,12 @@ static void open_notify(int fd, int err, void *data)
send_message_and_unref(pc->conn, reply);
/* Send the D-Bus signal */
- port_register(pc->conn, pc->id, fd, pname, owner, path);
- dbus_connection_emit_signal(pc->conn, SERIAL_MANAGER_PATH,
- SERIAL_MANAGER_INTERFACE, "PortCreated" ,
- DBUS_TYPE_STRING, &ppath,
- DBUS_TYPE_INVALID);
-
dbus_connection_emit_signal(pc->conn, SERIAL_MANAGER_PATH,
SERIAL_MANAGER_INTERFACE, "ServiceConnected" ,
DBUS_TYPE_STRING, &pname,
DBUS_TYPE_INVALID);
+ port_add_listener(pc->conn, pc->id, fd, port_name, owner);
}
static gboolean rfcomm_connect_cb(GIOChannel *chan,
@@ -453,7 +446,7 @@ static void record_reply(DBusPendingCall *call, void *data)
}
snprintf(port_name, sizeof(port_name), "/dev/rfcomm%d", err);
- port_register(pc->conn, err, -1, port_name, NULL, path);
+ port_register(pc->conn, err, port_name, path);
reply = dbus_message_new_method_return(pc->msg);
dbus_message_append_args(reply,
@@ -728,7 +721,7 @@ static DBusHandlerResult create_port(DBusConnection *conn,
return err_failed(conn, msg, strerror(-err));
snprintf(port_name, sizeof(port_name), "/dev/rfcomm%d", err);
- port_register(conn, err, -1, port_name, NULL, path);
+ port_register(conn, err, port_name, path);
reply = dbus_message_new_method_return(msg);
if (!reply)
@@ -920,12 +913,30 @@ static DBusHandlerResult cancel_connect_service(DBusConnection *conn,
static void manager_unregister(DBusConnection *conn, void *data)
{
+ char **dev;
+ int i;
+
if (pending_connects) {
g_slist_foreach(pending_connects,
(GFunc) pending_connect_free, NULL);
g_slist_free(pending_connects);
pending_connects = NULL;
}
+
+ /* Unregister all paths in serial hierarchy */
+ if (!dbus_connection_list_registered(conn, SERIAL_MANAGER_PATH, &dev))
+ return;
+
+ for (i = 0; dev[i]; i++) {
+ char dev_path[MAX_PATH_LENGTH];
+
+ snprintf(dev_path, sizeof(dev_path), "%s/%s", SERIAL_MANAGER_PATH,
+ dev[i]);
+
+ dbus_connection_destroy_object_path(conn, dev_path);
+ }
+
+ dbus_free_string_array(dev);
}
static DBusMethodVTable manager_methods[] = {
diff --git a/serial/port.c b/serial/port.c
index 7d3b95c8..5bd217b7 100644
--- a/serial/port.c
+++ b/serial/port.c
@@ -134,7 +134,6 @@ static void connection_owner_exited(const char *name, struct rfcomm_node *node)
DBUS_TYPE_INVALID);
connected_nodes = g_slist_remove(connected_nodes, node);
- dbus_connection_destroy_object_path(node->conn, path);
}
static gboolean rfcomm_disconnect_cb(GIOChannel *io,
@@ -168,8 +167,29 @@ static void port_unregister(DBusConnection *conn, void *data)
rfcomm_node_free(node);
}
-int port_register(DBusConnection *conn, int id, int fd,
- const char *name, const char *owner, char *ppath)
+int port_add_listener(DBusConnection *conn, int id, int fd,
+ const char *name, const char *owner)
+{
+ struct rfcomm_node *node;
+
+ node = g_new0(struct rfcomm_node, 1);
+ node->id = id;
+ node->name = g_strdup(name);
+ node->conn = dbus_connection_ref(conn);
+ node->owner = g_strdup(owner);
+ node->io = g_io_channel_unix_new(fd);
+ node->io_id = g_io_add_watch(node->io, G_IO_ERR | G_IO_NVAL | G_IO_HUP,
+ (GIOFunc) rfcomm_disconnect_cb, node);
+
+ connected_nodes = g_slist_append(connected_nodes, node);
+
+ /* Serial port connection listener */
+ return name_listener_add(conn, owner,
+ (name_cb_t) connection_owner_exited, node);
+
+}
+
+int port_register(DBusConnection *conn, int id, const char *name, char *ppath)
{
char path[MAX_PATH_LENGTH];
struct rfcomm_node *node;
@@ -198,24 +218,12 @@ int port_register(DBusConnection *conn, int id, int fd,
return -1;
}
- info("Registered RFCOMM:%s, path:%s owner:%s", name, path, owner);
+ info("Registered RFCOMM:%s, path:%s", name, path);
if (ppath)
strcpy(ppath, path);
- if (fd < 0)
- return 0;
-
- node->owner = g_strdup(owner);
- node->io = g_io_channel_unix_new(fd);
- node->io_id = g_io_add_watch(node->io, G_IO_ERR | G_IO_NVAL | G_IO_HUP,
- (GIOFunc) rfcomm_disconnect_cb, node);
-
- connected_nodes = g_slist_append(connected_nodes, node);
-
- /* Serial port connection listener */
- return name_listener_add(node->conn, owner,
- (name_cb_t) connection_owner_exited, node);
+ return 0;
}
const char *port_get_owner(DBusConnection *conn, int16_t id)
diff --git a/serial/port.h b/serial/port.h
index 9cab2847..1b17fb66 100644
--- a/serial/port.h
+++ b/serial/port.h
@@ -24,8 +24,10 @@
typedef void (*open_notify_t) (int fd, int err, void *data);
typedef void (*udata_free_t) (void *data);
-int port_register(DBusConnection *conn, int id, int fd,
- const char *name, const char *owner, char *path);
+int port_add_listener(DBusConnection *conn, int id, int fd,
+ const char *name, const char *owner);
+
+int port_register(DBusConnection *conn, int id, const char *name, char *ppath);
const char *port_get_owner(DBusConnection *conn, int16_t id);