adv_monitor: Receive the Device Found/Lost events
authorManish Mandlik <mmandlik@google.com>
Sat, 20 Nov 2021 15:29:38 +0000 (07:29 -0800)
committerAyush Garg <ayush.garg@samsung.com>
Fri, 11 Mar 2022 13:38:38 +0000 (19:08 +0530)
This patch registers callback functions to receive the Advertisement
Monitor Device Found and Device Lost events. It also disables software
based filtering whenever controller offloading support is available.

Test performed:
- Verified by logs that the MSFT Monitor Device is received from the
  controller and the bluetoothd is notified whenever the controller
  starts/stops monitoring a device.

Reviewed-by: Miao-chen Chou <mcchou@google.com>
Signed-off-by: Anuj Jain <anuj01.jain@samsung.com>
Signed-off-by: Ayush Garg <ayush.garg@samsung.com>
src/adapter.c
src/adapter.h
src/adv_monitor.c
src/adv_monitor.h

index 2e54edb..227595d 100644 (file)
@@ -12084,18 +12084,20 @@ static bool device_is_discoverable(struct btd_adapter *adapter,
 #endif
 
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
-static void update_found_devices(struct btd_adapter *adapter,
+void btd_adapter_update_found_device(struct btd_adapter *adapter,
                                        const bdaddr_t *bdaddr,
                                        uint8_t bdaddr_type, int8_t rssi,
                                        bool confirm, bool legacy, uint8_t adv_type,
-                                       const uint8_t *data, uint8_t data_len)
+                                       const uint8_t *data, uint8_t data_len,
+                                       bool monitoring)
 #else
-static void update_found_devices(struct btd_adapter *adapter,
+void btd_adapter_update_found_device(struct btd_adapter *adapter,
                                        const bdaddr_t *bdaddr,
                                        uint8_t bdaddr_type, int8_t rssi,
                                        bool confirm, bool legacy,
                                        bool not_connectable,
-                                       const uint8_t *data, uint8_t data_len)
+                                       const uint8_t *data, uint8_t data_len,
+                                       bool monitoring)
 #endif
 {
        struct btd_device *dev;
@@ -12116,20 +12118,24 @@ static void update_found_devices(struct btd_adapter *adapter,
 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
        struct queue *matched_monitors = NULL;
 
-       if (bdaddr_type != BDADDR_BREDR)
-               ad = bt_ad_new_with_data(data_len, data);
-
-       /* During the background scanning, update the device only when the data
-        * match at least one Adv monitor
-        */
-       if (ad) {
-               matched_monitors = btd_adv_monitor_content_filter(
-                                       adapter->adv_monitor_manager, ad);
-               bt_ad_unref(ad);
-               ad = NULL;
+       if (!btd_adv_monitor_offload_supported(adapter->adv_monitor_manager)) {
+               if (bdaddr_type != BDADDR_BREDR)
+                       ad = bt_ad_new_with_data(data_len, data);
+
+               /* During the background scanning, update the device only when
+               * the data match at least one Adv monitor
+               */
+               if (ad) {
+                       matched_monitors = btd_adv_monitor_content_filter(
+                                               adapter->adv_monitor_manager,
+                                               ad);
+                       bt_ad_unref(ad);
+                       ad = NULL;
+                       monitoring = matched_monitors ? true : false;
+               }
        }
 
-       if (!adapter->discovering && !matched_monitors)
+       if (!adapter->discovering && !monitoring)
                return;
 #endif
        memset(&eir_data, 0, sizeof(eir_data));
@@ -12233,7 +12239,7 @@ static void update_found_devices(struct btd_adapter *adapter,
 #else
        if (!btd_device_is_connected(dev) &&
                (device_is_temporary(dev) && !adapter->discovery_list) &&
-               !matched_monitors) {
+               !monitoring) {
                eir_data_free(&eir_data);
                return;
        }
@@ -12247,7 +12253,7 @@ static void update_found_devices(struct btd_adapter *adapter,
        /* If there is no matched Adv monitors, don't continue if not
         * discoverable or if active discovery filter don't match.
         */
-       if (!matched_monitors && (!discoverable ||
+       if (!monitoring && (!discoverable ||
                (adapter->filtered_discovery && !is_filter_match(
                                adapter->discovery_list, &eir_data, rssi)))) {
 #endif
@@ -12414,7 +12420,9 @@ static void device_found_callback(uint16_t index, uint16_t length,
        bool confirm_name;
        bool legacy;
        char addr[18];
-
+#ifndef TIZEN_FEATURE_BLUEZ_MODIFY
+       bool not_connectable;
+#endif
        if (length < sizeof(*ev)) {
                btd_error(adapter->dev_id,
                        "Too short device found event (%u bytes)", length);
@@ -12442,16 +12450,18 @@ static void device_found_callback(uint16_t index, uint16_t length,
 
        confirm_name = (flags & MGMT_DEV_FOUND_CONFIRM_NAME);
        legacy = (flags & MGMT_DEV_FOUND_LEGACY_PAIRING);
-
+#ifndef TIZEN_FEATURE_BLUEZ_MODIFY
+       not_connectable = (flags & MGMT_DEV_FOUND_NOT_CONNECTABLE);
+#endif
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
-       update_found_devices(adapter, &ev->addr.bdaddr, ev->addr.type,
+       btd_adapter_update_found_device(adapter, &ev->addr.bdaddr, ev->addr.type,
                                        ev->rssi, confirm_name, legacy, 0,
-                                       eir, eir_len);
+                                       eir, eir_len, false);
 #else
-       update_found_devices(adapter, &ev->addr.bdaddr, ev->addr.type,
+       btd_adapter_update_found_device(adapter, &ev->addr.bdaddr, ev->addr.type,
                                        ev->rssi, confirm_name, legacy,
-                                       flags & MGMT_DEV_FOUND_NOT_CONNECTABLE,
-                                       eir, eir_len);
+                                       not_connectable,
+                                       eir, eir_len, false);
 #endif
 }
 
@@ -12497,9 +12507,9 @@ static void le_device_found_callback(uint16_t index, uint16_t length,
        /*DBG("hci%u addr %s, addr_type %d rssi %d flags 0x%04x eir_len %u confirm_name %d legacy %d, adv_type %02x",
                        index, addr, ev->addr.type, ev->rssi, flags, eir_len, confirm_name, legacy, ev->adv_type);*/
 
-       update_found_devices(adapter, &ev->addr.bdaddr, ev->addr.type,
+       btd_adapter_update_found_device(adapter, &ev->addr.bdaddr, ev->addr.type,
                                        ev->rssi, confirm_name, legacy, ev->adv_type,
-                                       eir, eir_len);
+                                       eir, eir_len, false);
 }
 #endif
 
index d085a22..cdd334d 100644 (file)
@@ -163,6 +163,22 @@ struct btd_device *btd_adapter_find_device(struct btd_adapter *adapter,
 struct btd_device *btd_adapter_find_device_by_path(struct btd_adapter *adapter,
                                                   const char *path);
 
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+void btd_adapter_update_found_device(struct btd_adapter *adapter,
+                                       const bdaddr_t *bdaddr,
+                                       uint8_t bdaddr_type, int8_t rssi,
+                                       bool confirm, bool legacy, uint8_t adv_type,
+                                       const uint8_t *data, uint8_t data_len,
+                                       bool monitoring);
+#else
+void btd_adapter_update_found_device(struct btd_adapter *adapter,
+                                       const bdaddr_t *bdaddr,
+                                       uint8_t bdaddr_type, int8_t rssi,
+                                       bool confirm, bool legacy,
+                                       bool not_connectable,
+                                       const uint8_t *data, uint8_t data_len,
+                                       bool monitored);
+#endif
 const char *adapter_get_path(struct btd_adapter *adapter);
 const bdaddr_t *btd_adapter_get_address(struct btd_adapter *adapter);
 uint8_t btd_adapter_get_address_type(struct btd_adapter *adapter);
index 925992d..f896604 100644 (file)
@@ -1530,6 +1530,77 @@ static void adv_monitor_removed_callback(uint16_t index, uint16_t length,
                ev->monitor_handle);
 }
 
+/* Processes Adv Monitor Device Found event from kernel */
+static void adv_monitor_device_found_callback(uint16_t index, uint16_t length,
+                                               const void *param,
+                                               void *user_data)
+{
+       const struct mgmt_ev_adv_monitor_device_found *ev = param;
+       struct btd_adv_monitor_manager *manager = user_data;
+       const uint16_t adapter_id = manager->adapter_id;
+       struct btd_adapter *adapter = manager->adapter;
+       const uint8_t *ad_data = NULL;
+       uint16_t ad_data_len;
+       uint32_t flags;
+       bool confirm_name;
+       bool legacy;
+       char addr[18];
+       bool not_connectable;
+
+       if (length < sizeof(*ev)) {
+               btd_error(adapter_id,
+                               "Too short Adv Monitor Device Found event");
+               return;
+       }
+
+       ad_data_len = btohs(ev->ad_data_len);
+       if (length != sizeof(*ev) + ad_data_len) {
+               btd_error(adapter_id,
+                               "Wrong size of Adv Monitor Device Found event");
+               return;
+       }
+
+       if (ad_data_len > 0)
+               ad_data = ev->ad_data;
+
+       flags = btohl(ev->flags);
+
+       ba2str(&ev->addr.bdaddr, addr);
+       DBG("hci%u addr %s, rssi %d flags 0x%04x ad_data_len %u",
+                       index, addr, ev->rssi, flags, ad_data_len);
+
+       confirm_name = (flags & MGMT_DEV_FOUND_CONFIRM_NAME);
+       legacy = (flags & MGMT_DEV_FOUND_LEGACY_PAIRING);
+       not_connectable = (flags & MGMT_DEV_FOUND_NOT_CONNECTABLE);
+
+       btd_adapter_update_found_device(adapter, &ev->addr.bdaddr,
+                                       ev->addr.type, ev->rssi, confirm_name,
+                                       legacy, not_connectable, ad_data,
+                                       ad_data_len, true);
+}
+
+/* Processes Adv Monitor Device Lost event from kernel */
+static void adv_monitor_device_lost_callback(uint16_t index, uint16_t length,
+                                               const void *param,
+                                               void *user_data)
+{
+       struct btd_adv_monitor_manager *manager = user_data;
+       const struct mgmt_ev_adv_monitor_device_lost *ev = param;
+       uint16_t handle = le16_to_cpu(ev->monitor_handle);
+       const uint16_t adapter_id = manager->adapter_id;
+       char addr[18];
+
+       if (length < sizeof(*ev)) {
+               btd_error(adapter_id,
+                               "Wrong size of Adv Monitor Device Lost event");
+               return;
+       }
+
+       ba2str(&ev->addr.bdaddr, addr);
+       DBG("Adv Monitor with handle 0x%04x stopped tracking the device %s",
+               handle, addr);
+}
+
 /* Allocates a manager object */
 static struct btd_adv_monitor_manager *manager_new(
                                                struct btd_adapter *adapter,
@@ -1554,6 +1625,14 @@ static struct btd_adv_monitor_manager *manager_new(
                        manager->adapter_id, adv_monitor_removed_callback,
                        manager, NULL);
 
+       mgmt_register(manager->mgmt, MGMT_EV_ADV_MONITOR_DEVICE_FOUND,
+                       manager->adapter_id, adv_monitor_device_found_callback,
+                       manager, NULL);
+
+       mgmt_register(manager->mgmt, MGMT_EV_ADV_MONITOR_DEVICE_LOST,
+                       manager->adapter_id, adv_monitor_device_lost_callback,
+                       manager, NULL);
+
        return manager;
 }
 
@@ -1665,6 +1744,17 @@ void btd_adv_monitor_manager_destroy(struct btd_adv_monitor_manager *manager)
        manager_destroy(manager);
 }
 
+bool btd_adv_monitor_offload_supported(struct btd_adv_monitor_manager *manager)
+{
+       if (!manager) {
+               error("Manager is NULL, get offload support failed");
+               return false;
+       }
+
+       return !!(manager->enabled_features &
+                               MGMT_ADV_MONITOR_FEATURE_MASK_OR_PATTERNS);
+}
+
 /* Processes the content matching based pattern(s) of a monitor */
 static void adv_match_per_monitor(void *data, void *user_data)
 {
index d9cb9cc..bed6572 100644 (file)
@@ -27,6 +27,8 @@ struct btd_adv_monitor_manager *btd_adv_monitor_manager_create(
                                                struct mgmt *mgmt);
 void btd_adv_monitor_manager_destroy(struct btd_adv_monitor_manager *manager);
 
+bool btd_adv_monitor_offload_supported(struct btd_adv_monitor_manager *manager);
+
 struct queue *btd_adv_monitor_content_filter(
                                struct btd_adv_monitor_manager *manager,
                                struct bt_ad *ad);