Message ID | 20211117110627.BlueZ.v5.3.I68039747acc3c63f758278452889d6ed2bfff065@changeid (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | [BlueZ,v5,1/6] doc: Introduce the Adv Monitor Device Found/Lost events | expand |
Context | Check | Description |
---|---|---|
tedd_an/checkpatch | success | Checkpatch PASS |
tedd_an/gitlint | success | Gitlint PASS |
Hi Manish, On Wed, Nov 17, 2021 at 11:15 AM Manish Mandlik <mmandlik@google.com> wrote: > > 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> > --- > > Changes in v5: > - Update the Adv Monitor Device Found event to include fields from the > existing Device Found event and update the device object. > - Disable the software based filtering whenever controller offloading is > available. > > Changes in v4: > - Add Advertisement Monitor Device Found event. > > Changes in v3: > - Fix indentation of the adv_monitor_device_lost_callback() name and > it's arguments. > > Changes in v2: > - Update function name adv_monitor_tracking_callback() to > adv_monitor_device_lost_callback() as it will receive only Device Lost > event. > > src/adapter.c | 47 +++++++++++++----------- > src/adapter.h | 8 +++++ > src/adv_monitor.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++ > src/adv_monitor.h | 2 ++ > 4 files changed, 128 insertions(+), 20 deletions(-) > > diff --git a/src/adapter.c b/src/adapter.c > index d0d38621b..42463a3c1 100644 > --- a/src/adapter.c > +++ b/src/adapter.c > @@ -6984,12 +6984,13 @@ static bool device_is_discoverable(struct btd_adapter *adapter, > return discoverable; > } > > -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) > { > struct btd_device *dev; > struct bt_ad *ad = NULL; > @@ -6999,20 +7000,24 @@ static void update_found_devices(struct btd_adapter *adapter, > bool duplicate = false; > struct queue *matched_monitors = NULL; > > - if (bdaddr_type != BDADDR_BREDR) > - ad = bt_ad_new_with_data(data_len, data); > + 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; > + /* 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; > > memset(&eir_data, 0, sizeof(eir_data)); > @@ -7025,7 +7030,7 @@ static void update_found_devices(struct btd_adapter *adapter, > > dev = btd_adapter_find_device(adapter, bdaddr, bdaddr_type); > if (!dev) { > - if (!discoverable && !matched_monitors) { > + if (!discoverable && !monitoring) { > eir_data_free(&eir_data); > return; > } > @@ -7064,7 +7069,7 @@ static void update_found_devices(struct btd_adapter *adapter, > */ > if (!btd_device_is_connected(dev) && > (device_is_temporary(dev) && !adapter->discovery_list) && > - !matched_monitors) { > + !monitoring) { > eir_data_free(&eir_data); > return; > } > @@ -7072,7 +7077,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)))) { > eir_data_free(&eir_data); > @@ -7202,6 +7207,7 @@ static void device_found_callback(uint16_t index, uint16_t length, > bool confirm_name; > bool legacy; > char addr[18]; > + bool not_connectable; > > if (length < sizeof(*ev)) { > btd_error(adapter->dev_id, > @@ -7230,11 +7236,12 @@ 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); > + not_connectable = (flags & MGMT_DEV_FOUND_NOT_CONNECTABLE); > > - update_found_devices(adapter, &ev->addr.bdaddr, ev->addr.type, > - ev->rssi, confirm_name, legacy, > - flags & MGMT_DEV_FOUND_NOT_CONNECTABLE, > - eir, eir_len); > + btd_adapter_update_found_device(adapter, &ev->addr.bdaddr, > + ev->addr.type, ev->rssi, confirm_name, > + legacy, not_connectable, eir, eir_len, > + false); > } > > struct agent *adapter_get_agent(struct btd_adapter *adapter) > diff --git a/src/adapter.h b/src/adapter.h > index db3c17f23..cd0d037af 100644 > --- a/src/adapter.h > +++ b/src/adapter.h > @@ -87,6 +87,14 @@ 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); > > +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); > + > 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); > diff --git a/src/adv_monitor.c b/src/adv_monitor.c > index a3b33188b..e5bdfb6ef 100644 > --- a/src/adv_monitor.c > +++ b/src/adv_monitor.c > @@ -1531,6 +1531,78 @@ 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; > + uint16_t handle = le16_to_cpu(ev->monitor_handle); Make sure each patch don't break the build: src/adv_monitor.c: In function ‘adv_monitor_device_found_callback’: src/adv_monitor.c:1541:18: error: unused variable ‘handle’ [-Werror=unused-variable] 1541 | uint16_t handle = le16_to_cpu(ev->monitor_handle); | > + 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, > @@ -1555,6 +1627,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; > } > > @@ -1666,6 +1746,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) > { > diff --git a/src/adv_monitor.h b/src/adv_monitor.h > index d9cb9ccbb..bed6572d0 100644 > --- a/src/adv_monitor.h > +++ b/src/adv_monitor.h > @@ -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); > -- > 2.34.0.rc1.387.gb447b232ab-goog >
diff --git a/src/adapter.c b/src/adapter.c index d0d38621b..42463a3c1 100644 --- a/src/adapter.c +++ b/src/adapter.c @@ -6984,12 +6984,13 @@ static bool device_is_discoverable(struct btd_adapter *adapter, return discoverable; } -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) { struct btd_device *dev; struct bt_ad *ad = NULL; @@ -6999,20 +7000,24 @@ static void update_found_devices(struct btd_adapter *adapter, bool duplicate = false; struct queue *matched_monitors = NULL; - if (bdaddr_type != BDADDR_BREDR) - ad = bt_ad_new_with_data(data_len, data); + 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; + /* 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; memset(&eir_data, 0, sizeof(eir_data)); @@ -7025,7 +7030,7 @@ static void update_found_devices(struct btd_adapter *adapter, dev = btd_adapter_find_device(adapter, bdaddr, bdaddr_type); if (!dev) { - if (!discoverable && !matched_monitors) { + if (!discoverable && !monitoring) { eir_data_free(&eir_data); return; } @@ -7064,7 +7069,7 @@ static void update_found_devices(struct btd_adapter *adapter, */ if (!btd_device_is_connected(dev) && (device_is_temporary(dev) && !adapter->discovery_list) && - !matched_monitors) { + !monitoring) { eir_data_free(&eir_data); return; } @@ -7072,7 +7077,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)))) { eir_data_free(&eir_data); @@ -7202,6 +7207,7 @@ static void device_found_callback(uint16_t index, uint16_t length, bool confirm_name; bool legacy; char addr[18]; + bool not_connectable; if (length < sizeof(*ev)) { btd_error(adapter->dev_id, @@ -7230,11 +7236,12 @@ 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); + not_connectable = (flags & MGMT_DEV_FOUND_NOT_CONNECTABLE); - update_found_devices(adapter, &ev->addr.bdaddr, ev->addr.type, - ev->rssi, confirm_name, legacy, - flags & MGMT_DEV_FOUND_NOT_CONNECTABLE, - eir, eir_len); + btd_adapter_update_found_device(adapter, &ev->addr.bdaddr, + ev->addr.type, ev->rssi, confirm_name, + legacy, not_connectable, eir, eir_len, + false); } struct agent *adapter_get_agent(struct btd_adapter *adapter) diff --git a/src/adapter.h b/src/adapter.h index db3c17f23..cd0d037af 100644 --- a/src/adapter.h +++ b/src/adapter.h @@ -87,6 +87,14 @@ 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); +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); + 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); diff --git a/src/adv_monitor.c b/src/adv_monitor.c index a3b33188b..e5bdfb6ef 100644 --- a/src/adv_monitor.c +++ b/src/adv_monitor.c @@ -1531,6 +1531,78 @@ 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; + uint16_t handle = le16_to_cpu(ev->monitor_handle); + 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, @@ -1555,6 +1627,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; } @@ -1666,6 +1746,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) { diff --git a/src/adv_monitor.h b/src/adv_monitor.h index d9cb9ccbb..bed6572d0 100644 --- a/src/adv_monitor.h +++ b/src/adv_monitor.h @@ -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);
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> --- Changes in v5: - Update the Adv Monitor Device Found event to include fields from the existing Device Found event and update the device object. - Disable the software based filtering whenever controller offloading is available. Changes in v4: - Add Advertisement Monitor Device Found event. Changes in v3: - Fix indentation of the adv_monitor_device_lost_callback() name and it's arguments. Changes in v2: - Update function name adv_monitor_tracking_callback() to adv_monitor_device_lost_callback() as it will receive only Device Lost event. src/adapter.c | 47 +++++++++++++----------- src/adapter.h | 8 +++++ src/adv_monitor.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++ src/adv_monitor.h | 2 ++ 4 files changed, 128 insertions(+), 20 deletions(-)