summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2006-10-05 14:01:47 +0000
committerJohan Hedberg <johan.hedberg@nokia.com>2006-10-05 14:01:47 +0000
commit2b275bebdf4c5a9c85dfe847279b9bb68fc22cb7 (patch)
tree719b2348d194264622e4be866335355d6b2cc3e4
parent7e67b8266268dde84711740bceb373c4c271f3eb (diff)
Make audit queuing more sensible with many devices around
-rw-r--r--hcid/dbus-common.c4
-rw-r--r--hcid/dbus-test.c115
-rw-r--r--hcid/dbus.c6
-rw-r--r--hcid/dbus.h2
4 files changed, 77 insertions, 50 deletions
diff --git a/hcid/dbus-common.c b/hcid/dbus-common.c
index b1ece10d..74e2d3ae 100644
--- a/hcid/dbus-common.c
+++ b/hcid/dbus-common.c
@@ -219,8 +219,6 @@ int name_listener_add(DBusConnection *connection, const char *name,
char match_string[128];
int first;
- debug("name_listener_add(%s)", name);
-
if (!name_listener_initialized) {
if (!dbus_connection_add_filter(connection, name_exit_filter, NULL, NULL)) {
error("dbus_connection_add_filter() failed");
@@ -235,6 +233,8 @@ int name_listener_add(DBusConnection *connection, const char *name,
if (!first)
return 0;
+ debug("name_listener_add(%s)", name);
+
snprintf(match_string, sizeof(match_string),
"interface=%s,member=NameOwnerChanged,arg0=%s",
DBUS_INTERFACE_DBUS, name);
diff --git a/hcid/dbus-test.c b/hcid/dbus-test.c
index 74ab8abf..a18a5005 100644
--- a/hcid/dbus-test.c
+++ b/hcid/dbus-test.c
@@ -164,47 +164,6 @@ static gboolean audit_in_progress(void)
return FALSE;
}
-static void process_audits_list(void)
-{
- while (audits) {
- struct adapter *adapter;
- struct audit *audit;
- int sk;
-
- audit = audits->data;
-
- adapter = NULL;
-
- dbus_connection_get_object_path_data(audit->conn,
- audit->adapter_path,
- (void *) &adapter);
-
- if (!adapter) {
- audits = slist_remove(audits, audit);
- name_listener_remove(audit->conn, audit->requestor,
- (name_cb_t) audit_requestor_exited, audit);
- audit_free(audit);
- continue;
- }
-
- sk = l2raw_connect(adapter->address, &audit->peer);
- if (sk < 0) {
- send_audit_status(audit, "AuditRemoteDeviceFailed");
- audits = slist_remove(audits, audit);
- name_listener_remove(audit->conn, audit->requestor,
- (name_cb_t) audit_requestor_exited, audit);
- audit_free(audit);
- continue;
- }
-
- audit->io = g_io_channel_unix_new(sk);
- audit->io_id = g_io_add_watch(audit->io,
- G_IO_OUT | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
- (GIOFunc) l2raw_connect_complete, audit);
- return;
- }
-}
-
static gboolean l2raw_input_timer(struct audit *audit)
{
error("l2raw_input_timer: Timed out while waiting for input");
@@ -325,9 +284,10 @@ failed:
audits = slist_remove(audits, audit);
name_listener_remove(audit->conn, audit->requestor,
(name_cb_t) audit_requestor_exited, audit);
- audit_free(audit);
- process_audits_list();
+ process_audits_list(audit->adapter_path);
+
+ audit_free(audit);
return FALSE;
}
@@ -408,6 +368,7 @@ static DBusHandlerResult audit_remote_device(DBusConnection *conn,
const char *address;
struct audit *audit;
struct adapter *adapter = data;
+ gboolean queue;
dbus_error_init(&err);
dbus_message_get_args(msg, &err,
@@ -425,9 +386,6 @@ static DBusHandlerResult audit_remote_device(DBusConnection *conn,
str2ba(address, &peer);
str2ba(adapter->address, &local);
- if (adapter->disc_active)
- return error_discover_in_progress(conn, msg);
-
pending_remote_name_cancel(adapter);
if (adapter->bonding)
@@ -436,9 +394,18 @@ static DBusHandlerResult audit_remote_device(DBusConnection *conn,
if (slist_find(adapter->pin_reqs, &peer, pin_req_cmp))
return error_bonding_in_progress(conn, msg);
+ /* Just return if an audit for the same device is already queued */
+ if (slist_find(audits, &peer, audit_addr_cmp))
+ return DBUS_HANDLER_RESULT_HANDLED;
+
if (!read_l2cap_info(&local, &peer, NULL, NULL, NULL, NULL))
return error_audit_already_exists(conn, msg);
+ if (adapter->disc_active || (adapter->pdisc_active && !adapter->pinq_idle))
+ queue = TRUE;
+ else
+ queue = audit_in_progress();
+
reply = dbus_message_new_method_return(msg);
if (!reply)
return DBUS_HANDLER_RESULT_NEED_MEMORY;
@@ -449,7 +416,7 @@ static DBusHandlerResult audit_remote_device(DBusConnection *conn,
return DBUS_HANDLER_RESULT_NEED_MEMORY;
}
- if (!audit_in_progress()) {
+ if (!queue) {
int sk;
sk = l2raw_connect(adapter->address, &peer);
@@ -639,3 +606,57 @@ DBusHandlerResult handle_test_method(DBusConnection *conn, DBusMessage *msg, voi
return error_unknown_method(conn, msg);
}
+
+void process_audits_list(const char *adapter_path)
+{
+ struct slist *l, *next;
+
+ for (l = audits; l != NULL; l = next) {
+ struct adapter *adapter;
+ struct audit *audit;
+ int sk;
+
+ audit = l->data;
+ next = l->next;
+
+ if (strcmp(adapter_path, audit->adapter_path))
+ continue;
+
+ if (audit->io)
+ return;
+
+ adapter = NULL;
+
+ dbus_connection_get_object_path_data(audit->conn,
+ audit->adapter_path,
+ (void *) &adapter);
+
+ if (!adapter) {
+ audits = slist_remove(audits, audit);
+ name_listener_remove(audit->conn, audit->requestor,
+ (name_cb_t) audit_requestor_exited, audit);
+ audit_free(audit);
+ continue;
+ }
+
+ if (adapter->disc_active || (adapter->pdisc_active && !adapter->pinq_idle))
+ continue;
+
+ sk = l2raw_connect(adapter->address, &audit->peer);
+ if (sk < 0) {
+ send_audit_status(audit, "AuditRemoteDeviceFailed");
+ audits = slist_remove(audits, audit);
+ name_listener_remove(audit->conn, audit->requestor,
+ (name_cb_t) audit_requestor_exited, audit);
+ audit_free(audit);
+ continue;
+ }
+
+ audit->io = g_io_channel_unix_new(sk);
+ audit->io_id = g_io_add_watch(audit->io,
+ G_IO_OUT | G_IO_NVAL | G_IO_HUP | G_IO_ERR,
+ (GIOFunc) l2raw_connect_complete, audit);
+ return;
+ }
+}
+
diff --git a/hcid/dbus.c b/hcid/dbus.c
index 689ce46f..89de4054 100644
--- a/hcid/dbus.c
+++ b/hcid/dbus.c
@@ -1058,7 +1058,8 @@ void hcid_dbus_inquiry_complete(bdaddr_t *local)
id = hci_devid(local_addr);
if (id < 0) {
error("No matching device id for %s", local_addr);
- goto done;
+ bt_free(local_addr);
+ return;
}
snprintf(path, sizeof(path), "%s/hci%d", BASE_PATH, id);
@@ -1141,6 +1142,9 @@ void hcid_dbus_inquiry_complete(bdaddr_t *local)
}
done:
+ /* Proceed with any queued up audits */
+ process_audits_list(path);
+
bt_free(local_addr);
}
diff --git a/hcid/dbus.h b/hcid/dbus.h
index 8ae3bdb8..2d6dda62 100644
--- a/hcid/dbus.h
+++ b/hcid/dbus.h
@@ -209,6 +209,8 @@ int l2raw_connect(const char *local, const bdaddr_t *remote);
int check_address(const char *addr);
+void process_audits_list(const char *adapter_path);
+
DBusHandlerResult handle_test_method(DBusConnection *conn, DBusMessage *msg, void *data);
DBusHandlerResult handle_security_method(DBusConnection *conn, DBusMessage *msg, void *data);