[RFC v2 3/7] proximity: Split internal monitor registration API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Mikel Astiz <mikel.astiz@xxxxxxxxxxxx>

Split the monitor registration API into three independent registrations
each of them taking one specific GATT primary.
---
 profiles/proximity/manager.c |  16 +++-
 profiles/proximity/monitor.c | 220 ++++++++++++++++++++++++++++++++++---------
 profiles/proximity/monitor.h |  17 +++-
 3 files changed, 204 insertions(+), 49 deletions(-)

diff --git a/profiles/proximity/manager.c b/profiles/proximity/manager.c
index b405f15..3182596 100644
--- a/profiles/proximity/manager.c
+++ b/profiles/proximity/manager.c
@@ -52,18 +52,30 @@ static int monitor_device_probe(struct btd_profile *p,
 				struct btd_device *device, GSList *uuids)
 {
 	struct gatt_primary *linkloss, *txpower, *immediate;
+	int err = 0;
 
 	immediate = btd_device_get_primary(device, IMMEDIATE_ALERT_UUID);
 	txpower = btd_device_get_primary(device, TX_POWER_UUID);
 	linkloss = btd_device_get_primary(device, LINK_LOSS_UUID);
 
-	return monitor_register(device, linkloss, txpower, immediate, &enabled);
+	if (linkloss)
+		err = monitor_register_linkloss(device, &enabled, linkloss);
+
+	if (err >= 0 && immediate)
+		err = monitor_register_immediate(device, &enabled, immediate);
+
+	if (err >= 0 && txpower)
+		err = monitor_register_txpower(device, &enabled, txpower);
+
+	return err;
 }
 
 static void monitor_device_remove(struct btd_profile *p,
 						struct btd_device *device)
 {
-	monitor_unregister(device);
+	monitor_unregister_txpower(device);
+	monitor_unregister_immediate(device);
+	monitor_unregister_linkloss(device);
 }
 
 static struct btd_profile pxp_monitor_profile = {
diff --git a/profiles/proximity/monitor.c b/profiles/proximity/monitor.c
index 597f161..48f877d 100644
--- a/profiles/proximity/monitor.c
+++ b/profiles/proximity/monitor.c
@@ -34,6 +34,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/stat.h>
+#include <glib.h>
 
 #include <bluetooth/bluetooth.h>
 
@@ -83,6 +84,22 @@ struct monitor {
 	guint attioid;
 };
 
+static GSList *monitors = NULL;
+
+static struct monitor *find_monitor(struct btd_device *device)
+{
+	GSList *l;
+
+	for (l = monitors; l; l = l->next) {
+		struct monitor *monitor = l->data;
+
+		if (monitor->device == device)
+			return monitor;
+	}
+
+	return NULL;
+}
+
 static void write_proximity_config(struct btd_device *device, const char *alert,
 					const char *level)
 {
@@ -580,33 +597,25 @@ static void monitor_destroy(gpointer user_data)
 {
 	struct monitor *monitor = user_data;
 
-	if (monitor->immediateto)
-		g_source_remove(monitor->immediateto);
-
-	if (monitor->attioid)
-		btd_device_remove_attio_callback(monitor->device,
-						monitor->attioid);
-	if (monitor->attrib)
-		g_attrib_unref(monitor->attrib);
-
 	btd_device_unref(monitor->device);
-	g_free(monitor->linkloss);
-	g_free(monitor->immediate);
-	g_free(monitor->txpower);
 	g_free(monitor->linklosslevel);
 	g_free(monitor->immediatelevel);
 	g_free(monitor->signallevel);
 	g_free(monitor);
+
+	monitors = g_slist_remove(monitors, monitor);
 }
 
-int monitor_register(struct btd_device *device,
-		struct gatt_primary *linkloss, struct gatt_primary *txpower,
-		struct gatt_primary *immediate, struct enabled *enabled)
+static struct monitor *register_monitor(struct btd_device *device)
 {
 	const char *path = device_get_path(device);
 	struct monitor *monitor;
 	char *level;
 
+	monitor = find_monitor(device);
+	if (monitor != NULL)
+		return monitor;
+
 	level = read_proximity_config(device, "LinkLossAlertLevel");
 
 	monitor = g_new0(struct monitor, 1);
@@ -615,6 +624,8 @@ int monitor_register(struct btd_device *device,
 	monitor->signallevel = g_strdup("unknown");
 	monitor->immediatelevel = g_strdup("none");
 
+	monitors = g_slist_append(monitors, monitor);
+
 	if (g_dbus_register_interface(btd_get_dbus_connection(), path,
 				PROXIMITY_INTERFACE,
 				NULL, NULL, monitor_device_properties,
@@ -622,55 +633,178 @@ int monitor_register(struct btd_device *device,
 		error("D-Bus failed to register %s interface",
 						PROXIMITY_INTERFACE);
 		monitor_destroy(monitor);
-		return -1;
+		return NULL;
 	}
 
 	DBG("Registered interface %s on path %s", PROXIMITY_INTERFACE, path);
 
-	if (linkloss && enabled->linkloss) {
-		monitor->linkloss = g_new0(struct att_range, 1);
-		monitor->linkloss->start = linkloss->range.start;
-		monitor->linkloss->end = linkloss->range.end;
-
-		monitor->enabled.linkloss = TRUE;
-	}
-
-	if (immediate) {
-		if (txpower && enabled->pathloss) {
-			monitor->txpower = g_new0(struct att_range, 1);
-			monitor->txpower->start = txpower->range.start;
-			monitor->txpower->end = txpower->range.end;
-
-			monitor->enabled.pathloss = TRUE;
-		}
-
-		if (enabled->pathloss || enabled->findme) {
-			monitor->immediate = g_new0(struct att_range, 1);
-			monitor->immediate->start = immediate->range.start;
-			monitor->immediate->end = immediate->range.end;
-		}
+	return monitor;
+}
 
-		monitor->enabled.findme = enabled->findme;
-	}
+static void update_monitor(struct monitor *monitor)
+{
+	if (monitor->txpower != NULL && monitor->immediate != NULL)
+		monitor->enabled.pathloss = TRUE;
+	else
+		monitor->enabled.pathloss = FALSE;
 
 	DBG("Link Loss: %s, Path Loss: %s, FindMe: %s",
 				monitor->enabled.linkloss ? "TRUE" : "FALSE",
 				monitor->enabled.pathloss ? "TRUE" : "FALSE",
 				monitor->enabled.findme ? "TRUE" : "FALSE");
 
-	if (monitor->enabled.linkloss || monitor->enabled.pathloss)
-		monitor->attioid = btd_device_add_attio_callback(device,
+	if (!monitor->enabled.linkloss && !monitor->enabled.pathloss)
+		return;
+
+	if (monitor->attioid != 0)
+		return;
+
+	monitor->attioid = btd_device_add_attio_callback(monitor->device,
 							attio_connected_cb,
 							attio_disconnected_cb,
 							monitor);
+}
+
+int monitor_register_linkloss(struct btd_device *device,
+						struct enabled *enabled,
+						struct gatt_primary *linkloss)
+{
+	struct monitor *monitor;
+
+	if (!enabled->linkloss)
+		return 0;
+
+	monitor = register_monitor(device);
+	if (monitor == NULL)
+		return -1;
+
+	monitor->linkloss = g_new0(struct att_range, 1);
+	monitor->linkloss->start = linkloss->range.start;
+	monitor->linkloss->end = linkloss->range.end;
+	monitor->enabled.linkloss = TRUE;
+
+	update_monitor(monitor);
 
 	return 0;
 }
 
-void monitor_unregister(struct btd_device *device)
+int monitor_register_txpower(struct btd_device *device,
+						struct enabled *enabled,
+						struct gatt_primary *txpower)
 {
+	struct monitor *monitor;
+
+	if (!enabled->pathloss)
+		return 0;
+
+	monitor = register_monitor(device);
+	if (monitor == NULL)
+		return -1;
+
+	monitor->txpower = g_new0(struct att_range, 1);
+	monitor->txpower->start = txpower->range.start;
+	monitor->txpower->end = txpower->range.end;
+
+	update_monitor(monitor);
+
+	return 0;
+}
+
+int monitor_register_immediate(struct btd_device *device,
+						struct enabled *enabled,
+						struct gatt_primary *immediate)
+{
+	struct monitor *monitor;
+
+	if (!enabled->pathloss && !enabled->findme)
+		return 0;
+
+	monitor = register_monitor(device);
+	if (monitor == NULL)
+		return -1;
+
+	monitor->immediate = g_new0(struct att_range, 1);
+	monitor->immediate->start = immediate->range.start;
+	monitor->immediate->end = immediate->range.end;
+	monitor->enabled.findme = enabled->findme;
+
+	update_monitor(monitor);
+
+	return 0;
+}
+
+static void cleanup_monitor(struct monitor *monitor)
+{
+	struct btd_device *device = monitor->device;
 	const char *path = device_get_path(device);
 
+	if (monitor->immediate != NULL || monitor->txpower != NULL)
+		return;
+
+	if (monitor->immediateto != 0) {
+		g_source_remove(monitor->immediateto);
+		monitor->immediateto = 0;
+	}
+
+	if (monitor->linkloss != NULL)
+		return;
+
+	if (monitor->attioid != 0) {
+		btd_device_remove_attio_callback(device, monitor->attioid);
+		monitor->attioid = 0;
+	}
+
+	if (monitor->attrib != NULL) {
+		g_attrib_unref(monitor->attrib);
+		monitor->attrib = NULL;
+	}
+
 	g_dbus_unregister_interface(btd_get_dbus_connection(), path,
 							PROXIMITY_INTERFACE);
 }
+
+void monitor_unregister_linkloss(struct btd_device *device)
+{
+	struct monitor *monitor;
+
+	monitor = find_monitor(device);
+	if (monitor == NULL)
+		return;
+
+	g_free(monitor->linkloss);
+	monitor->linkloss = NULL;
+	monitor->enabled.linkloss = FALSE;
+
+	cleanup_monitor(monitor);
+}
+
+void monitor_unregister_txpower(struct btd_device *device)
+{
+	struct monitor *monitor;
+
+	monitor = find_monitor(device);
+	if (monitor == NULL)
+		return;
+
+	g_free(monitor->txpower);
+	monitor->txpower = NULL;
+	monitor->enabled.pathloss = FALSE;
+
+	cleanup_monitor(monitor);
+}
+
+void monitor_unregister_immediate(struct btd_device *device)
+{
+	struct monitor *monitor;
+
+	monitor = find_monitor(device);
+	if (monitor == NULL)
+		return;
+
+	g_free(monitor->immediate);
+	monitor->immediate = NULL;
+	monitor->enabled.findme = FALSE;
+	monitor->enabled.pathloss = FALSE;
+
+	cleanup_monitor(monitor);
+}
diff --git a/profiles/proximity/monitor.h b/profiles/proximity/monitor.h
index 191b562..d9a40c6 100644
--- a/profiles/proximity/monitor.h
+++ b/profiles/proximity/monitor.h
@@ -28,7 +28,16 @@ struct enabled {
 	gboolean findme;
 };
 
-int monitor_register(struct btd_device *device, struct gatt_primary *linkloss,
-		struct gatt_primary *txpower, struct gatt_primary *immediate,
-		struct enabled *enabled);
-void monitor_unregister(struct btd_device *device);
+int monitor_register_linkloss(struct btd_device *device,
+						struct enabled *enabled,
+						struct gatt_primary *linkloss);
+int monitor_register_txpower(struct btd_device *device,
+						struct enabled *enabled,
+						struct gatt_primary *txpower);
+int monitor_register_immediate(struct btd_device *device,
+						struct enabled *enabled,
+						struct gatt_primary *immediate);
+
+void monitor_unregister_linkloss(struct btd_device *device);
+void monitor_unregister_txpower(struct btd_device *device);
+void monitor_unregister_immediate(struct btd_device *device);
-- 
1.8.1

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux