diff --git a/src/adapter.c b/src/adapter.c
index d7f8c14..a6a4a4b 100644
--- a/src/adapter.c
+++ b/src/adapter.c
GSList *devices; /* Devices structure pointers */
GSList *mode_sessions; /* Request Mode sessions */
GSList *disc_sessions; /* Discovery sessions */
+ struct session_req *scanning_session;
GSList *connect_list; /* Devices to connect when found */
guint discov_id; /* Discovery timer */
gboolean discovering; /* Discovery active */
DBusMessage *msg, uint8_t mode,
GDBusWatchFunction cb)
{
- const char *sender = dbus_message_get_sender(msg);
+ const char *sender;
struct session_req *req;
req = g_new0(struct session_req, 1);
req->adapter = adapter;
- req->msg = dbus_message_ref(msg);
req->mode = mode;
+ if (msg == NULL)
+ return session_ref(req);
+
+ req->msg = dbus_message_ref(msg);
+
if (cb == NULL)
return session_ref(req);
+ sender = dbus_message_get_sender(msg);
req->owner = g_strdup(sender);
req->id = g_dbus_add_disconnect_watch(btd_get_dbus_connection(),
sender, cb, req, NULL);
for (; list; list = list->next) {
struct session_req *req = list->data;
- if (g_str_equal(req->owner, sender))
+ /* req->owner may be NULL if the session has been added by the
+ * daemon itself, so we use g_strcmp0 instead of g_str_equal */
+ if (g_strcmp0(req->owner, sender) == 0)
return req;
}
struct btd_adapter *adapter = req->adapter;
/* Ignore set_mode session */
- if (req->owner == NULL)
+ if (req->owner == NULL && adapter->pending_mode)
return;
DBG("%s session %p with %s deactivated",
struct btd_adapter *adapter = user_data;
adapter->discov_id = 0;
- mgmt_start_discovery(adapter->dev_id);
+
+ if (adapter->scanning_session &&
+ g_slist_length(adapter->disc_sessions) == 1)
+ mgmt_start_le_scanning(adapter->dev_id);
+ else
+ mgmt_start_discovery(adapter->dev_id);
return FALSE;
}
void adapter_connect_list_add(struct btd_adapter *adapter,
struct btd_device *device)
{
+ struct session_req *req;
+
if (g_slist_find(adapter->connect_list, device)) {
DBG("ignoring already added device %s",
device_get_path(device));
btd_device_ref(device));
DBG("%s added to %s's connect_list", device_get_path(device),
adapter->name);
+
+ if (!adapter->up)
+ return;
+
+ if (adapter->off_requested)
+ return;
+
+ if (adapter->scanning_session)
+ return;
+
+ if (adapter->disc_sessions == NULL)
+ adapter->discov_id = g_idle_add(discovery_cb, adapter);
+
+ req = create_session(adapter, NULL, 0, NULL);
+ adapter->disc_sessions = g_slist_append(adapter->disc_sessions, req);
+ adapter->scanning_session = req;
}
void adapter_connect_list_remove(struct btd_adapter *adapter,
void btd_adapter_start(struct btd_adapter *adapter)
{
+ struct session_req *req;
char address[18];
gboolean powered;
info("Adapter %s has been enabled", adapter->path);
- if (g_slist_length(adapter->connect_list) > 0)
- mgmt_start_le_scanning(adapter->dev_id);
+ if (g_slist_length(adapter->connect_list) == 0 ||
+ adapter->disc_sessions != NULL)
+ return;
+
+ req = create_session(adapter, NULL, 0, NULL);
+ adapter->disc_sessions = g_slist_append(adapter->disc_sessions, req);
+ adapter->scanning_session = req;
+
+ adapter->discov_id = g_idle_add(discovery_cb, adapter);
}
static void reply_pending_requests(struct btd_adapter *adapter)
connect_list_len = g_slist_length(adapter->connect_list);
+ if (connect_list_len == 0 && adapter->scanning_session) {
+ session_unref(adapter->scanning_session);
+ adapter->scanning_session = NULL;
+ }
+
if (adapter_has_discov_sessions(adapter)) {
adapter->discov_id = g_idle_add(discovery_cb, adapter);
g_slist_length(adapter->disc_sessions));
return;
}
-
- if (connect_list_len > 0) {
- mgmt_start_le_scanning(adapter->dev_id);
-
- DBG("hci%u restarting scanning connect_list_len %u",
- adapter->dev_id, connect_list_len);
- return;
- }
}
static void suspend_discovery(struct btd_adapter *adapter)
if (adapter->waiting_to_connect == 0 &&
g_slist_length(adapter->connect_list) > 0)
- mgmt_start_le_scanning(adapter->dev_id);
+ adapter->discov_id = g_idle_add(discovery_cb, adapter);
btd_device_unref(device);