Diff between 7bfdb32a177fb19a3aaa63fb8963826c89aa4266 and f083aa524223c26911580d583982267d0ef1ae52

Changed Files

File Additions Deletions Status
profiles/thermometer/thermometer.c +70 -64 modified

Full Patch

diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index bcfd241..08503e5 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -59,6 +59,8 @@
 struct thermometer_adapter {
 	struct btd_adapter	*adapter;
 	GSList			*devices;
+	GSList			*fwatchers;	/* Final measurements */
+	GSList			*iwatchers;	/* Intermediate measurements */
 };
 
 struct thermometer {
@@ -70,8 +72,6 @@ struct thermometer {
 	guint				attindid;	/* Att incications id */
 	guint				attnotid;	/* Att notif id */
 	GSList				*chars;		/* Characteristics */
-	GSList				*fwatchers;     /* Final measurements */
-	GSList				*iwatchers;     /* Intermediate meas  */
 	gboolean			intermediate;
 	uint8_t				type;
 	uint16_t			interval;
@@ -94,10 +94,10 @@ struct descriptor {
 };
 
 struct watcher {
-	struct thermometer	*t;
-	guint			id;
-	char			*srv;
-	char			*path;
+	struct thermometer_adapter	*tadapter;
+	guint				id;
+	char				*srv;
+	char				*path;
 };
 
 struct measurement {
@@ -182,9 +182,6 @@ static void destroy_thermometer(gpointer user_data)
 	if (t->chars != NULL)
 		g_slist_free_full(t->chars, destroy_char);
 
-	if (t->fwatchers != NULL)
-		g_slist_free_full(t->fwatchers, remove_watcher);
-
 	btd_device_unref(t->dev);
 	g_free(t->svc_range);
 	g_free(t);
@@ -197,6 +194,9 @@ static void destroy_thermometer_adapter(gpointer user_data)
 	if (tadapter->devices != NULL)
 		g_slist_free_full(tadapter->devices, destroy_thermometer);
 
+	if (tadapter->fwatchers != NULL)
+		g_slist_free_full(tadapter->fwatchers, remove_watcher);
+
 	g_free(tadapter);
 }
 
@@ -400,7 +400,7 @@ static void process_thermometer_desc(struct descriptor *desc)
 
 		if (g_strcmp0(ch->attr.uuid,
 					TEMPERATURE_MEASUREMENT_UUID) == 0) {
-			if (g_slist_length(ch->t->fwatchers) == 0)
+			if (g_slist_length(ch->t->tadapter->fwatchers) == 0)
 				return;
 
 			val = GATT_CLIENT_CHARAC_CFG_IND_BIT;
@@ -408,7 +408,7 @@ static void process_thermometer_desc(struct descriptor *desc)
 								"indication");
 		} else if (g_strcmp0(ch->attr.uuid,
 					INTERMEDIATE_TEMPERATURE_UUID) == 0) {
-			if (g_slist_length(ch->t->iwatchers) == 0)
+			if (g_slist_length(ch->t->tadapter->iwatchers) == 0)
 				return;
 
 			val = GATT_CLIENT_CHARAC_CFG_NOTIF_BIT;
@@ -718,8 +718,9 @@ static DBusMessage *set_property(DBusConnection *conn, DBusMessage *msg,
 	return write_attr_interval(t, msg, value);
 }
 
-static void enable_final_measurement(struct thermometer *t)
+static void enable_final_measurement(gpointer data, gpointer user_data)
 {
+	struct thermometer *t = data;
 	struct characteristic *ch;
 	struct descriptor *desc;
 	bt_uuid_t btuuid;
@@ -748,15 +749,16 @@ static void enable_final_measurement(struct thermometer *t)
 	gatt_write_char(t->attrib, desc->handle, atval, 2, measurement_cb, msg);
 }
 
-static void enable_intermediate_measurement(struct thermometer *t)
+static void enable_intermediate_measurement(gpointer data, gpointer user_data)
 {
+	struct thermometer *t = data;
 	struct characteristic *ch;
 	struct descriptor *desc;
 	bt_uuid_t btuuid;
 	uint8_t atval[2];
 	char *msg;
 
-	if (t->attrib == NULL)
+	if (t->attrib == NULL || !t->intermediate)
 		return;
 
 	ch = get_characteristic(t, INTERMEDIATE_TEMPERATURE_UUID);
@@ -778,8 +780,9 @@ static void enable_intermediate_measurement(struct thermometer *t)
 	gatt_write_char(t->attrib, desc->handle, atval, 2, measurement_cb, msg);
 }
 
-static void disable_final_measurement(struct thermometer *t)
+static void disable_final_measurement(gpointer data, gpointer user_data)
 {
+	struct thermometer *t = data;
 	struct characteristic *ch;
 	struct descriptor *desc;
 	bt_uuid_t btuuid;
@@ -808,8 +811,9 @@ static void disable_final_measurement(struct thermometer *t)
 	gatt_write_char(t->attrib, desc->handle, atval, 2, measurement_cb, msg);
 }
 
-static void disable_intermediate_measurement(struct thermometer *t)
+static void disable_intermediate_measurement(gpointer data, gpointer user_data)
 {
+	struct thermometer *t = data;
 	struct characteristic *ch;
 	struct descriptor *desc;
 	bt_uuid_t btuuid;
@@ -838,31 +842,34 @@ static void disable_intermediate_measurement(struct thermometer *t)
 	gatt_write_char(t->attrib, desc->handle, atval, 2, measurement_cb, msg);
 }
 
-static void remove_int_watcher(struct thermometer *t, struct watcher *w)
+static void remove_int_watcher(struct thermometer_adapter *tadapter,
+							struct watcher *w)
 {
-	if (!g_slist_find(t->iwatchers, w))
+	if (!g_slist_find(tadapter->iwatchers, w))
 		return;
 
-	t->iwatchers = g_slist_remove(t->iwatchers, w);
+	tadapter->iwatchers = g_slist_remove(tadapter->iwatchers, w);
 
-	if (g_slist_length(t->iwatchers) == 0)
-		disable_intermediate_measurement(t);
+	if (g_slist_length(tadapter->iwatchers) == 0)
+		g_slist_foreach(tadapter->devices,
+					disable_intermediate_measurement, 0);
 }
 
 static void watcher_exit(DBusConnection *conn, void *user_data)
 {
 	struct watcher *watcher = user_data;
-	struct thermometer *t = watcher->t;
+	struct thermometer_adapter *tadapter = watcher->tadapter;
 
 	DBG("Thermometer watcher %s disconnected", watcher->path);
 
-	remove_int_watcher(t, watcher);
+	remove_int_watcher(tadapter, watcher);
 
-	t->fwatchers = g_slist_remove(t->fwatchers, watcher);
+	tadapter->fwatchers = g_slist_remove(tadapter->fwatchers, watcher);
 	g_dbus_remove_watch(btd_get_dbus_connection(), watcher->id);
 
-	if (g_slist_length(t->fwatchers) == 0)
-		disable_final_measurement(t);
+	if (g_slist_length(tadapter->fwatchers) == 0)
+		g_slist_foreach(tadapter->devices,
+					disable_final_measurement, 0);
 }
 
 static struct watcher *find_watcher(GSList *list, const char *sender,
@@ -888,7 +895,7 @@ static DBusMessage *register_watcher(DBusConnection *conn, DBusMessage *msg,
 								void *data)
 {
 	const char *sender = dbus_message_get_sender(msg);
-	struct thermometer *t = data;
+	struct thermometer_adapter *tadapter = data;
 	struct watcher *watcher;
 	char *path;
 
@@ -896,7 +903,7 @@ static DBusMessage *register_watcher(DBusConnection *conn, DBusMessage *msg,
 							DBUS_TYPE_INVALID))
 		return btd_error_invalid_args(msg);
 
-	watcher = find_watcher(t->fwatchers, sender, path);
+	watcher = find_watcher(tadapter->fwatchers, sender, path);
 	if (watcher != NULL)
 		return btd_error_already_exists(msg);
 
@@ -905,14 +912,14 @@ static DBusMessage *register_watcher(DBusConnection *conn, DBusMessage *msg,
 	watcher = g_new0(struct watcher, 1);
 	watcher->srv = g_strdup(sender);
 	watcher->path = g_strdup(path);
-	watcher->t = t;
+	watcher->tadapter = tadapter;
 	watcher->id = g_dbus_add_disconnect_watch(conn, sender, watcher_exit,
 						watcher, destroy_watcher);
 
-	if (g_slist_length(t->fwatchers) == 0)
-		enable_final_measurement(t);
+	if (g_slist_length(tadapter->fwatchers) == 0)
+		g_slist_foreach(tadapter->devices, enable_final_measurement, 0);
 
-	t->fwatchers = g_slist_prepend(t->fwatchers, watcher);
+	tadapter->fwatchers = g_slist_prepend(tadapter->fwatchers, watcher);
 
 	return dbus_message_new_method_return(msg);
 }
@@ -921,7 +928,7 @@ static DBusMessage *unregister_watcher(DBusConnection *conn, DBusMessage *msg,
 								void *data)
 {
 	const char *sender = dbus_message_get_sender(msg);
-	struct thermometer *t = data;
+	struct thermometer_adapter *tadapter = data;
 	struct watcher *watcher;
 	char *path;
 
@@ -929,19 +936,20 @@ static DBusMessage *unregister_watcher(DBusConnection *conn, DBusMessage *msg,
 							DBUS_TYPE_INVALID))
 		return btd_error_invalid_args(msg);
 
-	watcher = find_watcher(t->fwatchers, sender, path);
+	watcher = find_watcher(tadapter->fwatchers, sender, path);
 	if (watcher == NULL)
 		return btd_error_does_not_exist(msg);
 
 	DBG("Thermometer watcher %s unregistered", path);
 
-	remove_int_watcher(t, watcher);
+	remove_int_watcher(tadapter, watcher);
 
-	t->fwatchers = g_slist_remove(t->fwatchers, watcher);
+	tadapter->fwatchers = g_slist_remove(tadapter->fwatchers, watcher);
 	g_dbus_remove_watch(btd_get_dbus_connection(), watcher->id);
 
-	if (g_slist_length(t->fwatchers) == 0)
-		disable_final_measurement(t);
+	if (g_slist_length(tadapter->fwatchers) == 0)
+		g_slist_foreach(tadapter->devices,
+					disable_final_measurement, 0);
 
 	return dbus_message_new_method_return(msg);
 }
@@ -950,30 +958,28 @@ static DBusMessage *enable_intermediate(DBusConnection *conn, DBusMessage *msg,
 								void *data)
 {
 	const char *sender = dbus_message_get_sender(msg);
-	struct thermometer *t = data;
+	struct thermometer_adapter *ta = data;
 	struct watcher *watcher;
 	char *path;
 
-	if (!t->intermediate)
-		return btd_error_not_supported(msg);
-
 	if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
 							DBUS_TYPE_INVALID))
 		return btd_error_invalid_args(msg);
 
-	watcher = find_watcher(t->fwatchers, sender, path);
+	watcher = find_watcher(ta->fwatchers, sender, path);
 	if (watcher == NULL)
 		return btd_error_does_not_exist(msg);
 
-	if (find_watcher(t->iwatchers, sender, path))
+	if (find_watcher(ta->iwatchers, sender, path))
 		return btd_error_already_exists(msg);
 
 	DBG("Intermediate measurement watcher %s registered", path);
 
-	if (g_slist_length(t->iwatchers) == 0)
-		enable_intermediate_measurement(t);
+	if (g_slist_length(ta->iwatchers) == 0)
+		g_slist_foreach(ta->devices,
+					enable_intermediate_measurement, 0);
 
-	t->iwatchers = g_slist_prepend(t->iwatchers, watcher);
+	ta->iwatchers = g_slist_prepend(ta->iwatchers, watcher);
 
 	return dbus_message_new_method_return(msg);
 }
@@ -982,7 +988,7 @@ static DBusMessage *disable_intermediate(DBusConnection *conn, DBusMessage *msg,
 								void *data)
 {
 	const char *sender = dbus_message_get_sender(msg);
-	struct thermometer *t = data;
+	struct thermometer_adapter *ta = data;
 	struct watcher *watcher;
 	char *path;
 
@@ -990,13 +996,13 @@ static DBusMessage *disable_intermediate(DBusConnection *conn, DBusMessage *msg,
 							DBUS_TYPE_INVALID))
 		return btd_error_invalid_args(msg);
 
-	watcher = find_watcher(t->iwatchers, sender, path);
+	watcher = find_watcher(ta->iwatchers, sender, path);
 	if (watcher == NULL)
 		return btd_error_does_not_exist(msg);
 
 	DBG("Intermediate measurement %s unregistered", path);
 
-	remove_int_watcher(t, watcher);
+	remove_int_watcher(ta, watcher);
 
 	return dbus_message_new_method_return(msg);
 }
@@ -1008,18 +1014,6 @@ static const GDBusMethodTable thermometer_methods[] = {
 	{ GDBUS_ASYNC_METHOD("SetProperty",
 			GDBUS_ARGS({ "name", "s" }, { "value", "v" }), NULL,
 			set_property) },
-	{ GDBUS_METHOD("RegisterWatcher",
-			GDBUS_ARGS({ "agent", "o" }), NULL,
-			register_watcher) },
-	{ GDBUS_METHOD("UnregisterWatcher",
-			GDBUS_ARGS({ "agent", "o" }), NULL,
-			unregister_watcher) },
-	{ GDBUS_METHOD("EnableIntermediateMeasurement",
-			GDBUS_ARGS({ "agent", "o" }), NULL,
-			enable_intermediate) },
-	{ GDBUS_METHOD("DisableIntermediateMeasurement",
-			GDBUS_ARGS({ "agent", "o" }), NULL,
-			disable_intermediate) },
 	{ }
 };
 
@@ -1071,9 +1065,9 @@ static void recv_measurement(struct thermometer *t, struct measurement *m)
 	GSList *wlist;
 
 	if (g_strcmp0(m->value, "Intermediate") == 0)
-		wlist = t->iwatchers;
+		wlist = t->tadapter->iwatchers;
 	else
-		wlist = t->fwatchers;
+		wlist = t->tadapter->fwatchers;
 
 	g_slist_foreach(wlist, update_watcher, m);
 }
@@ -1332,6 +1326,18 @@ void thermometer_unregister(struct btd_device *device)
 }
 
 static const GDBusMethodTable thermometer_manager_methods[] = {
+	{ GDBUS_METHOD("RegisterWatcher",
+			GDBUS_ARGS({ "agent", "o" }), NULL,
+			register_watcher) },
+	{ GDBUS_METHOD("UnregisterWatcher",
+			GDBUS_ARGS({ "agent", "o" }), NULL,
+			unregister_watcher) },
+	{ GDBUS_METHOD("EnableIntermediateMeasurement",
+			GDBUS_ARGS({ "agent", "o" }), NULL,
+			enable_intermediate) },
+	{ GDBUS_METHOD("DisableIntermediateMeasurement",
+			GDBUS_ARGS({ "agent", "o" }), NULL,
+			disable_intermediate) },
 	{ }
 };