From 342293a80657406a02003452e3a23d097dd9c73e Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 17 Jun 2008 21:18:33 +0000 Subject: Only allow discover requestor to cancel it. --- hcid/device.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- hcid/device.h | 3 +++ 2 files changed, 68 insertions(+), 9 deletions(-) diff --git a/hcid/device.c b/hcid/device.c index 6b9ccac9..6c40cf88 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1026,29 +1026,64 @@ static DBusMessage *set_property(DBusConnection *conn, return invalid_args(msg); } +static void discover_services_req_exit(void *user_data) +{ + struct device *device = user_data; + struct adapter *adapter = device->adapter; + bdaddr_t src, dst; + + debug("DiscoverDevices requestor exited"); + + str2ba(adapter->address, &src); + str2ba(device->address, &dst); + + bt_cancel_discovery(&src, &dst); +} + static DBusMessage *discover_services(DBusConnection *conn, DBusMessage *msg, void *user_data) { struct device *device = user_data; const char *pattern; uint16_t search; + int err; + + if (device->discov_active) + return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress", + "Discover in progress"); if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern, DBUS_TYPE_INVALID) == FALSE) - return NULL; + goto fail; if (strlen(pattern) == 0) { - device_browse(device, conn, msg, TRUE, 0); - return NULL; - } + err = device_browse(device, conn, msg, TRUE, 0); + if (err < 0) + goto fail; + } else { - search = sdp_str2svclass(pattern); - if (!search) - return invalid_args(msg); + search = sdp_str2svclass(pattern); + if (!search) + return invalid_args(msg); - device_browse(device, conn, msg, TRUE, search); + err = device_browse(device, conn, msg, TRUE, search); + if (err < 0) + goto fail; + } + device->discov_active = 1; + device->discov_requestor = g_strdup(dbus_message_get_sender(msg)); + /* track the request owner to cancel it automatically if the owner + * exits */ + device->discov_listener = g_dbus_add_disconnect_watch(conn, + dbus_message_get_sender(msg), + discover_services_req_exit, + device, NULL); return NULL; + +fail: + return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", + "Discovery Failed"); } static DBusMessage *cancel_discover(DBusConnection *conn, @@ -1058,7 +1093,19 @@ static DBusMessage *cancel_discover(DBusConnection *conn, struct adapter *adapter = device->adapter; bdaddr_t src, dst; - str2ba(adapter->address, &src); + if (!device->discov_active) + return g_dbus_create_error(msg, + ERROR_INTERFACE ".Failed", + "No pending discovery"); + + /* only the discover requestor can cancel the inquiry process */ + if (!device->discov_requestor || + strcmp(device->discov_requestor, dbus_message_get_sender(msg))) + return g_dbus_create_error(msg, + ERROR_INTERFACE ".NotAuthorized", + "Not Authorized"); + + str2ba(adapter->address, &src); str2ba(device->address, &dst); if (bt_cancel_discovery(&src, &dst) < 0) @@ -1269,6 +1316,15 @@ static void browse_cb(sdp_list_t *recs, int err, gpointer user_data) DBusMessage *reply; uuid_t uuid; + device->discov_active = 0; + + if (device->discov_requestor) { + g_dbus_remove_watch(req->conn, device->discov_listener); + device->discov_listener = 0; + g_free(device->discov_requestor); + device->discov_requestor = NULL; + } + if (err < 0) goto proceed; diff --git a/hcid/device.h b/hcid/device.h index b476b1da..b142d761 100644 --- a/hcid/device.h +++ b/hcid/device.h @@ -40,6 +40,9 @@ struct device { gboolean temporary; struct agent *agent; guint disconn_timer; + int discov_active; /* Service discovery active */ + char *discov_requestor; /* discovery requestor unique name */ + guint discov_listener; /* For Secure Simple Pairing */ uint8_t cap; -- cgit