Diff between f6fe4992a094f7765d58fb2b6ccb8d8530e2d3be and 67666f295a07af3b1531eca42990fee3cb760ded

Changed Files

File Additions Deletions Status
src/adapter.c +86 -0 modified
src/adapter.h +4 -0 modified
src/device.c +7 -1 modified

Full Patch

diff --git a/src/adapter.c b/src/adapter.c
index 9f063b4..1dae5f8 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3239,6 +3239,92 @@ void adapter_connect_list_remove(struct btd_adapter *adapter,
 	trigger_passive_scanning(adapter);
 }
 
+static void add_whitelist_complete(uint8_t status, uint16_t length,
+					const void *param, void *user_data)
+{
+	const struct mgmt_rp_add_device *rp = param;
+	struct btd_adapter *adapter = user_data;
+	struct btd_device *dev;
+	char addr[18];
+
+	if (length < sizeof(*rp)) {
+		error("Too small Add Device complete event");
+		return;
+	}
+
+	ba2str(&rp->addr.bdaddr, addr);
+
+	dev = btd_adapter_find_device(adapter, &rp->addr.bdaddr,
+							rp->addr.type);
+	if (!dev) {
+		error("Add Device complete for unknown device %s", addr);
+		return;
+	}
+
+	if (status != MGMT_STATUS_SUCCESS) {
+		error("Failed to add device %s: %s (0x%02x)",
+					addr, mgmt_errstr(status), status);
+		return;
+	}
+
+	DBG("%s added to kernel whitelist", addr);
+}
+
+void adapter_whitelist_add(struct btd_adapter *adapter, struct btd_device *dev)
+{
+	struct mgmt_cp_add_device cp;
+
+	if (!kernel_conn_control)
+		return;
+
+	memset(&cp, 0, sizeof(cp));
+	bacpy(&cp.addr.bdaddr, device_get_address(dev));
+	cp.addr.type = BDADDR_BREDR;
+	cp.action = 0x01;
+
+	mgmt_send(adapter->mgmt, MGMT_OP_ADD_DEVICE,
+				adapter->dev_id, sizeof(cp), &cp,
+				add_whitelist_complete, adapter, NULL);
+}
+
+static void remove_whitelist_complete(uint8_t status, uint16_t length,
+					const void *param, void *user_data)
+{
+	const struct mgmt_rp_remove_device *rp = param;
+	char addr[18];
+
+	if (length < sizeof(*rp)) {
+		error("Too small Remove Device complete event");
+		return;
+	}
+
+	ba2str(&rp->addr.bdaddr, addr);
+
+	if (status != MGMT_STATUS_SUCCESS) {
+		error("Failed to remove device %s: %s (0x%02x)",
+					addr, mgmt_errstr(status), status);
+		return;
+	}
+
+	DBG("%s removed from kernel whitelist", addr);
+}
+
+void adapter_whitelist_remove(struct btd_adapter *adapter, struct btd_device *dev)
+{
+	struct mgmt_cp_remove_device cp;
+
+	if (!kernel_conn_control)
+		return;
+
+	memset(&cp, 0, sizeof(cp));
+	bacpy(&cp.addr.bdaddr, device_get_address(dev));
+	cp.addr.type = BDADDR_BREDR;
+
+	mgmt_send(adapter->mgmt, MGMT_OP_REMOVE_DEVICE,
+				adapter->dev_id, sizeof(cp), &cp,
+				remove_whitelist_complete, adapter, NULL);
+}
+
 static void add_device_complete(uint8_t status, uint16_t length,
 					const void *param, void *user_data)
 {
diff --git a/src/adapter.h b/src/adapter.h
index a214cf9..6801fee 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -203,6 +203,10 @@ void adapter_auto_connect_add(struct btd_adapter *adapter,
 					struct btd_device *device);
 void adapter_auto_connect_remove(struct btd_adapter *adapter,
 					struct btd_device *device);
+void adapter_whitelist_add(struct btd_adapter *adapter,
+						struct btd_device *dev);
+void adapter_whitelist_remove(struct btd_adapter *adapter,
+						struct btd_device *dev);
 
 void btd_adapter_set_oob_handler(struct btd_adapter *adapter,
 						struct oob_handler *handler);
diff --git a/src/device.c b/src/device.c
index 23b0c08..397233b 100644
--- a/src/device.c
+++ b/src/device.c
@@ -4006,8 +4006,14 @@ void btd_device_set_temporary(struct btd_device *device, gboolean temporary)
 
 	DBG("temporary %d", temporary);
 
-	if (temporary)
+	if (temporary) {
+		if (device->bredr)
+			adapter_whitelist_remove(device->adapter, device);
 		adapter_connect_list_remove(device->adapter, device);
+	} else {
+		if (device->bredr)
+			adapter_whitelist_add(device->adapter, device);
+	}
 
 	device->temporary = temporary;
 }