Diff between e14f645912bb391c575fe76131fe5d392c132161 and 9bf6b051b520bd88473da4bbf7b84c92f994a2c0

Changed Files

File Additions Deletions Status
src/adapter.c +43 -0 modified
src/adapter.h +2 -0 modified

Full Patch

diff --git a/src/adapter.c b/src/adapter.c
index 422f89f..ce929ff 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -8794,6 +8794,33 @@ static void connected_callback(uint16_t index, uint16_t length,
 	eir_data_free(&eir_data);
 }
 
+static void controller_resume_notify(struct btd_adapter *adapter)
+{
+	GSList *l;
+
+	for (l = adapter->drivers; l; l = g_slist_next(l)) {
+		struct btd_adapter_driver *driver = l->data;
+		if (driver->resume)
+			driver->resume(adapter);
+	}
+}
+
+static void controller_resume_callback(uint16_t index, uint16_t length,
+				       const void *param, void *user_data)
+{
+	const struct mgmt_ev_controller_resume *ev = param;
+	struct btd_adapter *adapter = user_data;
+
+	if (length < sizeof(*ev)) {
+		btd_error(adapter->dev_id, "Too small device resume event");
+		return;
+	}
+
+	info("Controller resume with wake event 0x%x", ev->wake_reason);
+
+	controller_resume_notify(adapter);
+}
+
 static void device_blocked_callback(uint16_t index, uint16_t length,
 					const void *param, void *user_data)
 {
@@ -9417,6 +9444,11 @@ static void read_info_complete(uint8_t status, uint16_t length,
 						user_passkey_notify_callback,
 						adapter, NULL);
 
+	mgmt_register(adapter->mgmt, MGMT_EV_CONTROLLER_RESUME,
+						adapter->dev_id,
+						controller_resume_callback,
+						adapter, NULL);
+
 	set_dev_class(adapter);
 
 	set_name(adapter, btd_adapter_get_name(adapter));
@@ -9627,6 +9659,17 @@ static void read_commands_complete(uint8_t status, uint16_t length,
 			break;
 		}
 	}
+
+	for (i = 0; i < num_events; i++) {
+		uint16_t ev = get_le16(rp->opcodes + num_commands + i);
+
+		switch(ev) {
+		case MGMT_EV_CONTROLLER_RESUME:
+			DBG("kernel supports suspend/resume events");
+			kernel_features |= KERNEL_HAS_RESUME_EVT;
+			break;
+		}
+	}
 }
 
 static void read_version_complete(uint8_t status, uint16_t length,
diff --git a/src/adapter.h b/src/adapter.h
index 5982460..960a00c 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -116,6 +116,7 @@ struct btd_adapter_driver {
 	const char *name;
 	int (*probe) (struct btd_adapter *adapter);
 	void (*remove) (struct btd_adapter *adapter);
+	void (*resume) (struct btd_adapter *adapter);
 };
 
 typedef void (*service_auth_cb) (DBusError *derr, void *user_data);
@@ -242,6 +243,7 @@ enum kernel_features {
 	KERNEL_BLOCKED_KEYS_SUPPORTED	= 1 << 1,
 	KERNEL_SET_SYSTEM_CONFIG	= 1 << 2,
 	KERNEL_EXP_FEATURES		= 1 << 3,
+	KERNEL_HAS_RESUME_EVT		= 1 << 4,
 };
 
 bool has_kernel_features(uint32_t feature);