1 // SPDX-License-Identifier: LGPL-2.1-or-later
4 * BlueZ - Bluetooth protocol stack for Linux
6 * Copyright (C) 2020 Google LLC
20 #include <dbus/dbus.h>
21 #include <gdbus/gdbus.h>
23 #include "lib/bluetooth.h"
28 #include "dbus-common.h"
31 #include "src/error.h"
32 #include "src/shared/mgmt.h"
33 #include "src/shared/queue.h"
34 #include "src/shared/timeout.h"
35 #include "src/shared/util.h"
37 #include "adv_monitor.h"
39 #define ADV_MONITOR_INTERFACE "org.bluez.AdvertisementMonitor1"
40 #define ADV_MONITOR_MGR_INTERFACE "org.bluez.AdvertisementMonitorManager1"
42 #define ADV_MONITOR_UNSET_RSSI 127 /* dBm */
43 #define ADV_MONITOR_MAX_RSSI 20 /* dBm */
44 #define ADV_MONITOR_MIN_RSSI -127 /* dBm */
45 #define ADV_MONITOR_UNSET_TIMEOUT 0 /* second */
46 #define ADV_MONITOR_MIN_TIMEOUT 1 /* second */
47 #define ADV_MONITOR_MAX_TIMEOUT 300 /* second */
48 #define ADV_MONITOR_DEFAULT_LOW_TIMEOUT 5 /* second */
49 #define ADV_MONITOR_DEFAULT_HIGH_TIMEOUT 10 /* second */
50 #define ADV_MONITOR_UNSET_SAMPLING_PERIOD 256 /* 100 ms */
51 #define ADV_MONITOR_MAX_SAMPLING_PERIOD 255 /* 100 ms */
53 struct btd_adv_monitor_manager {
54 struct btd_adapter *adapter;
58 uint32_t supported_features; /* MGMT_ADV_MONITOR_FEATURE_MASK_* */
59 uint32_t enabled_features; /* MGMT_ADV_MONITOR_FEATURE_MASK_* */
60 uint16_t max_num_monitors;
61 uint8_t max_num_patterns;
63 struct queue *apps; /* apps who registered for Adv monitoring */
64 struct queue *merged_patterns;
67 struct adv_monitor_app {
68 struct btd_adv_monitor_manager *manager;
75 struct queue *monitors;
80 MONITOR_TYPE_OR_PATTERNS,
84 MONITOR_STATE_NEW, /* New but not yet init'ed with actual values */
85 MONITOR_STATE_FAILED, /* Failed to be init'ed */
86 MONITOR_STATE_INITED, /* Init'ed but not yet sent to kernel */
87 MONITOR_STATE_ACTIVE, /* Accepted by kernel */
88 MONITOR_STATE_REMOVED, /* Removed from kernel */
89 MONITOR_STATE_RELEASED, /* Dbus Object removed by app */
92 enum merged_pattern_state {
93 MERGED_PATTERN_STATE_ADDING, /* Adding pattern to kernel */
94 MERGED_PATTERN_STATE_REMOVING, /* Removing pattern from kernel */
95 MERGED_PATTERN_STATE_STABLE, /* Idle */
98 struct rssi_parameters {
99 int8_t high_rssi; /* High RSSI threshold */
100 uint16_t high_rssi_timeout; /* High RSSI threshold timeout */
101 int8_t low_rssi; /* Low RSSI threshold */
102 uint16_t low_rssi_timeout; /* Low RSSI threshold timeout */
103 uint16_t sampling_period; /* Merge packets in the same timeslot.
104 * Currenly unimplemented in user space.
105 * Used only to pass data to kernel.
110 struct adv_monitor_app *app;
114 enum monitor_state state; /* MONITOR_STATE_* */
116 struct rssi_parameters rssi; /* RSSI parameter for this monitor */
117 struct adv_monitor_merged_pattern *merged_pattern;
119 struct queue *devices; /* List of adv_monitor_device objects */
122 /* Some chipsets doesn't support multiple monitors with the same pattern.
123 * To solve that and to generally ease their task, we merge monitors with the
124 * same pattern, so those monitors will only be sent once to the kernel.
126 struct adv_monitor_merged_pattern {
127 struct btd_adv_monitor_manager *manager;
128 uint16_t monitor_handle; /* Kernel Monitor Handle */
129 struct rssi_parameters rssi; /* Merged RSSI parameter for |monitors|,
130 * this will be sent to the kernel.
132 struct queue *monitors; /* List of adv_monitor objects which
135 enum monitor_type type; /* MONITOR_TYPE_* */
136 struct queue *patterns; /* List of bt_ad_pattern objects */
137 enum merged_pattern_state current_state; /* MERGED_PATTERN_STATE_* */
138 enum merged_pattern_state next_state; /* MERGED_PATTERN_STATE_* */
141 /* Some data like last_seen, timer/timeout values need to be maintained
142 * per device. struct adv_monitor_device maintains such data.
144 struct adv_monitor_device {
145 struct adv_monitor *monitor;
146 struct btd_device *device;
148 time_t high_rssi_first_seen; /* Start time when RSSI climbs above
149 * the high RSSI threshold
151 time_t low_rssi_first_seen; /* Start time when RSSI drops below
152 * the low RSSI threshold
154 time_t last_seen; /* Time when last Adv was received */
155 bool found; /* State of the device - lost/found */
156 unsigned int lost_timer; /* Timer to track if the device goes
157 * offline/out-of-range
161 struct app_match_data {
166 struct adv_content_filter_info {
168 struct queue *matched_monitors; /* List of matched monitors */
171 struct adv_rssi_filter_info {
172 struct btd_device *device;
176 struct monitored_device_info {
177 uint16_t monitor_handle; /* Kernel Monitor Handle */
178 struct btd_device *device;
181 static void monitor_device_free(void *data);
182 static void adv_monitor_filter_rssi(struct adv_monitor *monitor,
183 struct btd_device *device, int8_t rssi);
185 static void merged_pattern_send_add(
186 struct adv_monitor_merged_pattern *merged_pattern);
187 static void merged_pattern_send_remove(
188 struct adv_monitor_merged_pattern *merged_pattern);
190 const struct adv_monitor_type {
191 enum monitor_type type;
193 } supported_types[] = {
194 { MONITOR_TYPE_OR_PATTERNS, "or_patterns" },
198 static void rssi_unset(struct rssi_parameters *rssi)
200 rssi->high_rssi = ADV_MONITOR_UNSET_RSSI;
201 rssi->high_rssi_timeout = ADV_MONITOR_UNSET_TIMEOUT;
202 rssi->low_rssi = ADV_MONITOR_UNSET_RSSI;
203 rssi->low_rssi_timeout = ADV_MONITOR_UNSET_TIMEOUT;
204 rssi->sampling_period = ADV_MONITOR_UNSET_SAMPLING_PERIOD;
207 static bool rssi_is_unset(const struct rssi_parameters *rssi)
209 return rssi->high_rssi == ADV_MONITOR_UNSET_RSSI &&
210 rssi->low_rssi == ADV_MONITOR_UNSET_RSSI &&
211 rssi->high_rssi_timeout == ADV_MONITOR_UNSET_TIMEOUT &&
212 rssi->low_rssi_timeout == ADV_MONITOR_UNSET_TIMEOUT &&
213 rssi->sampling_period == ADV_MONITOR_UNSET_SAMPLING_PERIOD;
216 /* Replies to an app's D-Bus message and unref it */
217 static void app_reply_msg(struct adv_monitor_app *app, DBusMessage *reply)
219 if (!app || !app->reg || !reply)
222 g_dbus_send_message(btd_get_dbus_connection(), reply);
223 dbus_message_unref(app->reg);
227 /* Frees a pattern */
228 static void pattern_free(void *data)
230 struct bt_ad_pattern *pattern = data;
235 static void merged_pattern_free(void *data)
237 struct adv_monitor_merged_pattern *merged_pattern = data;
239 queue_destroy(merged_pattern->patterns, pattern_free);
240 queue_destroy(merged_pattern->monitors, NULL);
242 if (merged_pattern->manager)
243 queue_remove(merged_pattern->manager->merged_patterns,
245 free(merged_pattern);
248 /* Returns the smaller of the two integers |a| and |b| which is not equal to the
249 * |unset| value. If both are unset, return unset.
251 static int get_smaller_not_unset(int a, int b, int unset)
258 return a < b ? a : b;
261 /* Merges two RSSI parameters, return the result. The result is chosen to be
262 * whichever is more lenient of the two inputs, so we can pass that to the
263 * kernel and still do additional filtering in the user space without loss of
264 * information while still receiving benefit from offloading some filtering to
266 * It is allowed for |a|, |b|, and |merged| to point to the same object.
268 static void merge_rssi(const struct rssi_parameters *a,
269 const struct rssi_parameters *b,
270 struct rssi_parameters *merged)
272 /* For low rssi, low_timeout, and high_rssi, choose the minimum of the
273 * two values. Filtering the higher values is done on userspace.
275 merged->low_rssi = get_smaller_not_unset(a->low_rssi, b->low_rssi,
276 ADV_MONITOR_UNSET_RSSI);
277 merged->high_rssi = get_smaller_not_unset(a->high_rssi, b->high_rssi,
278 ADV_MONITOR_UNSET_RSSI);
279 merged->low_rssi_timeout = get_smaller_not_unset(a->low_rssi_timeout,
281 ADV_MONITOR_UNSET_TIMEOUT);
283 /* High timeout doesn't matter for now, it will be zeroed when it is
284 * forwarded to kernel anyway.
286 merged->high_rssi_timeout = 0;
288 /* Sampling period is not implemented yet in userspace. There is no
289 * good value if the two values are different, so just choose 0 for
290 * always reporting, to avoid missing packets.
292 if (a->sampling_period != b->sampling_period)
293 merged->sampling_period = 0;
295 merged->sampling_period = a->sampling_period;
298 /* Two merged_pattern are considered equal if all the following are true:
299 * (1) both has the same monitor_type
300 * (2) both has exactly the same pattern in the same order
301 * Therefore, patterns A+B and B+A are considered different, as well as patterns
302 * A and A+A. This shouldn't cause any issue, but solving this issue is a
303 * potential improvement.
305 static bool merged_pattern_is_equal(const void *data, const void *match_data)
307 const struct adv_monitor_merged_pattern *a = data;
308 const struct adv_monitor_merged_pattern *b = match_data;
309 const struct queue_entry *a_entry, *b_entry;
310 struct bt_ad_pattern *a_data, *b_data;
312 if (a->type != b->type)
315 if (queue_length(a->patterns) != queue_length(b->patterns))
318 a_entry = queue_get_entries(a->patterns);
319 b_entry = queue_get_entries(b->patterns);
322 a_data = a_entry->data;
323 b_data = b_entry->data;
325 if (a_data->type != b_data->type ||
326 a_data->offset != b_data->offset ||
327 a_data->len != b_data->len ||
328 memcmp(a_data->data, b_data->data, a_data->len) != 0)
331 a_entry = a_entry->next;
332 b_entry = b_entry->next;
338 static char *get_merged_pattern_state_name(enum merged_pattern_state state)
341 case MERGED_PATTERN_STATE_ADDING:
343 case MERGED_PATTERN_STATE_REMOVING:
345 case MERGED_PATTERN_STATE_STABLE:
352 /* Adds a new merged pattern */
353 static void merged_pattern_add(
354 struct adv_monitor_merged_pattern *merged_pattern)
356 /* This is only called when no merged_pattern found. Therefore, the
357 * state must be stable.
359 if (merged_pattern->current_state != MERGED_PATTERN_STATE_STABLE) {
360 btd_error(merged_pattern->manager->adapter_id,
361 "Add merged_pattern request when state is not stable");
365 merged_pattern->current_state = MERGED_PATTERN_STATE_ADDING;
366 merged_pattern_send_add(merged_pattern);
368 DBG("Monitor state: %s -> %s",
369 get_merged_pattern_state_name(merged_pattern->current_state),
370 get_merged_pattern_state_name(merged_pattern->next_state));
373 /* Removes merged pattern, or queues for removal if busy */
374 static void merged_pattern_remove(
375 struct adv_monitor_merged_pattern *merged_pattern)
377 rssi_unset(&merged_pattern->rssi);
379 /* If we currently are removing, cancel subsequent ADD command if any */
380 if (merged_pattern->current_state == MERGED_PATTERN_STATE_REMOVING) {
381 merged_pattern->next_state = MERGED_PATTERN_STATE_STABLE;
385 /* If stable, we can proceed with removal right away */
386 if (merged_pattern->current_state == MERGED_PATTERN_STATE_STABLE) {
387 merged_pattern->current_state = MERGED_PATTERN_STATE_REMOVING;
388 merged_pattern_send_remove(merged_pattern);
390 /* otherwise queue the removal */
391 merged_pattern->next_state = MERGED_PATTERN_STATE_REMOVING;
395 DBG("Monitor state: %s -> %s",
396 get_merged_pattern_state_name(merged_pattern->current_state),
397 get_merged_pattern_state_name(merged_pattern->next_state));
400 /* Replaces (removes and re-adds) merged pattern, or queues it if busy */
401 static void merged_pattern_replace(
402 struct adv_monitor_merged_pattern *merged_pattern,
403 const struct rssi_parameters *rssi)
405 /* If the RSSI are the same then nothing needs to be done, except on
406 * the case where pattern is being removed. In that case, we need to
407 * re-add the pattern.
408 * high_rssi_timeout is purposedly left out in the comparison since
409 * the value is ignored upon submission to kernel.
411 if (merged_pattern->rssi.high_rssi == rssi->high_rssi &&
412 merged_pattern->rssi.low_rssi == rssi->low_rssi &&
413 merged_pattern->rssi.low_rssi_timeout == rssi->low_rssi_timeout &&
414 merged_pattern->rssi.sampling_period == rssi->sampling_period &&
415 merged_pattern->current_state != MERGED_PATTERN_STATE_REMOVING &&
416 merged_pattern->next_state != MERGED_PATTERN_STATE_REMOVING)
419 merged_pattern->rssi = *rssi;
421 /* If stable, we can proceed with replacement. */
422 if (merged_pattern->current_state == MERGED_PATTERN_STATE_STABLE) {
423 /* Replacement is done by first removing, then re-adding */
424 merged_pattern->current_state = MERGED_PATTERN_STATE_REMOVING;
425 merged_pattern->next_state = MERGED_PATTERN_STATE_ADDING;
426 merged_pattern_send_remove(merged_pattern);
428 /* otherwise queue the replacement */
429 merged_pattern->next_state = MERGED_PATTERN_STATE_ADDING;
432 DBG("Monitor state: %s -> %s",
433 get_merged_pattern_state_name(merged_pattern->current_state),
434 get_merged_pattern_state_name(merged_pattern->next_state));
437 /* Current_state of merged_pattern is done, proceed to the next_state */
438 static void merged_pattern_process_next_step(
439 struct adv_monitor_merged_pattern *mp)
441 if (mp->current_state == MERGED_PATTERN_STATE_STABLE) {
442 btd_error(mp->manager->adapter_id,
443 "Merged pattern invalid current state");
447 if (mp->current_state == MERGED_PATTERN_STATE_REMOVING) {
448 /* We might need to follow-up with re-adding the pattern */
449 if (mp->next_state == MERGED_PATTERN_STATE_ADDING) {
450 mp->current_state = MERGED_PATTERN_STATE_ADDING;
451 mp->next_state = MERGED_PATTERN_STATE_STABLE;
452 merged_pattern_send_add(mp);
456 /* We should never end up with remove-remove sequence */
457 if (mp->next_state == MERGED_PATTERN_STATE_REMOVING)
458 btd_error(mp->manager->adapter_id,
459 "Merged pattern can't be removed again");
461 /* No more operations */
462 mp->current_state = MERGED_PATTERN_STATE_STABLE;
463 mp->next_state = MERGED_PATTERN_STATE_STABLE;
467 /* current_state == MERGED_PATTERN_STATE_ADDING */
468 if (mp->next_state == MERGED_PATTERN_STATE_REMOVING) {
469 mp->current_state = MERGED_PATTERN_STATE_REMOVING;
470 mp->next_state = MERGED_PATTERN_STATE_STABLE;
471 merged_pattern_send_remove(mp);
473 } else if (mp->next_state == MERGED_PATTERN_STATE_ADDING) {
474 /* To re-add a just added pattern, we need to remove it first */
475 mp->current_state = MERGED_PATTERN_STATE_REMOVING;
476 mp->next_state = MERGED_PATTERN_STATE_ADDING;
477 merged_pattern_send_remove(mp);
481 /* No more operations */
482 mp->current_state = MERGED_PATTERN_STATE_STABLE;
483 mp->next_state = MERGED_PATTERN_STATE_STABLE;
486 DBG("Monitor state: %s -> %s",
487 get_merged_pattern_state_name(mp->current_state),
488 get_merged_pattern_state_name(mp->next_state));
491 /* Frees a monitor object */
492 static void monitor_free(struct adv_monitor *monitor)
494 g_dbus_proxy_unref(monitor->proxy);
495 g_free(monitor->path);
497 queue_destroy(monitor->devices, monitor_device_free);
498 monitor->devices = NULL;
503 /* Calls Release() method of the remote Adv Monitor */
504 static void monitor_release(struct adv_monitor *monitor)
506 /* Release() method on a monitor can be called when -
507 * 1. monitor initialization failed
508 * 2. app calls UnregisterMonitor and monitors held by app are released,
509 * it may or may not be activated at this point
510 * 3. monitor is removed by kernel
512 if (monitor->state != MONITOR_STATE_FAILED &&
513 monitor->state != MONITOR_STATE_INITED &&
514 monitor->state != MONITOR_STATE_ACTIVE &&
515 monitor->state != MONITOR_STATE_REMOVED) {
519 DBG("Calling Release() on Adv Monitor of owner %s at path %s",
520 monitor->app->owner, monitor->path);
522 g_dbus_proxy_method_call(monitor->proxy, "Release", NULL, NULL, NULL,
526 /* Removes monitor from the merged_pattern. This would result in removing it
527 * from the kernel if there is only one such monitor with that pattern.
529 static void monitor_remove(struct adv_monitor *monitor)
531 struct adv_monitor_app *app = monitor->app;
532 uint16_t adapter_id = app->manager->adapter_id;
533 struct adv_monitor_merged_pattern *merged_pattern;
534 const struct queue_entry *e;
535 struct rssi_parameters rssi;
537 /* Monitor from kernel can be removed when -
538 * 1. monitor object is deleted by app - may or may not be activated
539 * 2. app is destroyed and monitors held by app are marked as released
541 if (monitor->state != MONITOR_STATE_INITED &&
542 monitor->state != MONITOR_STATE_ACTIVE &&
543 monitor->state != MONITOR_STATE_RELEASED) {
547 monitor->state = MONITOR_STATE_REMOVED;
549 if (!monitor->merged_pattern) {
550 btd_error(adapter_id,
551 "Merged_pattern not found when removing monitor");
555 merged_pattern = monitor->merged_pattern;
556 monitor->merged_pattern = NULL;
557 queue_remove(merged_pattern->monitors, monitor);
559 /* No more monitors - just remove the pattern entirely */
560 if (queue_length(merged_pattern->monitors) == 0) {
561 merged_pattern_remove(merged_pattern);
565 /* Calculate the merge result of the RSSIs of the monitors with the
566 * same pattern, minus the monitor being removed.
569 for (e = queue_get_entries(merged_pattern->monitors); e; e = e->next) {
570 struct adv_monitor *m = e->data;
572 merge_rssi(&rssi, &m->rssi, &rssi);
575 merged_pattern_replace(merged_pattern, &rssi);
578 /* Destroys monitor object */
579 static void monitor_destroy(void *data)
581 struct adv_monitor *monitor = data;
586 queue_remove(monitor->app->monitors, monitor);
588 monitor_release(monitor);
589 monitor_remove(monitor);
590 monitor_free(monitor);
593 /* Destroys an app object along with related D-Bus handlers */
594 static void app_destroy(void *data)
596 struct adv_monitor_app *app = data;
601 DBG("Destroy Adv Monitor app %s at path %s", app->owner, app->path);
603 queue_destroy(app->monitors, monitor_destroy);
606 app_reply_msg(app, btd_error_failed(app->reg,
607 "Adv Monitor app destroyed"));
611 g_dbus_client_set_disconnect_watch(app->client, NULL, NULL);
612 g_dbus_client_set_proxy_handlers(app->client, NULL, NULL, NULL,
614 g_dbus_client_set_ready_watch(app->client, NULL, NULL);
615 g_dbus_client_unref(app->client);
624 /* Updates monitor state to 'released' */
625 static void monitor_state_released(void *data, void *user_data)
627 struct adv_monitor *monitor = data;
629 if (!monitor || (monitor->state != MONITOR_STATE_INITED
630 && monitor->state != MONITOR_STATE_ACTIVE))
633 monitor->state = MONITOR_STATE_RELEASED;
636 /* Updates monitor state to 'active' */
637 static void monitor_state_active(void *data, void *user_data)
639 struct adv_monitor *monitor = data;
641 if (!monitor || monitor->state != MONITOR_STATE_INITED)
644 monitor->state = MONITOR_STATE_ACTIVE;
646 DBG("Calling Activate() on Adv Monitor of owner %s at path %s",
647 monitor->app->owner, monitor->path);
649 g_dbus_proxy_method_call(monitor->proxy, "Activate", NULL,
653 /* Handles a D-Bus disconnection event of an app */
654 static void app_disconnect_cb(DBusConnection *conn, void *user_data)
656 struct adv_monitor_app *app = user_data;
659 error("Unexpected NULL app object upon app disconnect");
663 btd_info(app->manager->adapter_id,
664 "Adv Monitor app %s disconnected from D-Bus",
667 if (queue_remove(app->manager->apps, app)) {
668 queue_foreach(app->monitors, monitor_state_released, NULL);
673 /* Handles the ready signal of Adv Monitor app */
674 static void app_ready_cb(GDBusClient *client, void *user_data)
676 struct adv_monitor_app *app = user_data;
677 uint16_t adapter_id = app->manager->adapter_id;
679 btd_info(adapter_id, "Path %s reserved for Adv Monitor app %s",
680 app->path, app->owner);
682 app_reply_msg(app, dbus_message_new_method_return(app->reg));
685 /* Allocates an Adv Monitor */
686 static struct adv_monitor *monitor_new(struct adv_monitor_app *app,
689 struct adv_monitor *monitor;
694 monitor = new0(struct adv_monitor, 1);
699 monitor->proxy = g_dbus_proxy_ref(proxy);
700 monitor->path = g_strdup(g_dbus_proxy_get_path(proxy));
702 monitor->state = MONITOR_STATE_NEW;
704 rssi_unset(&monitor->rssi);
705 monitor->devices = queue_new();
710 /* Matches a monitor based on its D-Bus path */
711 static bool monitor_match(const void *a, const void *b)
713 const GDBusProxy *proxy = b;
714 const struct adv_monitor *monitor = a;
716 if (!proxy || !monitor)
719 if (g_strcmp0(g_dbus_proxy_get_path(proxy), monitor->path) != 0)
725 /* Retrieves Type from the remote Adv Monitor object, verifies the value and
726 * update the local Adv Monitor
728 static bool parse_monitor_type(struct adv_monitor *monitor, const char *path)
730 DBusMessageIter iter;
731 const struct adv_monitor_type *t;
732 const char *type_str;
733 uint16_t adapter_id = monitor->app->manager->adapter_id;
735 if (!g_dbus_proxy_get_property(monitor->proxy, "Type", &iter)) {
736 btd_error(adapter_id,
737 "Failed to retrieve property Type from the "
738 "Adv Monitor at path %s", path);
742 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
745 dbus_message_iter_get_basic(&iter, &type_str);
747 for (t = supported_types; t->name; t++) {
748 if (strcmp(t->name, type_str) == 0) {
749 monitor->merged_pattern->type = t->type;
755 btd_error(adapter_id,
756 "Invalid argument of property Type of the Adv Monitor "
762 /* Retrieves RSSI thresholds and timeouts from the remote Adv Monitor object,
763 * verifies the values and update the local Adv Monitor
765 static bool parse_rssi_and_timeout(struct adv_monitor *monitor,
768 DBusMessageIter iter;
769 GDBusProxy *proxy = monitor->proxy;
770 int16_t h_rssi = ADV_MONITOR_UNSET_RSSI;
771 int16_t l_rssi = ADV_MONITOR_UNSET_RSSI;
772 uint16_t h_rssi_timeout = ADV_MONITOR_UNSET_TIMEOUT;
773 uint16_t l_rssi_timeout = ADV_MONITOR_UNSET_TIMEOUT;
774 uint16_t sampling_period = ADV_MONITOR_UNSET_SAMPLING_PERIOD;
775 uint16_t adapter_id = monitor->app->manager->adapter_id;
777 /* Extract RSSIHighThreshold */
778 if (g_dbus_proxy_get_property(proxy, "RSSIHighThreshold", &iter)) {
779 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT16)
781 dbus_message_iter_get_basic(&iter, &h_rssi);
784 /* Extract RSSIHighTimeout */
785 if (g_dbus_proxy_get_property(proxy, "RSSIHighTimeout", &iter)) {
786 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT16)
788 dbus_message_iter_get_basic(&iter, &h_rssi_timeout);
791 /* Extract RSSILowThreshold */
792 if (g_dbus_proxy_get_property(proxy, "RSSILowThreshold", &iter)) {
793 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INT16)
795 dbus_message_iter_get_basic(&iter, &l_rssi);
798 /* Extract RSSILowTimeout */
799 if (g_dbus_proxy_get_property(proxy, "RSSILowTimeout", &iter)) {
800 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT16)
802 dbus_message_iter_get_basic(&iter, &l_rssi_timeout);
805 /* Extract RSSISamplingPeriod */
806 if (g_dbus_proxy_get_property(proxy, "RSSISamplingPeriod", &iter)) {
807 if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT16)
809 dbus_message_iter_get_basic(&iter, &sampling_period);
812 /* Verify the values of RSSIs and their timeouts. All fields should be
813 * either set to the unset values or are set within valid ranges.
814 * If the fields are only partially set, we would try our best to fill
815 * in with some sane values.
817 if (h_rssi == ADV_MONITOR_UNSET_RSSI &&
818 l_rssi == ADV_MONITOR_UNSET_RSSI &&
819 h_rssi_timeout == ADV_MONITOR_UNSET_TIMEOUT &&
820 l_rssi_timeout == ADV_MONITOR_UNSET_TIMEOUT &&
821 sampling_period == ADV_MONITOR_UNSET_SAMPLING_PERIOD) {
825 if (l_rssi == ADV_MONITOR_UNSET_RSSI)
826 l_rssi = ADV_MONITOR_MIN_RSSI;
828 if (h_rssi == ADV_MONITOR_UNSET_RSSI)
831 if (l_rssi_timeout == ADV_MONITOR_UNSET_TIMEOUT)
832 l_rssi_timeout = ADV_MONITOR_DEFAULT_LOW_TIMEOUT;
834 if (h_rssi_timeout == ADV_MONITOR_UNSET_TIMEOUT)
835 h_rssi_timeout = ADV_MONITOR_DEFAULT_HIGH_TIMEOUT;
837 if (sampling_period == ADV_MONITOR_UNSET_SAMPLING_PERIOD)
838 sampling_period = btd_opts.advmon.rssi_sampling_period;
840 if (h_rssi < ADV_MONITOR_MIN_RSSI || h_rssi > ADV_MONITOR_MAX_RSSI ||
841 l_rssi < ADV_MONITOR_MIN_RSSI ||
842 l_rssi > ADV_MONITOR_MAX_RSSI || h_rssi < l_rssi) {
846 if (h_rssi_timeout < ADV_MONITOR_MIN_TIMEOUT ||
847 h_rssi_timeout > ADV_MONITOR_MAX_TIMEOUT ||
848 l_rssi_timeout < ADV_MONITOR_MIN_TIMEOUT ||
849 l_rssi_timeout > ADV_MONITOR_MAX_TIMEOUT) {
853 if (sampling_period > ADV_MONITOR_MAX_SAMPLING_PERIOD)
856 monitor->rssi.high_rssi = h_rssi;
857 monitor->rssi.low_rssi = l_rssi;
858 monitor->rssi.high_rssi_timeout = h_rssi_timeout;
859 monitor->rssi.low_rssi_timeout = l_rssi_timeout;
860 monitor->rssi.sampling_period = sampling_period;
863 DBG("Adv Monitor at %s initiated with high RSSI threshold %d, high "
864 "RSSI threshold timeout %d, low RSSI threshold %d, low RSSI "
865 "threshold timeout %d, sampling period %d", path,
866 monitor->rssi.high_rssi, monitor->rssi.high_rssi_timeout,
867 monitor->rssi.low_rssi, monitor->rssi.low_rssi_timeout,
868 monitor->rssi.sampling_period);
870 monitor->merged_pattern->rssi = monitor->rssi;
875 btd_error(adapter_id,
876 "Invalid argument of RSSI thresholds and timeouts "
877 "of the Adv Monitor at path %s",
883 /* Retrieves Patterns from the remote Adv Monitor object, verifies the values
884 * and update the local Adv Monitor
886 static bool parse_patterns(struct adv_monitor *monitor, const char *path)
888 DBusMessageIter array, array_iter;
889 uint16_t adapter_id = monitor->app->manager->adapter_id;
891 if (!g_dbus_proxy_get_property(monitor->proxy, "Patterns", &array)) {
892 btd_error(adapter_id,
893 "Failed to retrieve property Patterns from the "
894 "Adv Monitor at path %s", path);
898 if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY ||
899 dbus_message_iter_get_element_type(&array) !=
904 monitor->merged_pattern->patterns = queue_new();
906 dbus_message_iter_recurse(&array, &array_iter);
908 while (dbus_message_iter_get_arg_type(&array_iter) ==
912 uint8_t offset, ad_type;
913 struct bt_ad_pattern *pattern;
914 DBusMessageIter struct_iter, value_iter;
916 dbus_message_iter_recurse(&array_iter, &struct_iter);
918 // Extract start position
919 if (dbus_message_iter_get_arg_type(&struct_iter) !=
923 dbus_message_iter_get_basic(&struct_iter, &offset);
924 if (!dbus_message_iter_next(&struct_iter))
927 // Extract AD data type
928 if (dbus_message_iter_get_arg_type(&struct_iter) !=
932 dbus_message_iter_get_basic(&struct_iter, &ad_type);
933 if (!dbus_message_iter_next(&struct_iter))
936 // Extract value of a pattern
937 if (dbus_message_iter_get_arg_type(&struct_iter) !=
941 dbus_message_iter_recurse(&struct_iter, &value_iter);
942 dbus_message_iter_get_fixed_array(&value_iter, &value,
945 pattern = bt_ad_pattern_new(ad_type, offset, value_len, value);
949 queue_push_tail(monitor->merged_pattern->patterns, pattern);
951 dbus_message_iter_next(&array_iter);
954 /* There must be at least one pattern. */
955 if (queue_isempty(monitor->merged_pattern->patterns))
961 btd_error(adapter_id, "Invalid argument of property Patterns of the "
962 "Adv Monitor at path %s", path);
967 /* Processes the content of the remote Adv Monitor */
968 static bool monitor_process(struct adv_monitor *monitor)
970 const char *path = g_dbus_proxy_get_path(monitor->proxy);
972 monitor->state = MONITOR_STATE_FAILED;
974 monitor->merged_pattern = malloc0(sizeof(*monitor->merged_pattern));
975 monitor->merged_pattern->current_state = MERGED_PATTERN_STATE_STABLE;
976 monitor->merged_pattern->next_state = MERGED_PATTERN_STATE_STABLE;
978 if (!parse_monitor_type(monitor, path))
981 if (!parse_rssi_and_timeout(monitor, path))
984 if (monitor->merged_pattern->type != MONITOR_TYPE_OR_PATTERNS ||
985 !parse_patterns(monitor, path))
988 monitor->state = MONITOR_STATE_INITED;
989 monitor->merged_pattern->monitors = queue_new();
990 queue_push_tail(monitor->merged_pattern->monitors, monitor);
995 merged_pattern_free(monitor->merged_pattern);
996 monitor->merged_pattern = NULL;
1000 static void merged_pattern_destroy_monitors(
1001 struct adv_monitor_merged_pattern *merged_pattern)
1003 const struct queue_entry *e;
1005 for (e = queue_get_entries(merged_pattern->monitors); e; e = e->next) {
1006 struct adv_monitor *monitor = e->data;
1008 monitor->merged_pattern = NULL;
1009 monitor_destroy(monitor);
1013 /* Handles the callback of Remove Adv Monitor command */
1014 static void remove_adv_monitor_cb(uint8_t status, uint16_t length,
1015 const void *param, void *user_data)
1017 const struct mgmt_rp_remove_adv_monitor *rp = param;
1018 struct adv_monitor_merged_pattern *merged_pattern = user_data;
1020 if (status != MGMT_STATUS_SUCCESS || !param) {
1021 error("Failed to Remove Adv Monitor with status 0x%02x",
1026 if (length < sizeof(*rp)) {
1027 error("Wrong size of Remove Adv Monitor response");
1031 DBG("Adv monitor with handle:0x%04x removed from kernel",
1032 le16_to_cpu(rp->monitor_handle));
1034 merged_pattern_process_next_step(merged_pattern);
1036 if (merged_pattern->current_state == MERGED_PATTERN_STATE_STABLE)
1037 merged_pattern_free(merged_pattern);
1042 merged_pattern_destroy_monitors(merged_pattern);
1043 merged_pattern_free(merged_pattern);
1046 /* sends MGMT_OP_REMOVE_ADV_MONITOR */
1047 static void merged_pattern_send_remove(
1048 struct adv_monitor_merged_pattern *merged_pattern)
1050 struct mgmt_cp_remove_adv_monitor cp;
1051 struct btd_adv_monitor_manager *manager = merged_pattern->manager;
1053 cp.monitor_handle = cpu_to_le16(merged_pattern->monitor_handle);
1055 if (!mgmt_send(manager->mgmt, MGMT_OP_REMOVE_ADV_MONITOR,
1056 manager->adapter_id, sizeof(cp), &cp,
1057 remove_adv_monitor_cb, merged_pattern, NULL)) {
1058 btd_error(merged_pattern->manager->adapter_id,
1059 "Unable to send Remove Advt Monitor command");
1063 /* Handles the callback of Add Adv Patterns Monitor command */
1064 static void add_adv_patterns_monitor_cb(uint8_t status, uint16_t length,
1065 const void *param, void *user_data)
1067 const struct mgmt_rp_add_adv_patterns_monitor *rp = param;
1068 struct adv_monitor_merged_pattern *merged_pattern = user_data;
1069 uint16_t adapter_id = merged_pattern->manager->adapter_id;
1071 if (status != MGMT_STATUS_SUCCESS || !param) {
1072 btd_error(adapter_id,
1073 "Failed to Add Adv Patterns Monitor with status"
1078 if (length < sizeof(*rp)) {
1079 btd_error(adapter_id, "Wrong size of Add Adv Patterns Monitor "
1084 merged_pattern->monitor_handle = le16_to_cpu(rp->monitor_handle);
1085 DBG("Adv monitor with handle:0x%04x added",
1086 merged_pattern->monitor_handle);
1088 merged_pattern_process_next_step(merged_pattern);
1090 if (merged_pattern->current_state != MERGED_PATTERN_STATE_STABLE)
1093 queue_foreach(merged_pattern->monitors, monitor_state_active, NULL);
1098 merged_pattern_destroy_monitors(merged_pattern);
1099 merged_pattern_free(merged_pattern);
1102 /* sends MGMT_OP_ADD_ADV_PATTERNS_MONITOR */
1103 static bool merged_pattern_send_add_pattern(
1104 struct adv_monitor_merged_pattern *merged_pattern)
1106 struct mgmt_cp_add_adv_monitor *cp = NULL;
1107 uint8_t pattern_count, cp_len;
1108 const struct queue_entry *e;
1109 bool success = true;
1111 pattern_count = queue_length(merged_pattern->patterns);
1112 cp_len = sizeof(*cp) + pattern_count * sizeof(struct mgmt_adv_pattern);
1114 cp = malloc0(cp_len);
1118 for (e = queue_get_entries(merged_pattern->patterns); e; e = e->next) {
1119 struct bt_ad_pattern *pattern = e->data;
1121 memcpy(&cp->patterns[cp->pattern_count++], pattern,
1125 if (!mgmt_send(merged_pattern->manager->mgmt,
1126 MGMT_OP_ADD_ADV_PATTERNS_MONITOR,
1127 merged_pattern->manager->adapter_id, cp_len, cp,
1128 add_adv_patterns_monitor_cb, merged_pattern, NULL)) {
1129 error("Unable to send Add Adv Patterns Monitor command");
1137 /* sends MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI */
1138 static bool merged_pattern_send_add_pattern_rssi(
1139 struct adv_monitor_merged_pattern *merged_pattern)
1141 struct mgmt_cp_add_adv_patterns_monitor_rssi *cp = NULL;
1142 uint8_t pattern_count, cp_len;
1143 const struct queue_entry *e;
1144 bool success = true;
1146 pattern_count = queue_length(merged_pattern->patterns);
1147 cp_len = sizeof(*cp) + pattern_count * sizeof(struct mgmt_adv_pattern);
1149 cp = malloc0(cp_len);
1153 cp->rssi.high_threshold = merged_pattern->rssi.high_rssi;
1154 /* High threshold timeout is unsupported in kernel. Value must be 0. */
1155 cp->rssi.high_threshold_timeout = 0;
1156 cp->rssi.low_threshold = merged_pattern->rssi.low_rssi;
1157 cp->rssi.low_threshold_timeout =
1158 htobs(merged_pattern->rssi.low_rssi_timeout);
1159 cp->rssi.sampling_period = merged_pattern->rssi.sampling_period;
1161 for (e = queue_get_entries(merged_pattern->patterns); e; e = e->next) {
1162 struct bt_ad_pattern *pattern = e->data;
1164 memcpy(&cp->patterns[cp->pattern_count++], pattern,
1168 if (!mgmt_send(merged_pattern->manager->mgmt,
1169 MGMT_OP_ADD_ADV_PATTERNS_MONITOR_RSSI,
1170 merged_pattern->manager->adapter_id, cp_len, cp,
1171 add_adv_patterns_monitor_cb, merged_pattern, NULL)) {
1172 error("Unable to send Add Adv Patterns Monitor RSSI command");
1180 /* Sends mgmt command to kernel for adding monitor */
1181 static void merged_pattern_send_add(
1182 struct adv_monitor_merged_pattern *merged_pattern)
1184 if (rssi_is_unset(&merged_pattern->rssi))
1185 merged_pattern_send_add_pattern(merged_pattern);
1187 merged_pattern_send_add_pattern_rssi(merged_pattern);
1190 /* Handles an Adv Monitor D-Bus proxy added event */
1191 static void monitor_proxy_added_cb(GDBusProxy *proxy, void *user_data)
1193 struct adv_monitor *monitor;
1194 struct adv_monitor_app *app = user_data;
1195 struct adv_monitor_merged_pattern *existing_pattern;
1196 uint16_t adapter_id = app->manager->adapter_id;
1197 const char *path = g_dbus_proxy_get_path(proxy);
1198 const char *iface = g_dbus_proxy_get_interface(proxy);
1199 struct rssi_parameters rssi;
1201 if (strcmp(iface, ADV_MONITOR_INTERFACE) != 0 ||
1202 !g_str_has_prefix(path, app->path)) {
1206 if (queue_find(app->monitors, monitor_match, proxy)) {
1207 btd_error(adapter_id,
1208 "Adv Monitor proxy already exists with path %s",
1213 monitor = monitor_new(app, proxy);
1215 btd_error(adapter_id,
1216 "Failed to allocate an Adv Monitor for the "
1217 "object at %s", path);
1221 if (!monitor_process(monitor)) {
1222 monitor_destroy(monitor);
1223 DBG("Adv Monitor at path %s released due to invalid content",
1228 queue_push_tail(app->monitors, monitor);
1230 existing_pattern = queue_find(monitor->app->manager->merged_patterns,
1231 merged_pattern_is_equal,
1232 monitor->merged_pattern);
1234 if (!existing_pattern) {
1235 monitor->merged_pattern->manager = monitor->app->manager;
1236 queue_push_tail(monitor->app->manager->merged_patterns,
1237 monitor->merged_pattern);
1238 merged_pattern_add(monitor->merged_pattern);
1240 /* Since there is a matching pattern, abandon the one we have */
1241 merged_pattern_free(monitor->merged_pattern);
1242 monitor->merged_pattern = existing_pattern;
1243 queue_push_tail(existing_pattern->monitors, monitor);
1245 merge_rssi(&existing_pattern->rssi, &monitor->rssi, &rssi);
1246 merged_pattern_replace(existing_pattern, &rssi);
1248 /* Stable means request is not forwarded to kernel */
1249 if (existing_pattern->current_state ==
1250 MERGED_PATTERN_STATE_STABLE)
1251 monitor_state_active(monitor, NULL);
1254 DBG("Adv Monitor allocated for the object at path %s", path);
1257 /* Handles the removal of an Adv Monitor D-Bus proxy */
1258 static void monitor_proxy_removed_cb(GDBusProxy *proxy, void *user_data)
1260 struct adv_monitor *monitor;
1261 struct adv_monitor_app *app = user_data;
1263 monitor = queue_find(app->monitors, monitor_match, proxy);
1268 DBG("Adv Monitor removed in state %02x with path %s", monitor->state,
1271 monitor_state_released(monitor, NULL);
1272 monitor_destroy(monitor);
1275 /* Creates an app object, initiates it and sets D-Bus event handlers */
1276 static struct adv_monitor_app *app_create(DBusConnection *conn,
1277 DBusMessage *msg, const char *sender,
1279 struct btd_adv_monitor_manager *manager)
1281 struct adv_monitor_app *app;
1283 if (!path || !sender || !manager)
1286 app = new0(struct adv_monitor_app, 1);
1290 app->owner = g_strdup(sender);
1291 app->path = g_strdup(path);
1292 app->manager = manager;
1295 app->client = g_dbus_client_new_full(conn, sender, path, path);
1301 app->monitors = queue_new();
1303 app->reg = dbus_message_ref(msg);
1305 g_dbus_client_set_disconnect_watch(app->client, app_disconnect_cb, app);
1307 /* Note that any property changes on a monitor object would not affect
1308 * the content of the corresponding monitor.
1310 g_dbus_client_set_proxy_handlers(app->client, monitor_proxy_added_cb,
1311 monitor_proxy_removed_cb, NULL,
1314 g_dbus_client_set_ready_watch(app->client, app_ready_cb, app);
1319 /* Matches an app based on its owner and path */
1320 static bool app_match(const void *a, const void *b)
1322 const struct adv_monitor_app *app = a;
1323 const struct app_match_data *match = b;
1325 if (match->owner && strcmp(app->owner, match->owner))
1328 if (match->path && strcmp(app->path, match->path))
1334 /* Handles a RegisterMonitor D-Bus call */
1335 static DBusMessage *register_monitor(DBusConnection *conn, DBusMessage *msg,
1338 DBusMessageIter args;
1339 struct app_match_data match;
1340 struct adv_monitor_app *app;
1341 struct btd_adv_monitor_manager *manager = user_data;
1343 if (!dbus_message_iter_init(msg, &args))
1344 return btd_error_invalid_args(msg);
1346 if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH)
1347 return btd_error_invalid_args(msg);
1349 dbus_message_iter_get_basic(&args, &match.path);
1351 if (!strlen(match.path) || !g_str_has_prefix(match.path, "/"))
1352 return btd_error_invalid_args(msg);
1354 match.owner = dbus_message_get_sender(msg);
1356 if (queue_find(manager->apps, app_match, &match))
1357 return btd_error_already_exists(msg);
1359 app = app_create(conn, msg, match.owner, match.path, manager);
1361 btd_error(manager->adapter_id,
1362 "Failed to reserve %s for Adv Monitor app %s",
1363 match.path, match.owner);
1364 return btd_error_failed(msg,
1365 "Failed to create Adv Monitor app");
1368 queue_push_tail(manager->apps, app);
1373 /* Handles UnregisterMonitor D-Bus call */
1374 static DBusMessage *unregister_monitor(DBusConnection *conn,
1375 DBusMessage *msg, void *user_data)
1377 DBusMessageIter args;
1378 struct app_match_data match;
1379 struct adv_monitor_app *app;
1380 struct btd_adv_monitor_manager *manager = user_data;
1382 if (!dbus_message_iter_init(msg, &args))
1383 return btd_error_invalid_args(msg);
1385 if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_OBJECT_PATH)
1386 return btd_error_invalid_args(msg);
1388 dbus_message_iter_get_basic(&args, &match.path);
1390 if (!strlen(match.path) || !g_str_has_prefix(match.path, "/"))
1391 return btd_error_invalid_args(msg);
1393 match.owner = dbus_message_get_sender(msg);
1395 app = queue_find(manager->apps, app_match, &match);
1397 return btd_error_does_not_exist(msg);
1399 queue_remove(manager->apps, app);
1402 btd_info(manager->adapter_id,
1403 "Path %s removed along with Adv Monitor app %s",
1404 match.path, match.owner);
1406 return dbus_message_new_method_return(msg);
1409 static const GDBusMethodTable adv_monitor_methods[] = {
1410 { GDBUS_EXPERIMENTAL_ASYNC_METHOD("RegisterMonitor",
1411 GDBUS_ARGS({ "application", "o" }),
1412 NULL, register_monitor) },
1413 { GDBUS_EXPERIMENTAL_ASYNC_METHOD("UnregisterMonitor",
1414 GDBUS_ARGS({ "application", "o" }),
1415 NULL, unregister_monitor) },
1419 /* Gets SupportedMonitorTypes property */
1420 static gboolean get_supported_monitor_types(const GDBusPropertyTable *property,
1421 DBusMessageIter *iter,
1424 DBusMessageIter entry;
1425 const struct adv_monitor_type *t;
1427 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1428 DBUS_TYPE_STRING_AS_STRING,
1431 for (t = supported_types; t->name; t++) {
1432 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
1436 dbus_message_iter_close_container(iter, &entry);
1441 const struct adv_monitor_feature {
1444 } supported_features[] = {
1445 { MGMT_ADV_MONITOR_FEATURE_MASK_OR_PATTERNS, "controller-patterns" },
1449 /* Gets SupportedFeatures property */
1450 static gboolean get_supported_features(const GDBusPropertyTable *property,
1451 DBusMessageIter *iter,
1454 DBusMessageIter entry;
1455 const struct adv_monitor_feature *f;
1456 struct btd_adv_monitor_manager *manager = data;
1458 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1459 DBUS_TYPE_STRING_AS_STRING,
1462 for (f = supported_features; f->name; f++) {
1463 if (manager->supported_features & f->mask) {
1464 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
1469 dbus_message_iter_close_container(iter, &entry);
1474 static const GDBusPropertyTable adv_monitor_properties[] = {
1475 {"SupportedMonitorTypes", "as", get_supported_monitor_types, NULL, NULL,
1476 G_DBUS_PROPERTY_FLAG_EXPERIMENTAL},
1477 {"SupportedFeatures", "as", get_supported_features, NULL, NULL,
1478 G_DBUS_PROPERTY_FLAG_EXPERIMENTAL},
1482 /* Updates monitor state to 'removed' */
1483 static void monitor_state_removed(void *data, void *user_data)
1485 struct adv_monitor *monitor = data;
1487 if (!monitor || (monitor->state != MONITOR_STATE_INITED
1488 && monitor->state != MONITOR_STATE_ACTIVE))
1491 monitor->state = MONITOR_STATE_REMOVED;
1492 monitor->merged_pattern = NULL;
1495 /* Remove the matched merged_pattern and remove the monitors */
1496 static void remove_merged_pattern(void *data, void *user_data)
1498 struct adv_monitor_merged_pattern *merged_pattern = data;
1499 uint16_t *handle = user_data;
1504 /* handle = 0 indicates kernel has removed all monitors */
1505 if (handle != 0 && *handle != merged_pattern->monitor_handle)
1508 DBG("Adv monitor with handle:0x%04x removed by kernel",
1509 merged_pattern->monitor_handle);
1511 queue_foreach(merged_pattern->monitors, monitor_state_removed, NULL);
1512 queue_destroy(merged_pattern->monitors, monitor_destroy);
1513 merged_pattern_free(merged_pattern);
1516 /* Processes Adv Monitor removed event from kernel */
1517 static void adv_monitor_removed_callback(uint16_t index, uint16_t length,
1518 const void *param, void *user_data)
1520 struct btd_adv_monitor_manager *manager = user_data;
1521 const struct mgmt_ev_adv_monitor_removed *ev = param;
1522 uint16_t handle = ev->monitor_handle;
1523 const uint16_t adapter_id = manager->adapter_id;
1525 if (length < sizeof(*ev)) {
1526 btd_error(adapter_id,
1527 "Wrong size of Adv Monitor Removed event");
1531 /* Traverse the merged_patterns to find matching pattern */
1532 queue_foreach(manager->merged_patterns, remove_merged_pattern, &handle);
1534 DBG("Adv Monitor removed event with handle 0x%04x processed",
1535 ev->monitor_handle);
1538 /* Includes found/lost device's object path into the dbus message */
1539 static void report_device_state_setup(DBusMessageIter *iter, void *user_data)
1541 const char *path = device_get_path(user_data);
1543 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &path);
1546 /* Invokes DeviceFound on the matched monitor */
1547 static void notify_device_found_per_monitor(void *data, void *user_data)
1549 struct adv_monitor *monitor = data;
1550 struct monitored_device_info *info = user_data;
1552 if (monitor->merged_pattern->monitor_handle == info->monitor_handle) {
1553 DBG("Calling DeviceFound() on Adv Monitor of owner %s "
1554 "at path %s", monitor->app->owner, monitor->path);
1556 g_dbus_proxy_method_call(monitor->proxy, "DeviceFound",
1557 report_device_state_setup, NULL,
1558 info->device, NULL);
1562 /* Checks all monitors for match in the app to invoke DeviceFound */
1563 static void notify_device_found_per_app(void *data, void *user_data)
1565 struct adv_monitor_app *app = data;
1567 queue_foreach(app->monitors, notify_device_found_per_monitor,
1571 /* Processes Adv Monitor Device Found event from kernel */
1572 static void adv_monitor_device_found_callback(uint16_t index, uint16_t length,
1576 const struct mgmt_ev_adv_monitor_device_found *ev = param;
1577 struct btd_adv_monitor_manager *manager = user_data;
1578 const uint16_t adapter_id = manager->adapter_id;
1579 struct btd_adapter *adapter = manager->adapter;
1580 uint16_t handle = le16_to_cpu(ev->monitor_handle);
1581 struct monitored_device_info info;
1582 const uint8_t *ad_data = NULL;
1583 uint16_t ad_data_len;
1588 bool not_connectable;
1590 if (length < sizeof(*ev)) {
1591 btd_error(adapter_id,
1592 "Too short Adv Monitor Device Found event");
1596 ad_data_len = btohs(ev->ad_data_len);
1597 if (length != sizeof(*ev) + ad_data_len) {
1598 btd_error(adapter_id,
1599 "Wrong size of Adv Monitor Device Found event");
1603 if (ad_data_len > 0)
1604 ad_data = ev->ad_data;
1606 flags = btohl(ev->flags);
1608 ba2str(&ev->addr.bdaddr, addr);
1609 DBG("hci%u addr %s, rssi %d flags 0x%04x ad_data_len %u",
1610 index, addr, ev->rssi, flags, ad_data_len);
1612 confirm_name = (flags & MGMT_DEV_FOUND_CONFIRM_NAME);
1613 legacy = (flags & MGMT_DEV_FOUND_LEGACY_PAIRING);
1614 not_connectable = (flags & MGMT_DEV_FOUND_NOT_CONNECTABLE);
1616 btd_adapter_update_found_device(adapter, &ev->addr.bdaddr,
1617 ev->addr.type, ev->rssi, confirm_name,
1618 legacy, not_connectable, ad_data,
1622 DBG("Adv Monitor with handle 0x%04x started tracking "
1623 "the device %s", handle, addr);
1625 info.device = btd_adapter_find_device(adapter, &ev->addr.bdaddr,
1628 btd_error(adapter_id, "Device object not found for %s",
1633 /* Check for matched monitor in all apps */
1634 info.monitor_handle = handle;
1635 queue_foreach(manager->apps, notify_device_found_per_app,
1640 /* Invokes DeviceLost on the matched monitor */
1641 static void notify_device_lost_per_monitor(void *data, void *user_data)
1643 struct adv_monitor *monitor = data;
1644 struct monitored_device_info *info = user_data;
1646 if (monitor->merged_pattern->monitor_handle == info->monitor_handle) {
1647 DBG("Calling DeviceLost() on Adv Monitor of owner %s "
1648 "at path %s", monitor->app->owner, monitor->path);
1650 g_dbus_proxy_method_call(monitor->proxy, "DeviceLost",
1651 report_device_state_setup, NULL,
1652 info->device, NULL);
1656 /* Checks all monitors for match in the app to invoke DeviceLost */
1657 static void notify_device_lost_per_app(void *data, void *user_data)
1659 struct adv_monitor_app *app = data;
1661 queue_foreach(app->monitors, notify_device_lost_per_monitor,
1665 /* Processes Adv Monitor Device Lost event from kernel */
1666 static void adv_monitor_device_lost_callback(uint16_t index, uint16_t length,
1670 struct btd_adv_monitor_manager *manager = user_data;
1671 const struct mgmt_ev_adv_monitor_device_lost *ev = param;
1672 uint16_t handle = le16_to_cpu(ev->monitor_handle);
1673 const uint16_t adapter_id = manager->adapter_id;
1674 struct btd_adapter *adapter = manager->adapter;
1675 struct monitored_device_info info;
1678 if (length < sizeof(*ev)) {
1679 btd_error(adapter_id,
1680 "Wrong size of Adv Monitor Device Lost event");
1684 ba2str(&ev->addr.bdaddr, addr);
1685 DBG("Adv Monitor with handle 0x%04x stopped tracking the device %s",
1688 info.device = btd_adapter_find_device(adapter, &ev->addr.bdaddr,
1691 btd_error(adapter_id, "Device object not found for %s", addr);
1695 /* Check for matched monitor in all apps */
1696 info.monitor_handle = handle;
1697 queue_foreach(manager->apps, notify_device_lost_per_app, &info);
1700 /* Allocates a manager object */
1701 static struct btd_adv_monitor_manager *manager_new(
1702 struct btd_adapter *adapter,
1705 struct btd_adv_monitor_manager *manager;
1707 if (!adapter || !mgmt)
1710 manager = new0(struct btd_adv_monitor_manager, 1);
1714 manager->adapter = adapter;
1715 manager->mgmt = mgmt_ref(mgmt);
1716 manager->adapter_id = btd_adapter_get_index(adapter);
1717 manager->apps = queue_new();
1718 manager->merged_patterns = queue_new();
1720 mgmt_register(manager->mgmt, MGMT_EV_ADV_MONITOR_REMOVED,
1721 manager->adapter_id, adv_monitor_removed_callback,
1724 mgmt_register(manager->mgmt, MGMT_EV_ADV_MONITOR_DEVICE_FOUND,
1725 manager->adapter_id, adv_monitor_device_found_callback,
1728 mgmt_register(manager->mgmt, MGMT_EV_ADV_MONITOR_DEVICE_LOST,
1729 manager->adapter_id, adv_monitor_device_lost_callback,
1735 /* Frees a manager object */
1736 static void manager_free(struct btd_adv_monitor_manager *manager)
1738 mgmt_unref(manager->mgmt);
1740 queue_destroy(manager->apps, app_destroy);
1741 queue_destroy(manager->merged_patterns, merged_pattern_free);
1746 /* Destroys a manager object and unregisters its D-Bus interface */
1747 static void manager_destroy(struct btd_adv_monitor_manager *manager)
1752 g_dbus_unregister_interface(btd_get_dbus_connection(),
1753 adapter_get_path(manager->adapter),
1754 ADV_MONITOR_MGR_INTERFACE);
1756 manager_free(manager);
1759 /* Initiates manager's members based on the return of
1760 * MGMT_OP_READ_ADV_MONITOR_FEATURES
1762 static void read_adv_monitor_features_cb(uint8_t status, uint16_t length,
1766 const struct mgmt_rp_read_adv_monitor_features *rp = param;
1767 struct btd_adv_monitor_manager *manager = user_data;
1769 if (status != MGMT_STATUS_SUCCESS || !param) {
1770 btd_error(manager->adapter_id,
1771 "Failed to Read Adv Monitor Features with "
1772 "status 0x%02x", status);
1776 if (length < sizeof(*rp)) {
1777 btd_error(manager->adapter_id,
1778 "Wrong size of Read Adv Monitor Features "
1783 manager->supported_features = le32_to_cpu(rp->supported_features);
1784 manager->enabled_features = le32_to_cpu(rp->enabled_features);
1785 manager->max_num_monitors = le16_to_cpu(rp->max_num_handles);
1786 manager->max_num_patterns = rp->max_num_patterns;
1788 btd_info(manager->adapter_id, "Adv Monitor Manager created with "
1789 "supported features:0x%08x, enabled features:0x%08x, "
1790 "max number of supported monitors:%d, "
1791 "max number of supported patterns:%d",
1792 manager->supported_features, manager->enabled_features,
1793 manager->max_num_monitors, manager->max_num_patterns);
1796 /* Creates a manager and registers its D-Bus interface */
1797 struct btd_adv_monitor_manager *btd_adv_monitor_manager_create(
1798 struct btd_adapter *adapter,
1801 struct btd_adv_monitor_manager *manager;
1803 manager = manager_new(adapter, mgmt);
1807 if (!g_dbus_register_interface(btd_get_dbus_connection(),
1808 adapter_get_path(manager->adapter),
1809 ADV_MONITOR_MGR_INTERFACE,
1810 adv_monitor_methods, NULL,
1811 adv_monitor_properties, manager,
1813 btd_error(manager->adapter_id,
1814 "Failed to register "
1815 ADV_MONITOR_MGR_INTERFACE);
1816 manager_free(manager);
1820 if (!mgmt_send(manager->mgmt, MGMT_OP_READ_ADV_MONITOR_FEATURES,
1821 manager->adapter_id, 0, NULL,
1822 read_adv_monitor_features_cb, manager, NULL)) {
1823 btd_error(manager->adapter_id,
1824 "Failed to send Read Adv Monitor Features");
1825 manager_destroy(manager);
1832 /* Destroys a manager and unregisters its D-Bus interface */
1833 void btd_adv_monitor_manager_destroy(struct btd_adv_monitor_manager *manager)
1838 btd_info(manager->adapter_id, "Destroy Adv Monitor Manager");
1840 manager_destroy(manager);
1843 bool btd_adv_monitor_offload_supported(struct btd_adv_monitor_manager *manager)
1846 error("Manager is NULL, get offload support failed");
1850 return !!(manager->enabled_features &
1851 MGMT_ADV_MONITOR_FEATURE_MASK_OR_PATTERNS);
1854 /* Processes the content matching based pattern(s) of a monitor */
1855 static void adv_match_per_monitor(void *data, void *user_data)
1857 struct adv_monitor *monitor = data;
1858 struct adv_content_filter_info *info = user_data;
1859 struct queue *patterns;
1862 error("Unexpected NULL adv_monitor object upon match");
1866 if (monitor->state != MONITOR_STATE_ACTIVE)
1869 if (!monitor->merged_pattern)
1872 patterns = monitor->merged_pattern->patterns;
1873 if (monitor->merged_pattern->type == MONITOR_TYPE_OR_PATTERNS &&
1874 bt_ad_pattern_match(info->ad, patterns)) {
1881 if (!info->matched_monitors)
1882 info->matched_monitors = queue_new();
1884 queue_push_tail(info->matched_monitors, monitor);
1887 /* Processes the content matching for the monitor(s) of an app */
1888 static void adv_match_per_app(void *data, void *user_data)
1890 struct adv_monitor_app *app = data;
1893 error("Unexpected NULL adv_monitor_app object upon match");
1897 queue_foreach(app->monitors, adv_match_per_monitor, user_data);
1900 /* Processes the content matching for every app without RSSI filtering and
1901 * notifying monitors. The caller is responsible of releasing the memory of the
1902 * list but not the ad data.
1903 * Returns the list of monitors whose content match the ad data.
1905 struct queue *btd_adv_monitor_content_filter(
1906 struct btd_adv_monitor_manager *manager,
1909 struct adv_content_filter_info info;
1911 if (!manager || !ad)
1915 info.matched_monitors = NULL;
1917 queue_foreach(manager->apps, adv_match_per_app, &info);
1919 return info.matched_monitors;
1922 /* Wraps adv_monitor_filter_rssi() to processes the content-matched monitor with
1923 * RSSI filtering and notifies it on device found/lost event
1925 static void monitor_filter_rssi(void *data, void *user_data)
1927 struct adv_monitor *monitor = data;
1928 struct adv_rssi_filter_info *info = user_data;
1930 if (!monitor || !info)
1933 adv_monitor_filter_rssi(monitor, info->device, info->rssi);
1936 /* Processes every content-matched monitor with RSSI filtering and notifies on
1937 * device found/lost event. The caller is responsible of releasing the memory
1938 * of matched_monitors list but not its data.
1940 void btd_adv_monitor_notify_monitors(struct btd_adv_monitor_manager *manager,
1941 struct btd_device *device, int8_t rssi,
1942 struct queue *matched_monitors)
1944 struct adv_rssi_filter_info info;
1946 if (!manager || !device || !matched_monitors ||
1947 queue_isempty(matched_monitors)) {
1951 info.device = device;
1954 queue_foreach(matched_monitors, monitor_filter_rssi, &info);
1957 /* Matches a device based on btd_device object */
1958 static bool monitor_device_match(const void *a, const void *b)
1960 const struct adv_monitor_device *dev = a;
1961 const struct btd_device *device = b;
1964 error("Unexpected NULL adv_monitor_device object upon match");
1968 if (dev->device != device)
1974 /* Frees a monitor device object */
1975 static void monitor_device_free(void *data)
1977 struct adv_monitor_device *dev = data;
1980 error("Unexpected NULL adv_monitor_device object upon free");
1984 if (dev->lost_timer) {
1985 timeout_remove(dev->lost_timer);
1986 dev->lost_timer = 0;
1989 dev->monitor = NULL;
1995 /* Removes a device from monitor->devices list */
1996 static void remove_device_from_monitor(void *data, void *user_data)
1998 struct adv_monitor *monitor = data;
1999 struct btd_device *device = user_data;
2000 struct adv_monitor_device *dev = NULL;
2003 error("Unexpected NULL adv_monitor object upon device remove");
2007 dev = queue_remove_if(monitor->devices, monitor_device_match, device);
2009 DBG("Device removed from the Adv Monitor at path %s",
2011 monitor_device_free(dev);
2015 /* Removes a device from every monitor in an app */
2016 static void remove_device_from_app(void *data, void *user_data)
2018 struct adv_monitor_app *app = data;
2019 struct btd_device *device = user_data;
2022 error("Unexpected NULL adv_monitor_app object upon device "
2027 queue_foreach(app->monitors, remove_device_from_monitor, device);
2030 /* Removes a device from every monitor in all apps */
2031 void btd_adv_monitor_device_remove(struct btd_adv_monitor_manager *manager,
2032 struct btd_device *device)
2034 if (!manager || !device)
2037 queue_foreach(manager->apps, remove_device_from_app, device);
2040 /* Creates a device object to track the per-device information */
2041 static struct adv_monitor_device *monitor_device_create(
2042 struct adv_monitor *monitor,
2043 struct btd_device *device)
2045 struct adv_monitor_device *dev = NULL;
2047 dev = new0(struct adv_monitor_device, 1);
2051 dev->monitor = monitor;
2052 dev->device = device;
2054 queue_push_tail(monitor->devices, dev);
2059 /* Handles a situation where the device goes offline/out-of-range */
2060 static bool handle_device_lost_timeout(gpointer user_data)
2062 struct adv_monitor_device *dev = user_data;
2063 struct adv_monitor *monitor = dev->monitor;
2065 DBG("Device Lost timeout triggered for device %p. Calling DeviceLost() "
2066 "on Adv Monitor of owner %s at path %s", dev->device,
2067 monitor->app->owner, monitor->path);
2069 g_dbus_proxy_method_call(monitor->proxy, "DeviceLost",
2070 report_device_state_setup,
2071 NULL, dev->device, NULL);
2073 dev->lost_timer = 0;
2079 /* Filters an Adv based on its RSSI value */
2080 static void adv_monitor_filter_rssi(struct adv_monitor *monitor,
2081 struct btd_device *device, int8_t rssi)
2083 struct adv_monitor_device *dev = NULL;
2084 time_t curr_time = time(NULL);
2085 uint16_t adapter_id = monitor->app->manager->adapter_id;
2087 /* If the RSSI thresholds and timeouts are not specified, report the
2088 * DeviceFound() event without tracking for the RSSI as the Adv has
2089 * already matched the pattern filter.
2091 if (rssi_is_unset(&monitor->rssi)) {
2092 DBG("Calling DeviceFound() on Adv Monitor of owner %s "
2093 "at path %s", monitor->app->owner, monitor->path);
2095 g_dbus_proxy_method_call(monitor->proxy, "DeviceFound",
2096 report_device_state_setup, NULL,
2102 dev = queue_find(monitor->devices, monitor_device_match, device);
2104 dev = monitor_device_create(monitor, device);
2106 btd_error(adapter_id,
2107 "Failed to create Adv Monitor device object.");
2112 if (dev->lost_timer) {
2113 timeout_remove(dev->lost_timer);
2114 dev->lost_timer = 0;
2117 /* Reset the timings of found/lost if a device has been offline for
2118 * longer than the high/low timeouts.
2120 if (dev->last_seen) {
2121 if (difftime(curr_time, dev->last_seen) >
2122 monitor->rssi.high_rssi_timeout) {
2123 dev->high_rssi_first_seen = 0;
2126 if (difftime(curr_time, dev->last_seen) >
2127 monitor->rssi.low_rssi_timeout) {
2128 dev->low_rssi_first_seen = 0;
2131 dev->last_seen = curr_time;
2133 /* Check for the found devices (if the device is not already found) */
2134 if (!dev->found && rssi > monitor->rssi.high_rssi) {
2135 if (dev->high_rssi_first_seen) {
2136 if (difftime(curr_time, dev->high_rssi_first_seen) >=
2137 monitor->rssi.high_rssi_timeout) {
2140 DBG("Calling DeviceFound() on Adv Monitor "
2141 "of owner %s at path %s",
2142 monitor->app->owner, monitor->path);
2144 g_dbus_proxy_method_call(
2145 monitor->proxy, "DeviceFound",
2146 report_device_state_setup, NULL,
2150 dev->high_rssi_first_seen = curr_time;
2153 dev->high_rssi_first_seen = 0;
2156 /* Check for the lost devices (only if the device is already found, as
2157 * it doesn't make any sense to report the Device Lost event if the
2158 * device is not found yet)
2160 if (dev->found && rssi < monitor->rssi.low_rssi) {
2161 if (dev->low_rssi_first_seen) {
2162 if (difftime(curr_time, dev->low_rssi_first_seen) >=
2163 monitor->rssi.low_rssi_timeout) {
2166 DBG("Calling DeviceLost() on Adv Monitor "
2167 "of owner %s at path %s",
2168 monitor->app->owner, monitor->path);
2170 g_dbus_proxy_method_call(
2171 monitor->proxy, "DeviceLost",
2172 report_device_state_setup, NULL,
2176 dev->low_rssi_first_seen = curr_time;
2179 dev->low_rssi_first_seen = 0;
2182 /* Setup a timer to track if the device goes offline/out-of-range, only
2183 * if we are tracking for the Low RSSI Threshold. If we are tracking
2184 * the High RSSI Threshold, nothing needs to be done.
2188 timeout_add_seconds(monitor->rssi.low_rssi_timeout,
2189 handle_device_lost_timeout, dev,
2194 /* Clears running DeviceLost timer for a given device */
2195 static void clear_device_lost_timer(void *data, void *user_data)
2197 struct adv_monitor_device *dev = data;
2198 struct adv_monitor *monitor = NULL;
2200 if (dev->lost_timer) {
2201 timeout_remove(dev->lost_timer);
2202 dev->lost_timer = 0;
2204 monitor = dev->monitor;
2206 DBG("Calling DeviceLost() for device %p on Adv Monitor "
2207 "of owner %s at path %s", dev->device,
2208 monitor->app->owner, monitor->path);
2210 g_dbus_proxy_method_call(monitor->proxy, "DeviceLost",
2211 report_device_state_setup,
2212 NULL, dev->device, NULL);
2216 /* Clears running DeviceLost timers from each monitor */
2217 static void clear_lost_timers_from_monitor(void *data, void *user_data)
2219 struct adv_monitor *monitor = data;
2221 queue_foreach(monitor->devices, clear_device_lost_timer, NULL);
2224 /* Clears running DeviceLost timers from each app */
2225 static void clear_lost_timers_from_app(void *data, void *user_data)
2227 struct adv_monitor_app *app = data;
2229 queue_foreach(app->monitors, clear_lost_timers_from_monitor, NULL);
2232 /* Handles bt power down scenario */
2233 void btd_adv_monitor_power_down(struct btd_adv_monitor_manager *manager)
2236 error("Unexpected NULL btd_adv_monitor_manager object upon "
2241 /* Clear any running DeviceLost timers in case of power down */
2242 queue_foreach(manager->apps, clear_lost_timers_from_app, NULL);