adapter: Handle controller resume and notify drivers
authorAbhishek Pandit-Subedi <abhishekpandit@chromium.org>
Fri, 11 Sep 2020 22:30:35 +0000 (15:30 -0700)
committerAyush Garg <ayush.garg@samsung.com>
Fri, 11 Mar 2022 13:38:32 +0000 (19:08 +0530)
Register for controller resume notification and notify the adapter
drivers when it occurs. Also adds the resume event kernel feature to
make sure the kernel supports this event.

Signed-off-by: Anuj Jain <anuj01.jain@samsung.com>
Signed-off-by: Ayush Garg <ayush.garg@samsung.com>
src/adapter.c
src/adapter.h

index d56929d..a681742 100644 (file)
@@ -14786,6 +14786,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)
 {
@@ -15724,6 +15751,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);
+
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
        mgmt_register(adapter->mgmt, MGMT_EV_RSSI_ALERT,
                                                adapter->dev_id,
@@ -16008,6 +16040,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,
index bdb8bb0..31c87b0 100644 (file)
@@ -196,6 +196,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);
@@ -334,6 +335,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);