Diff between 4a6389350fbfb5dd6298ea8e4eb9735523bb43b6 and 7497ef07ba719ee1037cb3d3dc9e9b165baae1dd

Changed Files

File Additions Deletions Status
src/adapter.c +30 -9 modified
src/adapter.h +2 -1 modified
src/manager.c +4 -2 modified
src/manager.h +3 -1 modified
src/mgmt.c +4 -1 modified

Full Patch

diff --git a/src/adapter.c b/src/adapter.c
index 0e97e57..55f03a4 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -145,6 +145,7 @@ struct btd_adapter {
 	sdp_list_t *services;		/* Services associated to adapter */
 
 	bool connectable;		/* connectable state */
+	bool toggle_discoverable;	/* discoverable needs to be changed */
 	gboolean discoverable;		/* discoverable state */
 	gboolean pairable;		/* pairable state */
 	gboolean initialized;
@@ -2563,6 +2564,7 @@ static void load_config(struct btd_adapter *adapter)
 	char filename[PATH_MAX + 1];
 	char address[18];
 	GError *gerr = NULL;
+	gboolean stored_discoverable;
 
 	ba2str(&adapter->bdaddr, address);
 
@@ -2600,10 +2602,10 @@ static void load_config(struct btd_adapter *adapter)
 	}
 
 	/* Get discoverable mode */
-	adapter->discoverable = g_key_file_get_boolean(key_file, "General",
+	stored_discoverable = g_key_file_get_boolean(key_file, "General",
 							"Discoverable", &gerr);
 	if (gerr) {
-		adapter->discoverable = FALSE;
+		stored_discoverable = FALSE;
 		g_error_free(gerr);
 		gerr = NULL;
 	}
@@ -2617,23 +2619,34 @@ static void load_config(struct btd_adapter *adapter)
 		gerr = NULL;
 	}
 
-	mgmt_set_connectable(adapter->dev_id, TRUE);
+	if (!adapter->connectable)
+		mgmt_set_connectable(adapter->dev_id, TRUE);
 
-	if (adapter->discov_timeout > 0) {
-		/* Ensure that discoverable mode is off */
-		mgmt_set_discoverable(adapter->dev_id, FALSE, 0);
-	} else
-		mgmt_set_discoverable(adapter->dev_id, adapter->discoverable,
+	if (adapter->discov_timeout > 0 && adapter->discoverable) {
+		if (adapter->connectable)
+			mgmt_set_discoverable(adapter->dev_id, FALSE, 0);
+		else
+			adapter->toggle_discoverable = true;
+	} else if (stored_discoverable != adapter->discoverable) {
+		if (adapter->connectable)
+			mgmt_set_discoverable(adapter->dev_id,
+						adapter->discoverable,
 						adapter->discov_timeout);
+		else
+			adapter->toggle_discoverable = true;
+	}
 
 	g_key_file_free(key_file);
 }
 
-gboolean adapter_init(struct btd_adapter *adapter, gboolean powered)
+gboolean adapter_init(struct btd_adapter *adapter, gboolean powered,
+					bool connectable, bool discoverable)
 {
 	struct agent *agent;
 
 	adapter->powered = powered;
+	adapter->connectable = connectable;
+	adapter->discoverable = discoverable;
 
 	adapter->allow_name_changes = TRUE;
 
@@ -2964,6 +2977,14 @@ void adapter_update_connectable(struct btd_adapter *adapter, bool connectable)
 	if (adapter->connectable == connectable)
 		return;
 
+	if (adapter->toggle_discoverable) {
+		DBG("toggling discoverable from %u to %u",
+				adapter->discoverable, !adapter->discoverable);
+		mgmt_set_discoverable(adapter->dev_id, !adapter->discoverable,
+						adapter->discov_timeout);
+		adapter->toggle_discoverable = false;
+	}
+
 	adapter->connectable = connectable;
 	g_dbus_emit_property_changed(conn, adapter->path, ADAPTER_INTERFACE,
 								"Connectable");
diff --git a/src/adapter.h b/src/adapter.h
index 89910cc..d35b8db 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -93,7 +93,8 @@ void adapter_remove_device(struct btd_adapter *adapter,
 						gboolean remove_storage);
 
 struct btd_adapter *adapter_create(int id);
-gboolean adapter_init(struct btd_adapter *adapter, gboolean powered);
+gboolean adapter_init(struct btd_adapter *adapter, gboolean powered,
+					bool connectable, bool discoverable);
 void adapter_remove(struct btd_adapter *adapter);
 void adapter_set_allow_name_changes(struct btd_adapter *adapter,
 						gboolean allow_name_changes);
diff --git a/src/manager.c b/src/manager.c
index 8b55711..1b83114 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -156,7 +156,9 @@ GSList *manager_get_adapters(void)
 	return adapters;
 }
 
-struct btd_adapter *btd_manager_register_adapter(int id, gboolean powered)
+struct btd_adapter *btd_manager_register_adapter(int id, gboolean powered,
+							bool connectable,
+							bool discoverable)
 {
 	struct btd_adapter *adapter;
 	const char *path;
@@ -173,7 +175,7 @@ struct btd_adapter *btd_manager_register_adapter(int id, gboolean powered)
 
 	adapters = g_slist_append(adapters, adapter);
 
-	if (!adapter_init(adapter, powered)) {
+	if (!adapter_init(adapter, powered, connectable, discoverable)) {
 		adapters = g_slist_remove(adapters, adapter);
 		btd_adapter_unref(adapter);
 		return NULL;
diff --git a/src/manager.h b/src/manager.h
index a2b8c31..7311ce3 100644
--- a/src/manager.h
+++ b/src/manager.h
@@ -35,5 +35,7 @@ struct btd_adapter *manager_find_adapter_by_id(int id);
 struct btd_adapter *manager_get_default_adapter(void);
 void manager_foreach_adapter(adapter_cb func, gpointer user_data);
 GSList *manager_get_adapters(void);
-struct btd_adapter *btd_manager_register_adapter(int id, gboolean powered);
+struct btd_adapter *btd_manager_register_adapter(int id, gboolean powered,
+							bool connectable,
+							bool discoverable);
 int btd_manager_unregister_adapter(int id);
diff --git a/src/mgmt.c b/src/mgmt.c
index 798435f..03ec049 100644
--- a/src/mgmt.c
+++ b/src/mgmt.c
@@ -1201,7 +1201,10 @@ static void read_info_complete(int sk, uint16_t index, void *buf, size_t len)
 	clear_uuids(index);
 
 	adapter = btd_manager_register_adapter(index,
-					mgmt_powered(info->current_settings));
+				mgmt_powered(info->current_settings),
+				mgmt_connectable(info->current_settings),
+				mgmt_discoverable(info->current_settings));
+
 	if (adapter == NULL) {
 		error("mgmt: unable to register adapter");
 		return;