Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH v3 07/15] thermometer: Reformat MeasurementReceived description
From: Andrzej Kaczmarek @ 2012-10-09 11:19 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1349781598-22580-1-git-send-email-andrzej.kaczmarek@tieto.com>

MeasurementReceived method description is reformatted to be more
readable and consistent with other API documents.

Special values for Exponent and Mantissa fields specify now only NaN
value as this is only special value defined by HTS specification for
measurement.
---
 doc/thermometer-api.txt | 76 ++++++++++++++++++++++++++++++-------------------
 1 file changed, 46 insertions(+), 30 deletions(-)

diff --git a/doc/thermometer-api.txt b/doc/thermometer-api.txt
index 1828811..a1da2e6 100644
--- a/doc/thermometer-api.txt
+++ b/doc/thermometer-api.txt
@@ -97,33 +97,49 @@ Service		unique name
 Interface	org.bluez.ThermometerWatcher
 Object path	freely definable
 
-Methods		void MeasurementReceived(dict measure)
-
-			This callback gets called when a measure has been
-			scanned	in the thermometer. The Time entry in the dict
-			will be only present if the device supports storing of
-			data. The time value is expressed in seconds since epoch.
-			The value represented is (mantissa) x (10**exponent)
-			See foot note for special values when treating with
-			health devices. The Type entry is only present if the
-			measurement type is known. Otherwise, it is undefined.
-
-			Dict is defined as below:
-			{
-				"Exponent" : int8,
-				"Mantissa" : int32,
-				"Unit" : ("Celsius" or "Fahrenheit"),
-				"Time" : uint64,
-				"Type" : ("Armpit", "Body", "Ear", "Finger",
-					"Intestines", "Mouth", "Rectum", "Toe",
-					"Tympanum"),
-				"Measurement" : ("Final" or "Intermediate"),
-			}
-
-			For special cases, the exponent shall always be zero and
-			the mantissa should be one of following values:
-
-			NRes = -(2**23)
-			NaN = +(2**23-1)
-			INFINITY = (2**23-2)
-			-INFINITY = -(2**23-2)
+Methods		void MeasurementReceived(dict measurement)
+
+			This callback gets called when a measurement has been
+			scanned in the thermometer.
+
+			Measurement:
+
+				int16 Exponent:
+				int32 Mantissa:
+
+					Exponent and Mantissa values as
+					extracted from float value defined by
+					IEEE-11073-20601.
+
+					Measurement value is calculated as
+					(Mantissa) * (10^Exponent)
+
+					For special cases Exponent is set to 0
+					and Mantissa is set to one of following
+					values:
+
+					+(2^23 - 1)	NaN (invalid or missing data)
+					-(2^23)		NRes
+					+(2^23 - 2)	+Infinity
+					-(2^23 - 2)	-Infinity
+
+				string Unit:
+
+					Possible values: "Celsius" or "Fahrenheit"
+
+				uint64 Time (optional):
+
+					Time of measurement, if supported by device.
+					Expressed in seconds since epoch.
+
+				string Type (optional):
+
+					Only present if measurement type is known.
+
+					Possible values: "Armpit", "Body", "Ear",
+						"Finger", "Intestines", "Mouth",
+						"Rectum", "Toe", "Tympanum"
+
+				string Measurement:
+
+					Possible values: "Final" or "Intermediate"
-- 
1.7.11.3


^ permalink raw reply related

* [PATCH v3 06/15] thermometer: Update test script
From: Andrzej Kaczmarek @ 2012-10-09 11:19 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1349781598-22580-1-git-send-email-andrzej.kaczmarek@tieto.com>

---
 test/test-thermometer | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/test/test-thermometer b/test/test-thermometer
index 9216264..2ca260f 100755
--- a/test/test-thermometer
+++ b/test/test-thermometer
@@ -16,9 +16,9 @@ from optparse import OptionParser, make_option
 
 class Watcher(dbus.service.Object):
 	@dbus.service.method("org.bluez.ThermometerWatcher",
-					in_signature="a{sv}", out_signature="")
-	def MeasurementReceived(self, measure):
-		print(measure["Measurement"], " measurement received")
+					in_signature="oa{sv}", out_signature="")
+	def MeasurementReceived(self, device, measure):
+		print("%s measurement received from %s" % (measure["Measurement"], device))
 		print("Exponent: ", measure["Exponent"])
 		print("Mantissa: ", measure["Mantissa"])
 		print("Unit: ", measure["Unit"])
@@ -66,23 +66,23 @@ if __name__ == "__main__":
 	adapter = dbus.Interface(bus.get_object("org.bluez", adapter_path),
 							"org.bluez.Adapter")
 
+	thermometer_manager = dbus.Interface(bus.get_object("org.bluez",
+				adapter_path), "org.bluez.ThermometerManager")
+
 	device_path = adapter.FindDevice(options.address)
 
 	bus.add_signal_receiver(property_changed, bus_name="org.bluez",
 				dbus_interface="org.bluez.Thermometer",
 				signal_name="PropertyChanged")
 
-	thermometer = dbus.Interface(bus.get_object("org.bluez",
-					device_path), "org.bluez.Thermometer")
-
 	path = "/test/watcher"
 	watcher = Watcher(bus, path)
 
-	thermometer.RegisterWatcher(path)
+	thermometer_manager.RegisterWatcher(path)
 
 	if len(args) > 0:
 		if args[0] == "EnableIntermediateMeasurement":
-			thermometer.EnableIntermediateMeasurement(path)
+			thermometer_manager.EnableIntermediateMeasurement(path)
 		else:
 			print("unknown command")
 			sys.exit(1)
-- 
1.7.11.3


^ permalink raw reply related

* [PATCH v3 05/15] thermometer: Update API document
From: Andrzej Kaczmarek @ 2012-10-09 11:19 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1349781598-22580-1-git-send-email-andrzej.kaczmarek@tieto.com>

This patch updates Thermometer API document to reflect changes in
Thermometer interface and introduction of ThermometerManager
interface and fixes minor formatiing inconsistencies.
---
 doc/thermometer-api.txt | 60 +++++++++++++++++++++++++------------------------
 1 file changed, 31 insertions(+), 29 deletions(-)

diff --git a/doc/thermometer-api.txt b/doc/thermometer-api.txt
index 2271270..1828811 100644
--- a/doc/thermometer-api.txt
+++ b/doc/thermometer-api.txt
@@ -1,30 +1,16 @@
 BlueZ D-Bus Thermometer API description
-****************************************
+***************************************
 
 	Santiago Carot-Nemesio <sancane@gmail.com>
 
-Health Thermometer Profile hierarchy
-=====================================
+Health Thermometer Manager hierarchy
+====================================
 
 Service		org.bluez
-Interface	org.bluez.Thermometer
-Object path	[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX
-
-
-Methods		void SetProperty(string name, variant value)
-
-			Changes the value of the specified property. Only
-			read-write properties can be changed. On success
-			this will emit a PropertyChanged signal.
+Interface	org.bluez.ThermometerManager
+Object path	[variable prefix]/{hci0,hci1,...}
 
-			Possible Errors: org.bluez.Error.InvalidArguments
-
-		dict GetProperties()
-
-			Returns all properties for the interface. See the
-			Properties section for the available properties.
-
-		RegisterWatcher(object agent)
+Methods		RegisterWatcher(object agent)
 
 			Registers a watcher to monitor scanned measurements.
 			This agent will be notified about final temperature
@@ -36,30 +22,45 @@ Methods		void SetProperty(string name, variant value)
 
 			Unregisters a watcher.
 
-			Final and intermediate temperatures won't be notified to
-			this agent any more.
-
-			Possible Errors: org.bluez.Error.InvalidArguments
-					org.bluez.Error.NotFound
-
 		EnableIntermediateMeasurement(object agent)
 
 			Enables intermediate measurement notifications for this
-			agent if the thermometer supports it.
+			agent. Intermediate measurements will be enabled only
+			for thermometers which support it.
 
 			Possible Errors: org.bluez.Error.InvalidArguments
-					org.bluez.Error.NotSupported
 
 		DisableIntermediateMeasurement(object agent)
 
 			Disables intermediate measurement notifications for this
-			agent. It will disable notifications in the thermometer
+			agent. It will disable notifications in thermometers
 			when the last agent removes the watcher for intermediate
 			measurements.
 
 			Possible Errors: org.bluez.Error.InvalidArguments
 					org.bluez.Error.NotFound
 
+Health Thermometer Profile hierarchy
+====================================
+
+Service		org.bluez
+Interface	org.bluez.Thermometer
+Object path	[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX
+
+
+Methods		void SetProperty(string name, variant value)
+
+			Changes the value of the specified property. Only
+			read-write properties can be changed. On success
+			this will emit a PropertyChanged signal.
+
+			Possible Errors: org.bluez.Error.InvalidArguments
+
+		dict GetProperties()
+
+			Returns all properties for the interface. See the
+			Properties section for the available properties.
+
 Signals		PropertyChanged(string name, variant value)
 
 			This signal indicates a changed value of the given
@@ -91,6 +92,7 @@ Properties	boolean Intermediate [readonly]
 
 Health Thermometer Watcher hierarchy
 ====================================
+
 Service		unique name
 Interface	org.bluez.ThermometerWatcher
 Object path	freely definable
-- 
1.7.11.3


^ permalink raw reply related

* [PATCH v3 04/15] thermometer: Include remote device information in MeasurementReceived
From: Andrzej Kaczmarek @ 2012-10-09 11:19 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1349781598-22580-1-git-send-email-andrzej.kaczmarek@tieto.com>

Since watchers are now registered per-adapter it's necessary to include
remote device information in MeasurementReceived callback.

This patch adds parameter to MeasurementReceived method which is an
object path to remote device object.
---
 profiles/thermometer/thermometer.c | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index c2d0529..64029b2 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -101,13 +101,14 @@ struct watcher {
 };
 
 struct measurement {
-	int16_t		exp;
-	int32_t		mant;
-	uint64_t	time;
-	gboolean	suptime;
-	char		*unit;
-	char		*type;
-	char		*value;
+	struct thermometer	*t;
+	int16_t			exp;
+	int32_t			mant;
+	uint64_t		time;
+	gboolean		suptime;
+	char			*unit;
+	char			*type;
+	char			*value;
 };
 
 struct tmp_interval_data {
@@ -1027,6 +1028,7 @@ static void update_watcher(gpointer data, gpointer user_data)
 {
 	struct watcher *w = data;
 	struct measurement *m = user_data;
+	const gchar *path = device_get_path(m->t->dev);
 	DBusMessageIter iter;
 	DBusMessageIter dict;
 	DBusMessage *msg;
@@ -1039,6 +1041,8 @@ static void update_watcher(gpointer data, gpointer user_data)
 
 	dbus_message_iter_init_append(msg, &iter);
 
+	dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH , &path);
+
 	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
 			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
 			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
@@ -1064,6 +1068,8 @@ static void recv_measurement(struct thermometer *t, struct measurement *m)
 {
 	GSList *wlist;
 
+	m->t = t;
+
 	if (g_strcmp0(m->value, "Intermediate") == 0)
 		wlist = t->tadapter->iwatchers;
 	else
-- 
1.7.11.3


^ permalink raw reply related

* [PATCH v3 03/15] thermometer: Move watcher logic to adapter interface
From: Andrzej Kaczmarek @ 2012-10-09 11:19 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1349781598-22580-1-git-send-email-andrzej.kaczmarek@tieto.com>

This patch moves watcher related methods to ThermometerManager interface
so watchers can be registered per-adapter instead of per-device.

Final measurement notifications are now enabled on all devices connected
to given adapter when first watcher is registered and disabled when last
watcher is unregistered.

Intermediate measurement notifications are enabled for all devices
connected to given adapter which support this feature.
---
 profiles/thermometer/thermometer.c | 134 +++++++++++++++++++------------------
 1 file changed, 70 insertions(+), 64 deletions(-)

diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index cc5f23f..c2d0529 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);
 }
@@ -1333,6 +1327,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) },
 	{ }
 };
 
-- 
1.7.11.3


^ permalink raw reply related

* [PATCH v3 02/15] thermometer: Register ThermometerManager interface on adapter path
From: Andrzej Kaczmarek @ 2012-10-09 11:19 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1349781598-22580-1-git-send-email-andrzej.kaczmarek@tieto.com>

---
 profiles/thermometer/thermometer.c | 33 ++++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index e98be94..cc5f23f 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -42,7 +42,8 @@
 #include "gatt.h"
 #include "thermometer.h"
 
-#define THERMOMETER_INTERFACE "org.bluez.Thermometer"
+#define THERMOMETER_INTERFACE		"org.bluez.Thermometer"
+#define THERMOMETER_MANAGER_INTERFACE	"org.bluez.ThermometerManager"
 
 /* Temperature measurement flag fields */
 #define TEMP_UNITS		0x01
@@ -189,6 +190,16 @@ static void destroy_thermometer(gpointer user_data)
 	g_free(t);
 }
 
+static void destroy_thermometer_adapter(gpointer user_data)
+{
+	struct thermometer_adapter *tadapter = user_data;
+
+	if (tadapter->devices != NULL)
+		g_slist_free_full(tadapter->devices, destroy_thermometer);
+
+	g_free(tadapter);
+}
+
 static gint cmp_adapter(gconstpointer a, gconstpointer b)
 {
 	const struct thermometer_adapter *tadapter = a;
@@ -1321,6 +1332,10 @@ void thermometer_unregister(struct btd_device *device)
 				device_get_path(t->dev), THERMOMETER_INTERFACE);
 }
 
+static const GDBusMethodTable thermometer_manager_methods[] = {
+	{ }
+};
+
 int thermometer_adapter_register(struct btd_adapter *adapter)
 {
 	struct thermometer_adapter *tadapter;
@@ -1328,6 +1343,18 @@ int thermometer_adapter_register(struct btd_adapter *adapter)
 	tadapter = g_new0(struct thermometer_adapter, 1);
 	tadapter->adapter = adapter;
 
+	if (!g_dbus_register_interface(btd_get_dbus_connection(),
+						adapter_get_path(adapter),
+						THERMOMETER_MANAGER_INTERFACE,
+						thermometer_manager_methods,
+						NULL, NULL, tadapter,
+						destroy_thermometer_adapter)) {
+		error("D-Bus failed to register %s interface",
+						THERMOMETER_MANAGER_INTERFACE);
+		destroy_thermometer_adapter(tadapter);
+		return -EIO;
+	}
+
 	thermometer_adapters = g_slist_prepend(thermometer_adapters, tadapter);
 
 	return 0;
@@ -1342,4 +1369,8 @@ void thermometer_adapter_unregister(struct btd_adapter *adapter)
 		return;
 
 	thermometer_adapters = g_slist_remove(thermometer_adapters, tadapter);
+
+	g_dbus_unregister_interface(btd_get_dbus_connection(),
+					adapter_get_path(tadapter->adapter),
+					THERMOMETER_MANAGER_INTERFACE);
 }
-- 
1.7.11.3


^ permalink raw reply related

* [PATCH v3 01/15] thermometer: Store thermometer devices per-adapter
From: Andrzej Kaczmarek @ 2012-10-09 11:19 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1349781598-22580-1-git-send-email-andrzej.kaczmarek@tieto.com>

This patch replaces global list of thermometer devices with per-adapter
lists.
---
 profiles/thermometer/manager.c     |  16 +++++-
 profiles/thermometer/thermometer.c | 114 ++++++++++++++++++++++++++++++-------
 profiles/thermometer/thermometer.h |   2 +
 3 files changed, 110 insertions(+), 22 deletions(-)

diff --git a/profiles/thermometer/manager.c b/profiles/thermometer/manager.c
index d965976..86e3a0f 100644
--- a/profiles/thermometer/manager.c
+++ b/profiles/thermometer/manager.c
@@ -66,11 +66,25 @@ static void thermometer_driver_remove(struct btd_profile *p,
 	thermometer_unregister(device);
 }
 
+static int thermometer_adapter_probe(struct btd_profile *p,
+						struct btd_adapter *adapter)
+{
+	return thermometer_adapter_register(adapter);
+}
+
+static void thermometer_adapter_remove(struct btd_profile *p,
+						struct btd_adapter *adapter)
+{
+	thermometer_adapter_unregister(adapter);
+}
+
 static struct btd_profile thermometer_profile = {
 	.name		= "thermometer-device-driver",
 	.remote_uuids	= BTD_UUIDS(HEALTH_THERMOMETER_UUID),
 	.device_probe	= thermometer_driver_probe,
-	.device_remove	= thermometer_driver_remove
+	.device_remove	= thermometer_driver_remove,
+	.adapter_probe	= thermometer_adapter_probe,
+	.adapter_remove	= thermometer_adapter_remove
 };
 
 int thermometer_manager_init(void)
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index 3506ba7..e98be94 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -55,23 +55,29 @@
 #define TEMPERATURE_TYPE_SIZE	1
 #define MEASUREMENT_INTERVAL_SIZE	2
 
+struct thermometer_adapter {
+	struct btd_adapter	*adapter;
+	GSList			*devices;
+};
+
 struct thermometer {
-	struct btd_device	*dev;		/* Device reference */
-	GAttrib			*attrib;	/* GATT connection */
-	struct att_range	*svc_range;	/* Thermometer range */
-	guint			attioid;	/* Att watcher id */
-	guint			attindid;	/* Att incications id */
-	guint			attnotid;	/* Att notifications id */
-	GSList			*chars;		/* Characteristics */
-	GSList			*fwatchers;     /* Final measurements */
-	GSList			*iwatchers;     /* Intermediate measurements */
-	gboolean		intermediate;
-	uint8_t			type;
-	uint16_t		interval;
-	uint16_t		max;
-	uint16_t		min;
-	gboolean		has_type;
-	gboolean		has_interval;
+	struct btd_device		*dev;		/* Device reference */
+	struct thermometer_adapter	*tadapter;
+	GAttrib				*attrib;	/* GATT connection */
+	struct att_range		*svc_range;	/* Thermometer range */
+	guint				attioid;	/* Att watcher id */
+	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;
+	uint16_t			max;
+	uint16_t			min;
+	gboolean			has_type;
+	gboolean			has_interval;
 };
 
 struct characteristic {
@@ -108,7 +114,7 @@ struct tmp_interval_data {
 	uint16_t		interval;
 };
 
-static GSList *thermometers = NULL;
+static GSList *thermometer_adapters = NULL;
 
 const char *temp_type[] = {
 	"<reserved>",
@@ -183,6 +189,17 @@ static void destroy_thermometer(gpointer user_data)
 	g_free(t);
 }
 
+static gint cmp_adapter(gconstpointer a, gconstpointer b)
+{
+	const struct thermometer_adapter *tadapter = a;
+	const struct btd_adapter *adapter = b;
+
+	if (adapter == tadapter->adapter)
+		return 0;
+
+	return -1;
+}
+
 static gint cmp_device(gconstpointer a, gconstpointer b)
 {
 	const struct thermometer *t = a;
@@ -231,6 +248,17 @@ static gint cmp_descriptor(gconstpointer a, gconstpointer b)
 	return bt_uuid_cmp(&desc->uuid, uuid);
 }
 
+static struct thermometer_adapter *
+find_thermometer_adapter(struct btd_adapter *adapter)
+{
+	GSList *l = g_slist_find_custom(thermometer_adapters, adapter,
+								cmp_adapter);
+	if (!l)
+		return NULL;
+
+	return l->data;
+}
+
 static struct characteristic *get_characteristic(struct thermometer *t,
 							const char *uuid)
 {
@@ -1233,13 +1261,25 @@ int thermometer_register(struct btd_device *device, struct gatt_primary *tattr)
 {
 	const gchar *path = device_get_path(device);
 	struct thermometer *t;
+	struct btd_adapter *adapter;
+	struct thermometer_adapter *tadapter;
+
+	adapter = device_get_adapter(device);
+
+	tadapter = find_thermometer_adapter(adapter);
+
+	if (tadapter == NULL)
+		return -1;
 
 	t = g_new0(struct thermometer, 1);
 	t->dev = btd_device_ref(device);
+	t->tadapter = tadapter;
 	t->svc_range = g_new0(struct att_range, 1);
 	t->svc_range->start = tattr->range.start;
 	t->svc_range->end = tattr->range.end;
 
+	tadapter->devices = g_slist_prepend(tadapter->devices, t);
+
 	if (!g_dbus_register_interface(btd_get_dbus_connection(),
 				path, THERMOMETER_INTERFACE,
 				thermometer_methods, thermometer_signals,
@@ -1250,8 +1290,6 @@ int thermometer_register(struct btd_device *device, struct gatt_primary *tattr)
 		return -EIO;
 	}
 
-	thermometers = g_slist_prepend(thermometers, t);
-
 	t->attioid = btd_device_add_attio_callback(device, attio_connected_cb,
 						attio_disconnected_cb, t);
 	return 0;
@@ -1260,14 +1298,48 @@ int thermometer_register(struct btd_device *device, struct gatt_primary *tattr)
 void thermometer_unregister(struct btd_device *device)
 {
 	struct thermometer *t;
+	struct btd_adapter *adapter;
+	struct thermometer_adapter *tadapter;
 	GSList *l;
 
-	l = g_slist_find_custom(thermometers, device, cmp_device);
+	adapter = device_get_adapter(device);
+
+	tadapter = find_thermometer_adapter(adapter);
+
+	if (tadapter == NULL)
+		return;
+
+	l = g_slist_find_custom(tadapter->devices, device, cmp_device);
 	if (l == NULL)
 		return;
 
 	t = l->data;
-	thermometers = g_slist_remove(thermometers, t);
+
+	tadapter->devices = g_slist_remove(tadapter->devices, t);
+
 	g_dbus_unregister_interface(btd_get_dbus_connection(),
 				device_get_path(t->dev), THERMOMETER_INTERFACE);
 }
+
+int thermometer_adapter_register(struct btd_adapter *adapter)
+{
+	struct thermometer_adapter *tadapter;
+
+	tadapter = g_new0(struct thermometer_adapter, 1);
+	tadapter->adapter = adapter;
+
+	thermometer_adapters = g_slist_prepend(thermometer_adapters, tadapter);
+
+	return 0;
+}
+
+void thermometer_adapter_unregister(struct btd_adapter *adapter)
+{
+	struct thermometer_adapter *tadapter;
+
+	tadapter = find_thermometer_adapter(adapter);
+	if (tadapter == NULL)
+		return;
+
+	thermometer_adapters = g_slist_remove(thermometer_adapters, tadapter);
+}
diff --git a/profiles/thermometer/thermometer.h b/profiles/thermometer/thermometer.h
index 2744ed6..ca83c31 100644
--- a/profiles/thermometer/thermometer.h
+++ b/profiles/thermometer/thermometer.h
@@ -22,3 +22,5 @@
 
 int thermometer_register(struct btd_device *device, struct gatt_primary *tattr);
 void thermometer_unregister(struct btd_device *device);
+int thermometer_adapter_register(struct btd_adapter *adapter);
+void thermometer_adapter_unregister(struct btd_adapter *adapter);
-- 
1.7.11.3


^ permalink raw reply related

* [PATCH v3 00/15] Thermometer watchers API change + fixes
From: Andrzej Kaczmarek @ 2012-10-09 11:19 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Andrzej Kaczmarek

Hi,

Changes since v2:
- restored special values for exponent and mantissa in API document
  and added note about IEEE spec
- fixed parameters parsing for incoming measurement (memset was placed
  in wrong place)

Also this was tested with PTS 4.5.3 and works fine now after memset fix,
except for TP/THF/CO/BI-07-I which seems to have issue in PTS (there should
be reserved value for temperature type but PTS sends 0x02 which is
perfectly valid value thus it won't be discarded on our side).


Andrzej Kaczmarek (15):
  thermometer: Store thermometer devices per-adapter
  thermometer: Register ThermometerManager interface on adapter path
  thermometer: Move watcher logic to adapter interface
  thermometer: Include remote device information in MeasurementReceived
  thermometer: Update API document
  thermometer: Update test script
  thermometer: Reformat MeasurementReceived description
  thermometer: Change string properties to lower-case
  thermometer: Update driver naming style
  thermometer: Add constant definition for watcher interface name
  thermometer: Add common function to write characteristics CCC
  thermometer: Refactor processing of measurement characteristic value
  thermometer: Fix whitespace
  thermometer: Fix indentation
  thermometer: Fix missing braces

 doc/thermometer-api.txt            | 136 +++++-----
 profiles/thermometer/manager.c     |  24 +-
 profiles/thermometer/thermometer.c | 512 +++++++++++++++++++++----------------
 profiles/thermometer/thermometer.h |   2 +
 test/test-thermometer              |  16 +-
 5 files changed, 395 insertions(+), 295 deletions(-)

-- 
1.7.11.3


^ permalink raw reply

* Re: [PATCH BlueZ 1/8] adapter: Add DBus.Properties getters
From: Johan Hedberg @ 2012-10-09 10:46 UTC (permalink / raw)
  To: Lucas De Marchi; +Cc: linux-bluetooth, Lucas De Marchi
In-Reply-To: <1349769596-6050-1-git-send-email-lucas.demarchi@profusion.mobi>

Hi Lucas,

On Tue, Oct 09, 2012, Lucas De Marchi wrote:
> ---
>  src/adapter.c | 221 +++++++++++++++++++++++++++++++++++++++-------------------
>  1 file changed, 149 insertions(+), 72 deletions(-)

All of these patches have been applied. I also pushed three other
patches to convert list-devices, test-adapter and test-device to support
the new interfaces.

Johan

^ permalink raw reply

* Re: [PATCH 1/3] client: Add implementation for UpdateInbox
From: Venkateswaran, Srinivasa Ragavan @ 2012-10-09 10:16 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <CABBYNZ+xJuGLTmYdDCVXkxa4ut1XuF7OGdDUTCU5-acqkBE8yA@mail.gmail.com>

Hi Luiz

On Tue, Oct 9, 2012 at 2:44 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> Hi Srinivasa,
>
> On Sat, Oct 6, 2012 at 3:52 PM, Srinivasa Ragavan
> <srinivasa.ragavan.venkateswaran@intel.com> wrote:
>> ---
>>  client/map.c |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 58 insertions(+)
>>
>> diff --git a/client/map.c b/client/map.c
>> index 290eaae..c0a5bfc 100644
>> --- a/client/map.c
>> +++ b/client/map.c
>> @@ -1242,6 +1242,60 @@ static DBusMessage *map_list_filter_fields(DBusConnection *connection,
>>         return reply;
>>  }
>>
>> +static void update_inbox_cb(struct obc_session *session,
>> +                        struct obc_transfer *transfer,
>> +                        GError *err, void *user_data)
>> +{
>> +       struct map_data *map = user_data;
>> +       DBusMessage *reply;
>> +
>> +       if (err != NULL) {
>> +               reply = g_dbus_create_error(map->msg,
>> +                                               ERROR_INTERFACE ".Failed",
>> +                                               "%s", err->message);
>> +               goto done;
>> +       }
>> +
>> +       reply = dbus_message_new_method_return(map->msg);
>> +
>> +done:
>> +       g_dbus_send_message(conn, reply);
>> +       dbus_message_unref(map->msg);
>> +}
>> +
>> +static DBusMessage *map_update_inbox(DBusConnection *connection,
>> +                                 DBusMessage *message, void *user_data)
>> +{
>> +       struct map_data *map = user_data;
>> +       DBusMessage *reply;
>> +       char contents[2];
>> +       struct obc_transfer *transfer;
>> +       GError *err = NULL;
>> +
>> +       contents[0] = FILLER_BYTE;
>> +       contents[1] = '\0';
>> +
>> +       transfer = obc_transfer_put("x-bt/MAP-messageUpdate", NULL, NULL,
>> +                                                       contents,
>> +                                                       sizeof(contents), &err);
>> +       if (transfer == NULL)
>> +               goto fail;
>> +
>> +       if (!obc_session_queue(map->session, transfer,
>> +                              update_inbox_cb, map, &err))
>> +               goto fail;
>> +
>> +       map->msg = dbus_message_ref(message);
>> +
>> +       return NULL;
>> +
>> +fail:
>> +       reply = g_dbus_create_error(message, ERROR_INTERFACE ".Failed", "%s",
>> +                                                               err->message);
>> +       g_error_free(err);
>> +       return reply;
>> +}
>> +
>>  static const GDBusMethodTable map_methods[] = {
>>         { GDBUS_ASYNC_METHOD("SetFolder",
>>                                 GDBUS_ARGS({ "name", "s" }), NULL,
>> @@ -1258,6 +1312,10 @@ static const GDBusMethodTable map_methods[] = {
>>                         NULL,
>>                         GDBUS_ARGS({ "fields", "as" }),
>>                         map_list_filter_fields) },
>> +       { GDBUS_ASYNC_METHOD("UpdateInbox",
>> +                       NULL,
>> +                       NULL,
>> +                       map_update_inbox) },
>>         { }
>>  };
>>
>> --
>> 1.7.10.4
>
> These patches are now upstream, Ive made some codestyle changes
> because we don't use spaces to align on multilines but checkpatch
> don't seem to catch those are they are no really mandatory on kernel.

I'll be careful from here on. Thx for working it up.

-Srini.

^ permalink raw reply

* Re: [PATCH 1/3] client: Add implementation for UpdateInbox
From: Luiz Augusto von Dentz @ 2012-10-09  9:14 UTC (permalink / raw)
  To: Srinivasa Ragavan; +Cc: linux-bluetooth
In-Reply-To: <1349531535-706-1-git-send-email-srinivasa.ragavan.venkateswaran@intel.com>

Hi Srinivasa,

On Sat, Oct 6, 2012 at 3:52 PM, Srinivasa Ragavan
<srinivasa.ragavan.venkateswaran@intel.com> wrote:
> ---
>  client/map.c |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 58 insertions(+)
>
> diff --git a/client/map.c b/client/map.c
> index 290eaae..c0a5bfc 100644
> --- a/client/map.c
> +++ b/client/map.c
> @@ -1242,6 +1242,60 @@ static DBusMessage *map_list_filter_fields(DBusConnection *connection,
>         return reply;
>  }
>
> +static void update_inbox_cb(struct obc_session *session,
> +                        struct obc_transfer *transfer,
> +                        GError *err, void *user_data)
> +{
> +       struct map_data *map = user_data;
> +       DBusMessage *reply;
> +
> +       if (err != NULL) {
> +               reply = g_dbus_create_error(map->msg,
> +                                               ERROR_INTERFACE ".Failed",
> +                                               "%s", err->message);
> +               goto done;
> +       }
> +
> +       reply = dbus_message_new_method_return(map->msg);
> +
> +done:
> +       g_dbus_send_message(conn, reply);
> +       dbus_message_unref(map->msg);
> +}
> +
> +static DBusMessage *map_update_inbox(DBusConnection *connection,
> +                                 DBusMessage *message, void *user_data)
> +{
> +       struct map_data *map = user_data;
> +       DBusMessage *reply;
> +       char contents[2];
> +       struct obc_transfer *transfer;
> +       GError *err = NULL;
> +
> +       contents[0] = FILLER_BYTE;
> +       contents[1] = '\0';
> +
> +       transfer = obc_transfer_put("x-bt/MAP-messageUpdate", NULL, NULL,
> +                                                       contents,
> +                                                       sizeof(contents), &err);
> +       if (transfer == NULL)
> +               goto fail;
> +
> +       if (!obc_session_queue(map->session, transfer,
> +                              update_inbox_cb, map, &err))
> +               goto fail;
> +
> +       map->msg = dbus_message_ref(message);
> +
> +       return NULL;
> +
> +fail:
> +       reply = g_dbus_create_error(message, ERROR_INTERFACE ".Failed", "%s",
> +                                                               err->message);
> +       g_error_free(err);
> +       return reply;
> +}
> +
>  static const GDBusMethodTable map_methods[] = {
>         { GDBUS_ASYNC_METHOD("SetFolder",
>                                 GDBUS_ARGS({ "name", "s" }), NULL,
> @@ -1258,6 +1312,10 @@ static const GDBusMethodTable map_methods[] = {
>                         NULL,
>                         GDBUS_ARGS({ "fields", "as" }),
>                         map_list_filter_fields) },
> +       { GDBUS_ASYNC_METHOD("UpdateInbox",
> +                       NULL,
> +                       NULL,
> +                       map_update_inbox) },
>         { }
>  };
>
> --
> 1.7.10.4

These patches are now upstream, Ive made some codestyle changes
because we don't use spaces to align on multilines but checkpatch
don't seem to catch those are they are no really mandatory on kernel.

-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH v4 BlueZ 1/4] gatt: Add support for find included services
From: Johan Hedberg @ 2012-10-09  8:57 UTC (permalink / raw)
  To: Vinicius Costa Gomes; +Cc: linux-bluetooth
In-Reply-To: <1349741858-18325-1-git-send-email-vinicius.gomes@openbossa.org>

Hi Vinicius,

On Mon, Oct 08, 2012, Vinicius Costa Gomes wrote:
> Some services like HID over LE can reference another service using
> included services.
> 
> See Vol 3, Part G, section 2.6.3 of Core specification for more
> details.
> ---
>  attrib/gatt.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  attrib/gatt.h |   9 +++
>  2 files changed, 201 insertions(+)

All patches in this set have been applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH resend] net, bluetooth: don't attempt to free a channel that wasn't created
From: Gustavo Padovan @ 2012-10-09  8:57 UTC (permalink / raw)
  To: Sasha Levin
  Cc: marcel, johan.hedberg, davem, linux-bluetooth, davej, netdev,
	linux-kernel, levinsasha928
In-Reply-To: <1349729312-14259-1-git-send-email-sasha.levin@oracle.com>

Hi Sasha,

* Sasha Levin <sasha.levin@oracle.com> [2012-10-08 16:48:32 -0400]:

> We may currently attempt to free a channel which wasn't created due to
> an error in the initialization path, this would cause a NULL ptr deref.
> 
> This would cause the following oops:
> 
> [   12.919073] BUG: unable to handle kernel NULL pointer dereference at 0000000000000010
> [   12.919131] IP: [<ffffffff836645c4>] l2cap_chan_put+0x34/0x50
> [   12.919135] PGD 0
> [   12.919138] Oops: 0002 [#1] PREEMPT SMP DEBUG_PAGEALLOC
> [   12.919193] Dumping ftrace buffer:
> [   12.919242]    (ftrace buffer empty)
> [   12.919314] Modules linked in:
> [   12.919318] CPU 1
> [   12.919319] Pid: 6210, comm: krfcommd Tainted: G        W    3.6.0-next-20121004-sasha-00005-gb010653-dirty #30
> [   12.919374] RIP: 0010:[<ffffffff836645c4>]  [<ffffffff836645c4>] l2cap_chan_put+0x34/0x50
> [   12.919377] RSP: 0000:ffff880066933c38  EFLAGS: 00010246
> [   12.919378] RAX: ffffffff8366c780 RBX: 0000000000000000 RCX: 6666666666666667
> [   12.919379] RDX: 0000000000000fa0 RSI: ffffffff84d3f79e RDI: 0000000000000010
> [   12.919381] RBP: ffff880066933c48 R08: ffffffff859989f8 R09: 0000000000000001
> [   12.919382] R10: 0000000000000000 R11: 7fffffffffffffff R12: 0000000000000000
> [   12.919383] R13: ffff88009b00a200 R14: ffff88009b00a200 R15: 0000000000000001
> [   12.919385] FS:  0000000000000000(0000) GS:ffff880033600000(0000) knlGS:0000000000000000
> [   12.919437] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [   12.919440] CR2: 0000000000000010 CR3: 0000000005026000 CR4: 00000000000406e0
> [   12.919446] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> [   12.919451] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> [   12.919504] Process krfcommd (pid: 6210, threadinfo ffff880066932000, task ffff880065c4b000)
> [   12.919506] Stack:
> [   12.919510]  ffff88009b00a200 ffff880032084000 ffff880066933c68 ffffffff8366c7bc
> [   12.919513]  7fffffffffffffff ffff880032084000 ffff880066933c98 ffffffff833ae0ae
> [   12.919516]  ffff880066933ca8 0000000000000000 0000000000000000 ffff88009b00a200
> [   12.919517] Call Trace:
> [   12.919522]  [<ffffffff8366c7bc>] l2cap_sock_destruct+0x3c/0x80
> [   12.919527]  [<ffffffff833ae0ae>] __sk_free+0x1e/0x1f0
> [   12.919530]  [<ffffffff833ae2f7>] sk_free+0x17/0x20
> [   12.919585]  [<ffffffff8366ca4e>] l2cap_sock_alloc.constprop.5+0x9e/0xd0
> [   12.919591]  [<ffffffff8366cb9e>] l2cap_sock_create+0x7e/0x100
> [   12.919652]  [<ffffffff83a4f32a>] ? _raw_read_lock+0x6a/0x80
> [   12.919658]  [<ffffffff836402c4>] ? bt_sock_create+0x74/0x110
> [   12.919660]  [<ffffffff83640308>] bt_sock_create+0xb8/0x110
> [   12.919664]  [<ffffffff833aa232>] __sock_create+0x282/0x3b0
> [   12.919720]  [<ffffffff833aa0b0>] ? __sock_create+0x100/0x3b0
> [   12.919725]  [<ffffffff836785b0>] ? rfcomm_process_sessions+0x17e0/0x17e0
> [   12.919779]  [<ffffffff833aa37f>] sock_create_kern+0x1f/0x30
> [   12.919784]  [<ffffffff83675714>] rfcomm_l2sock_create+0x44/0x70
> [   12.919787]  [<ffffffff836785b0>] ? rfcomm_process_sessions+0x17e0/0x17e0
> [   12.919790]  [<ffffffff836785fe>] rfcomm_run+0x4e/0x1f0
> [   12.919846]  [<ffffffff836785b0>] ? rfcomm_process_sessions+0x17e0/0x17e0
> [   12.919852]  [<ffffffff81138ee3>] kthread+0xe3/0xf0
> [   12.919908]  [<ffffffff8117b12e>] ? put_lock_stats.isra.14+0xe/0x40
> [   12.919914]  [<ffffffff81138e00>] ? flush_kthread_work+0x1f0/0x1f0
> [   12.919968]  [<ffffffff83a5077c>] ret_from_fork+0x7c/0x90
> [   12.919973]  [<ffffffff81138e00>] ? flush_kthread_work+0x1f0/0x1f0
> [   12.920161] Code: 83 ec 08 f6 05 ff 58 44 02 04 74 1b 8b 4f 10 48 89 fa 48 c7 c6 d9 d7 d4 84 48 c7 c7 80 9e aa 85 31 c0 e8 80
> ac 3a fe 48 8d 7b 10 <f0> 83 6b 10 01 0f 94 c0 84 c0 74 05 e8 8b e0 ff ff 48 83 c4 08
> [   12.920165] RIP  [<ffffffff836645c4>] l2cap_chan_put+0x34/0x50
> [   12.920166]  RSP <ffff880066933c38>
> [   12.920167] CR2: 0000000000000010
> [   12.920417] ---[ end trace 5a9114e8a158ab84 ]---
> 
> Introduced in commit 61d6ef3e ("Bluetooth: Make better use of l2cap_chan
> reference counting").
> 
> Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
> ---
>  net/bluetooth/l2cap_sock.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Patch has been applied to bluetooth-next. Thanks.

	Gustavo

^ permalink raw reply

* Re: [PATCH BlueZ] Fix registering HoG service for non-HoG profiles
From: Johan Hedberg @ 2012-10-09  8:53 UTC (permalink / raw)
  To: Vinicius Costa Gomes; +Cc: linux-bluetooth
In-Reply-To: <1349741074-16665-1-git-send-email-vinicius.gomes@openbossa.org>

Hi Vinicius,

On Mon, Oct 08, 2012, Vinicius Costa Gomes wrote:
> We need to handle the case that the device has multiple HoG services,
> but before registering we must check the service UUID.
> ---
>  profiles/input/hog_manager.c | 3 +++
>  1 file changed, 3 insertions(+)

Applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH BlueZ] service: Fix passing stack variable as reference value
From: Johan Hedberg @ 2012-10-09  8:53 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1349726904-5381-1-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Mon, Oct 08, 2012, Luiz Augusto von Dentz wrote:
> BDADDR_ANY cannot be return as it uses stack allocation:
> 
> Conditional jump or move depends on uninitialised value(s)
>    at 0x170E47: sdp_record_remove (sdpd-database.c:269)
>    by 0x17071A: remove_record_from_server (sdpd-service.c:290)
>    by 0x14D416: exit_callback (service.c:131)
>    by 0x124396: service_filter (watch.c:486)
>    by 0x12405A: message_filter (watch.c:554)
>    by 0x4F63A35: dbus_connection_dispatch (in /usr/lib64/libdbus-1.so.3.5.6)
>    by 0x122EE7: message_dispatch (mainloop.c:76)
>    by 0x4C7B3BA: ??? (in /usr/lib64/libglib-2.0.so.0.3200.4)
>    by 0x4C7A824: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3200.4)
>    by 0x4C7AB57: ??? (in /usr/lib64/libglib-2.0.so.0.3200.4)
>    by 0x4C7AF51: g_main_loop_run (in /usr/lib64/libglib-2.0.so.0.3200.4)
>    by 0x1225B1: main (main.c:551)
>  Uninitialised value was created by a stack allocation
>    at 0x1705B0: add_record_to_server (sdpd-service.c:235)
> 
> Conditional jump or move depends on uninitialised value(s)
>    at 0x4A0AD21: bcmp (mc_replace_strmem.c:889)
>    by 0x4C959E0: g_slist_find_custom (in /usr/lib64/libglib-2.0.so.0.3200.4)
>    by 0x17C059: manager_find_adapter (manager.c:291)
>    by 0x170E8F: sdp_record_remove (sdpd-database.c:270)
>    by 0x17071A: remove_record_from_server (sdpd-service.c:290)
>    by 0x14D416: exit_callback (service.c:131)
>    by 0x124396: service_filter (watch.c:486)
>    by 0x12405A: message_filter (watch.c:554)
>    by 0x4F63A35: dbus_connection_dispatch (in /usr/lib64/libdbus-1.so.3.5.6)
>    by 0x122EE7: message_dispatch (mainloop.c:76)
>    by 0x4C7B3BA: ??? (in /usr/lib64/libglib-2.0.so.0.3200.4)
>    by 0x4C7A824: g_main_context_dispatch (in /usr/lib64/libglib-2.0.so.0.3200.4)
>  Uninitialised value was created by a stack allocation
>    at 0x1705B0: add_record_to_server (sdpd-service.c:235)
> ---
>  plugins/service.c | 10 ++--------
>  1 file changed, 2 insertions(+), 8 deletions(-)

Applied. Thanks.

Johan

^ permalink raw reply

* [PATCH BlueZ 8/8] adapter: Emit signals through DBus.Properties
From: Lucas De Marchi @ 2012-10-09  7:59 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lucas De Marchi
In-Reply-To: <1349769596-6050-1-git-send-email-lucas.demarchi@profusion.mobi>

From: Lucas De Marchi <lucas.de.marchi@gmail.com>

---
 src/adapter.c | 142 +++++++++++++++++++---------------------------------------
 1 file changed, 47 insertions(+), 95 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 18689c6..6b28651 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -470,9 +470,8 @@ void btd_adapter_pairable_changed(struct btd_adapter *adapter,
 
 	write_device_pairable(&adapter->bdaddr, pairable);
 
-	emit_property_changed(adapter->path,
-				ADAPTER_INTERFACE, "Pairable",
-				DBUS_TYPE_BOOLEAN, &pairable);
+	g_dbus_emit_property_changed(btd_get_dbus_connection(), adapter->path,
+					ADAPTER_INTERFACE, "Pairable");
 
 	if (pairable && adapter->pairable_timeout)
 		adapter_set_pairable_timeout(adapter,
@@ -736,9 +735,8 @@ void btd_adapter_class_changed(struct btd_adapter *adapter, uint8_t *new_class)
 		attrib_gap_set(adapter, GATT_CHARAC_APPEARANCE, cls, 2);
 	}
 
-	emit_property_changed(adapter->path,
-				ADAPTER_INTERFACE, "Class",
-				DBUS_TYPE_UINT32, &class);
+	g_dbus_emit_property_changed(btd_get_dbus_connection(), adapter->path,
+						ADAPTER_INTERFACE, "Class");
 }
 
 void adapter_name_changed(struct btd_adapter *adapter, const char *name)
@@ -830,52 +828,6 @@ struct btd_device *adapter_find_device(struct btd_adapter *adapter,
 	return device;
 }
 
-static void adapter_update_devices(struct btd_adapter *adapter)
-{
-	char **devices;
-	int i;
-	GSList *l;
-
-	/* Devices */
-	devices = g_new0(char *, g_slist_length(adapter->devices) + 1);
-	for (i = 0, l = adapter->devices; l; l = l->next, i++) {
-		struct btd_device *dev = l->data;
-		devices[i] = (char *) device_get_path(dev);
-	}
-
-	emit_array_property_changed(adapter->path,
-					ADAPTER_INTERFACE, "Devices",
-					DBUS_TYPE_OBJECT_PATH, &devices, i);
-	g_free(devices);
-}
-
-static void adapter_emit_uuids_updated(struct btd_adapter *adapter)
-{
-	char **uuids;
-	int i;
-	sdp_list_t *list;
-
-	if (!adapter->initialized)
-		return;
-
-	uuids = g_new0(char *, sdp_list_len(adapter->services) + 1);
-
-	for (i = 0, list = adapter->services; list; list = list->next) {
-		char *uuid;
-		sdp_record_t *rec = list->data;
-
-		uuid = bt_uuid2string(&rec->svclass);
-		if (uuid)
-			uuids[i++] = uuid;
-	}
-
-	emit_array_property_changed(adapter->path,
-					ADAPTER_INTERFACE, "UUIDs",
-					DBUS_TYPE_STRING, &uuids, i);
-
-	g_strfreev(uuids);
-}
-
 static uint8_t get_uuid_mask(uuid_t *uuid)
 {
 	if (uuid->type != SDP_UUID16)
@@ -947,7 +899,9 @@ void adapter_service_insert(struct btd_adapter *adapter, void *r)
 		mgmt_add_uuid(adapter->dev_id, &rec->svclass, svc_hint);
 	}
 
-	adapter_emit_uuids_updated(adapter);
+	if (adapter->initialized)
+		g_dbus_emit_property_changed(btd_get_dbus_connection(),
+				adapter->path, ADAPTER_INTERFACE, "UUIDs");
 }
 
 void adapter_service_remove(struct btd_adapter *adapter, void *r)
@@ -959,7 +913,9 @@ void adapter_service_remove(struct btd_adapter *adapter, void *r)
 	if (sdp_list_find(adapter->services, &rec->svclass, uuid_cmp) == NULL)
 		mgmt_remove_uuid(adapter->dev_id, &rec->svclass);
 
-	adapter_emit_uuids_updated(adapter);
+	if (adapter->initialized)
+		g_dbus_emit_property_changed(btd_get_dbus_connection(),
+				adapter->path, ADAPTER_INTERFACE, "UUIDs");
 }
 
 static struct btd_device *adapter_create_device(struct btd_adapter *adapter,
@@ -985,7 +941,8 @@ static struct btd_device *adapter_create_device(struct btd_adapter *adapter,
 			DBUS_TYPE_OBJECT_PATH, &path,
 			DBUS_TYPE_INVALID);
 
-	adapter_update_devices(adapter);
+	g_dbus_emit_property_changed(btd_get_dbus_connection(),
+				adapter->path, ADAPTER_INTERFACE, "Devices");
 
 	return device;
 }
@@ -1033,7 +990,8 @@ void adapter_remove_device(struct btd_adapter *adapter,
 		service_auth_cancel(auth);
 	}
 
-	adapter_update_devices(adapter);
+	g_dbus_emit_property_changed(btd_get_dbus_connection(),
+				adapter->path, ADAPTER_INTERFACE, "Devices");
 
 	g_dbus_emit_signal(btd_get_dbus_connection(), adapter->path,
 			ADAPTER_INTERFACE, "DeviceRemoved",
@@ -1807,8 +1765,6 @@ static const GDBusMethodTable adapter_methods[] = {
 };
 
 static const GDBusSignalTable adapter_signals[] = {
-	{ GDBUS_SIGNAL("PropertyChanged",
-			GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
 	{ GDBUS_SIGNAL("DeviceCreated",
 			GDBUS_ARGS({ "device", "o" })) },
 	{ GDBUS_SIGNAL("DeviceRemoved",
@@ -2449,7 +2405,6 @@ void btd_adapter_start(struct btd_adapter *adapter)
 {
 	struct session_req *req;
 	char address[18];
-	gboolean powered;
 
 	ba2str(&adapter->bdaddr, address);
 
@@ -2465,10 +2420,8 @@ void btd_adapter_start(struct btd_adapter *adapter)
 	else
 		adapter->mode = MODE_CONNECTABLE;
 
-	powered = TRUE;
-	emit_property_changed(adapter->path,
-				ADAPTER_INTERFACE, "Powered",
-				DBUS_TYPE_BOOLEAN, &powered);
+	g_dbus_emit_property_changed(btd_get_dbus_connection(), adapter->path,
+						ADAPTER_INTERFACE, "Powered");
 
 	call_adapter_powered_callbacks(adapter, TRUE);
 
@@ -2586,7 +2539,9 @@ static void set_mode_complete(struct btd_adapter *adapter)
 
 int btd_adapter_stop(struct btd_adapter *adapter)
 {
-	gboolean prop_false = FALSE;
+	DBusConnection *conn = btd_get_dbus_connection();
+	bool emit_discoverable = false, emit_pairable = false;
+	bool emit_discovering = false;
 
 	/* check pending requests */
 	reply_pending_requests(adapter);
@@ -2606,29 +2561,33 @@ int btd_adapter_stop(struct btd_adapter *adapter)
 	}
 
 	if (adapter->scan_mode == (SCAN_PAGE | SCAN_INQUIRY))
-		emit_property_changed(adapter->path,
-					ADAPTER_INTERFACE, "Discoverable",
-					DBUS_TYPE_BOOLEAN, &prop_false);
+		emit_discoverable = true;
 
 	if ((adapter->scan_mode & SCAN_PAGE) && adapter->pairable == TRUE)
-		emit_property_changed(adapter->path,
-					ADAPTER_INTERFACE, "Pairable",
-					DBUS_TYPE_BOOLEAN, &prop_false);
+		emit_pairable = true;
 
 	if (adapter->discovering)
-		emit_property_changed(adapter->path,
-					ADAPTER_INTERFACE, "Discovering",
-					DBUS_TYPE_BOOLEAN, &prop_false);
-
-	emit_property_changed(adapter->path,
-				ADAPTER_INTERFACE, "Powered",
-				DBUS_TYPE_BOOLEAN, &prop_false);
+		emit_discovering = true;
 
 	adapter->discovering = FALSE;
 	adapter->scan_mode = SCAN_DISABLED;
 	adapter->mode = MODE_OFF;
 	adapter->off_requested = FALSE;
 
+	if (emit_discoverable)
+		g_dbus_emit_property_changed(conn, adapter->path,
+					ADAPTER_INTERFACE, "Discoverable");
+	if (emit_pairable)
+		g_dbus_emit_property_changed(conn, adapter->path,
+					ADAPTER_INTERFACE, "Pairable");
+
+	if (emit_discovering)
+		g_dbus_emit_property_changed(conn, adapter->path,
+					ADAPTER_INTERFACE, "Discovering");
+
+	g_dbus_emit_property_changed(conn, adapter->path, ADAPTER_INTERFACE,
+								"Powered");
+
 	call_adapter_powered_callbacks(adapter, FALSE);
 
 	info("Adapter %s has been disabled", adapter->path);
@@ -2818,14 +2777,12 @@ void adapter_set_allow_name_changes(struct btd_adapter *adapter,
 void adapter_set_discovering(struct btd_adapter *adapter,
 						gboolean discovering)
 {
-	const char *path = adapter->path;
 	guint connect_list_len;
 
 	adapter->discovering = discovering;
 
-	emit_property_changed(path,
-				ADAPTER_INTERFACE, "Discovering",
-				DBUS_TYPE_BOOLEAN, &discovering);
+	g_dbus_emit_property_changed(btd_get_dbus_connection(), adapter->path,
+					ADAPTER_INTERFACE, "Discovering");
 
 	if (discovering)
 		return;
@@ -3319,7 +3276,7 @@ done:
 
 void adapter_mode_changed(struct btd_adapter *adapter, uint8_t scan_mode)
 {
-	gboolean discoverable, pairable;
+	bool emit_pairable = false;
 
 	DBG("old 0x%02x new 0x%02x", adapter->scan_mode, scan_mode);
 
@@ -3329,18 +3286,12 @@ void adapter_mode_changed(struct btd_adapter *adapter, uint8_t scan_mode)
 	switch (scan_mode) {
 	case SCAN_DISABLED:
 		adapter->mode = MODE_OFF;
-		discoverable = FALSE;
-		pairable = FALSE;
 		break;
 	case SCAN_PAGE:
 		adapter->mode = MODE_CONNECTABLE;
-		discoverable = FALSE;
-		pairable = adapter->pairable;
 		break;
 	case (SCAN_PAGE | SCAN_INQUIRY):
 		adapter->mode = MODE_DISCOVERABLE;
-		discoverable = TRUE;
-		pairable = adapter->pairable;
 		break;
 	default:
 		/* ignore, reserved */
@@ -3349,16 +3300,17 @@ void adapter_mode_changed(struct btd_adapter *adapter, uint8_t scan_mode)
 
 	/* If page scanning gets toggled emit the Pairable property */
 	if ((adapter->scan_mode & SCAN_PAGE) != (scan_mode & SCAN_PAGE))
-		emit_property_changed(adapter->path,
-					ADAPTER_INTERFACE, "Pairable",
-					DBUS_TYPE_BOOLEAN, &pairable);
-
-	emit_property_changed(adapter->path,
-				ADAPTER_INTERFACE, "Discoverable",
-				DBUS_TYPE_BOOLEAN, &discoverable);
+		emit_pairable = true;
 
 	adapter->scan_mode = scan_mode;
 
+	if (emit_pairable)
+		g_dbus_emit_property_changed(btd_get_dbus_connection(),
+				adapter->path, ADAPTER_INTERFACE, "Pairable");
+
+	g_dbus_emit_property_changed(btd_get_dbus_connection(), adapter->path,
+					ADAPTER_INTERFACE, "Discoverable");
+
 	set_mode_complete(adapter);
 }
 
-- 
1.7.12.2


^ permalink raw reply related

* [PATCH BlueZ 7/8] adapter: Port remaining properties to DBus.Properties
From: Lucas De Marchi @ 2012-10-09  7:59 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lucas De Marchi
In-Reply-To: <1349769596-6050-1-git-send-email-lucas.demarchi@profusion.mobi>

From: Lucas De Marchi <lucas.de.marchi@gmail.com>

Remaining properties ported to DBus.Properties:
	- Pairable
	- Discoverable
	- Powered
---
 src/adapter.c | 197 +++++++++++++++++++++++++++++++---------------------------
 1 file changed, 107 insertions(+), 90 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index a6593b2..18689c6 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -95,6 +95,7 @@ struct session_req {
 	struct btd_adapter	*adapter;
 	enum session_req_type	type;
 	DBusMessage		*msg;		/* Unreplied message ref */
+	GDBusPendingPropertySet prop_id;	/* Pending Properties.Set() */
 	char			*owner;		/* Bus name of the owner */
 	guint			id;		/* Listener id */
 	uint8_t			mode;		/* Requested mode */
@@ -347,10 +348,10 @@ static void set_session_pending_mode(struct btd_adapter *adapter,
 					SESSION_REQ_TYPE_SESSION, NULL);
 }
 
-static DBusMessage *set_discoverable(DBusMessage *msg,
-					gboolean discoverable, void *data)
+static void set_discoverable(struct btd_adapter *adapter,
+			gboolean discoverable, GDBusPendingPropertySet id)
 {
-	struct btd_adapter *adapter = data;
+	DBusConnection *conn = btd_get_dbus_connection();
 	uint8_t mode;
 	int err;
 
@@ -358,55 +359,61 @@ static DBusMessage *set_discoverable(DBusMessage *msg,
 
 	if (mode == adapter->mode) {
 		adapter->global_mode = mode;
-		return dbus_message_new_method_return(msg);
+		return g_dbus_pending_property_success(conn, id);
 	}
 
 	err = set_mode(adapter, mode);
 	if (err < 0)
-		return btd_error_failed(msg, strerror(-err));
+		return g_dbus_pending_property_error(conn, id,
+						ERROR_INTERFACE ".Failed",
+						strerror(-err));
 
-	adapter->pending_mode = create_session(adapter, msg, mode,
+	adapter->pending_mode = create_session(adapter, NULL, mode,
 						SESSION_REQ_TYPE_GLOBAL, NULL);
-
-	return NULL;
+	adapter->pending_mode->prop_id = id;
 }
 
-static DBusMessage *set_powered(DBusMessage *msg, gboolean powered, void *data)
+static void set_powered(struct btd_adapter *adapter, gboolean powered,
+						GDBusPendingPropertySet id)
 {
-	struct btd_adapter *adapter = data;
+	DBusConnection *conn = btd_get_dbus_connection();
 	uint8_t mode;
 	int err;
 
 	if (powered) {
 		mode = get_mode(&adapter->bdaddr, "on");
-		return set_discoverable(msg, mode == MODE_DISCOVERABLE, data);
+		return set_discoverable(adapter, mode == MODE_DISCOVERABLE,
+									id);
 	}
 
 	mode = MODE_OFF;
 
 	if (mode == adapter->mode) {
 		adapter->global_mode = mode;
-		return dbus_message_new_method_return(msg);
+		return g_dbus_pending_property_success(conn, id);
 	}
 
 	err = set_mode(adapter, mode);
 	if (err < 0)
-		return btd_error_failed(msg, strerror(-err));
+		return g_dbus_pending_property_error(conn, id,
+						ERROR_INTERFACE ".Failed",
+						strerror(-err));
 
-	adapter->pending_mode = create_session(adapter, msg, mode,
+	adapter->pending_mode = create_session(adapter, NULL, mode,
 						SESSION_REQ_TYPE_GLOBAL, NULL);
-
-	return NULL;
+	adapter->pending_mode->prop_id = id;
 }
 
-static DBusMessage *set_pairable(DBusMessage *msg,
-						gboolean pairable, void *data)
+static void set_pairable(struct btd_adapter *adapter, gboolean pairable,
+				bool reply, GDBusPendingPropertySet id)
 {
-	struct btd_adapter *adapter = data;
+	DBusConnection *conn = btd_get_dbus_connection();
 	int err;
 
 	if (adapter->scan_mode == SCAN_DISABLED)
-		return btd_error_not_ready(msg);
+		return g_dbus_pending_property_error(conn, id,
+						ERROR_INTERFACE ".NotReady",
+						"Resource Not Ready");
 
 	if (pairable == adapter->pairable)
 		goto done;
@@ -416,22 +423,26 @@ static DBusMessage *set_pairable(DBusMessage *msg,
 
 	err = set_mode(adapter, MODE_DISCOVERABLE);
 	if (err < 0) {
-		if (msg != NULL)
-			return btd_error_failed(msg, strerror(-err));
-
-		return NULL;
+		if (reply)
+			g_dbus_pending_property_error(conn, id,
+						ERROR_INTERFACE ".Failed",
+						strerror(-err));
+		return;
 	}
 
 store:
 	mgmt_set_pairable(adapter->dev_id, pairable);
 
 done:
-	return msg ? dbus_message_new_method_return(msg) : NULL;
+	if (reply)
+		g_dbus_pending_property_success(conn, id);
 }
 
+
+
 static gboolean pairable_timeout_handler(void *data)
 {
-	set_pairable(NULL, FALSE, data);
+	set_pairable(data, FALSE, false, 0);
 
 	return FALSE;
 }
@@ -1201,6 +1212,23 @@ static gboolean adapter_property_get_powered(
 	return TRUE;
 }
 
+static void adapter_property_set_powered(
+				const GDBusPropertyTable *property,
+				DBusMessageIter *value,
+				GDBusPendingPropertySet id, void *data)
+{
+	dbus_bool_t powered;
+
+	if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN)
+		return g_dbus_pending_property_error(btd_get_dbus_connection(),
+				id, ERROR_INTERFACE ".InvalidArguments",
+				"Invalid arguments in method call");
+
+	dbus_message_iter_get_basic(value, &powered);
+
+	set_powered(data, powered, id);
+}
+
 static gboolean adapter_property_get_discoverable(
 					const GDBusPropertyTable *property,
 					DBusMessageIter *iter, void *data)
@@ -1214,6 +1242,23 @@ static gboolean adapter_property_get_discoverable(
 	return TRUE;
 }
 
+static void adapter_property_set_discoverable(
+				const GDBusPropertyTable *property,
+				DBusMessageIter *value,
+				GDBusPendingPropertySet id, void *data)
+{
+	dbus_bool_t discoverable;
+
+	if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN)
+		return g_dbus_pending_property_error(btd_get_dbus_connection(),
+				id, ERROR_INTERFACE ".InvalidArguments",
+				"Invalid arguments in method call");
+
+	dbus_message_iter_get_basic(value, &discoverable);
+
+	set_discoverable(data, discoverable, id);
+}
+
 static gboolean adapter_property_get_pairable(
 					const GDBusPropertyTable *property,
 					DBusMessageIter *iter, void *data)
@@ -1225,6 +1270,22 @@ static gboolean adapter_property_get_pairable(
 	return TRUE;
 }
 
+static void adapter_property_set_pairable(const GDBusPropertyTable *property,
+		DBusMessageIter *value,
+		GDBusPendingPropertySet id, void *data)
+{
+	dbus_bool_t pairable;
+
+	if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN)
+		return g_dbus_pending_property_error(btd_get_dbus_connection(),
+				id, ERROR_INTERFACE ".InvalidArguments",
+				"Invalid arguments in method call");
+
+	dbus_message_iter_get_basic(value, &pairable);
+
+	set_pairable(data, pairable, true, id);
+}
+
 static gboolean adapter_property_get_discoverable_timeout(
 					const GDBusPropertyTable *property,
 					DBusMessageIter *iter, void *data)
@@ -1342,58 +1403,6 @@ static gboolean adapter_property_get_uuids(const GDBusPropertyTable *property,
 
 	return TRUE;
 }
-static DBusMessage *set_property(DBusConnection *conn,
-					DBusMessage *msg, void *data)
-{
-	DBusMessageIter iter;
-	DBusMessageIter sub;
-	const char *property;
-
-	if (!dbus_message_iter_init(msg, &iter))
-		return btd_error_invalid_args(msg);
-
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
-		return btd_error_invalid_args(msg);
-
-	dbus_message_iter_get_basic(&iter, &property);
-	dbus_message_iter_next(&iter);
-
-	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_VARIANT)
-		return btd_error_invalid_args(msg);
-	dbus_message_iter_recurse(&iter, &sub);
-
-
-	if (g_str_equal("Powered", property)) {
-		gboolean powered;
-
-		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
-			return btd_error_invalid_args(msg);
-
-		dbus_message_iter_get_basic(&sub, &powered);
-
-		return set_powered(msg, powered, data);
-	} else if (g_str_equal("Discoverable", property)) {
-		gboolean discoverable;
-
-		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
-			return btd_error_invalid_args(msg);
-
-		dbus_message_iter_get_basic(&sub, &discoverable);
-
-		return set_discoverable(msg, discoverable, data);
-	} else if (g_str_equal("Pairable", property)) {
-		gboolean pairable;
-
-		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
-			return btd_error_invalid_args(msg);
-
-		dbus_message_iter_get_basic(&sub, &pairable);
-
-		return set_pairable(msg, pairable, data);
-	}
-
-	return btd_error_invalid_args(msg);
-}
 
 static DBusMessage *request_session(DBusConnection *conn,
 					DBusMessage *msg, void *data)
@@ -1760,9 +1769,6 @@ static DBusMessage *unregister_agent(DBusConnection *conn, DBusMessage *msg,
 }
 
 static const GDBusMethodTable adapter_methods[] = {
-	{ GDBUS_ASYNC_METHOD("SetProperty",
-			GDBUS_ARGS({ "name", "s" }, { "value", "v" }), NULL,
-			set_property) },
 	{ GDBUS_ASYNC_METHOD("RequestSession", NULL, NULL,
 			request_session) },
 	{ GDBUS_METHOD("ReleaseSession", NULL, NULL,
@@ -1819,9 +1825,12 @@ static const GDBusPropertyTable adapter_properties[] = {
 	{ "Address", "s", adapter_property_get_address },
 	{ "Name", "s", adapter_property_get_name, adapter_property_set_name },
 	{ "Class", "u", adapter_property_get_class },
-	{ "Powered", "b", adapter_property_get_powered },
-	{ "Discoverable", "b", adapter_property_get_discoverable },
-	{ "Pairable", "b", adapter_property_get_pairable },
+	{ "Powered", "b", adapter_property_get_powered,
+					adapter_property_set_powered },
+	{ "Discoverable", "b", adapter_property_get_discoverable,
+					adapter_property_set_discoverable },
+	{ "Pairable", "b", adapter_property_get_pairable,
+					adapter_property_set_pairable },
 	{ "DiscoverableTimeout", "u",
 			adapter_property_get_discoverable_timeout,
 			adapter_property_set_discoverable_timeout },
@@ -2524,6 +2533,7 @@ static void unload_drivers(struct btd_adapter *adapter)
 
 static void set_mode_complete(struct btd_adapter *adapter)
 {
+	DBusConnection *conn = btd_get_dbus_connection();
 	struct session_req *pending;
 	const char *modestr;
 	int err;
@@ -2546,19 +2556,26 @@ static void set_mode_complete(struct btd_adapter *adapter)
 
 	err = (pending->mode != adapter->mode) ? -EINVAL : 0;
 
-	if (pending->msg != NULL) {
+	if (pending->type == SESSION_REQ_TYPE_GLOBAL) {
+		if (err < 0)
+			g_dbus_pending_property_error(conn, pending->prop_id,
+						ERROR_INTERFACE ".Failed",
+						strerror(-err));
+		else {
+			adapter->global_mode = adapter->mode;
+			g_dbus_pending_property_success(conn,
+							pending->prop_id);
+		}
+	} else if (pending->msg != NULL) {
 		DBusMessage *msg = pending->msg;
 		DBusMessage *reply;
 
 		if (err < 0)
 			reply = btd_error_failed(msg, strerror(-err));
-		else {
-			if (pending->type == SESSION_REQ_TYPE_GLOBAL)
-				adapter->global_mode = adapter->mode;
+		else
 			reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
-		}
 
-		g_dbus_send_message(btd_get_dbus_connection(), reply);
+		g_dbus_send_message(conn, reply);
 	}
 
 	if (err != 0)
-- 
1.7.12.2


^ permalink raw reply related

* [PATCH BlueZ 6/8] adapter: Fix calling mgmt_set_pairable() with error set
From: Lucas De Marchi @ 2012-10-09  7:59 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lucas De Marchi
In-Reply-To: <1349769596-6050-1-git-send-email-lucas.demarchi@profusion.mobi>

From: Lucas De Marchi <lucas.de.marchi@gmail.com>

---
 src/adapter.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 26016f6..a6593b2 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -415,8 +415,12 @@ static DBusMessage *set_pairable(DBusMessage *msg,
 		goto store;
 
 	err = set_mode(adapter, MODE_DISCOVERABLE);
-	if (err < 0 && msg)
-		return btd_error_failed(msg, strerror(-err));
+	if (err < 0) {
+		if (msg != NULL)
+			return btd_error_failed(msg, strerror(-err));
+
+		return NULL;
+	}
 
 store:
 	mgmt_set_pairable(adapter->dev_id, pairable);
-- 
1.7.12.2


^ permalink raw reply related

* [PATCH BlueZ 5/8] adapter: Add session type to session_req
From: Lucas De Marchi @ 2012-10-09  7:59 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lucas De Marchi
In-Reply-To: <1349769596-6050-1-git-send-email-lucas.demarchi@profusion.mobi>

From: Lucas De Marchi <lucas.de.marchi@gmail.com>

With this field we can differentiate requests that should have global
actions from the ones created with RequestSession(). The intention with
this is to allow to separate how we detect a global request on
set_mode_complete(), not tying to the name of the D-Bus method it came
from.
---
 src/adapter.c | 38 ++++++++++++++++++++++++--------------
 1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index c9ae8ca..26016f6 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -86,8 +86,14 @@
 
 static GSList *adapter_drivers = NULL;
 
+enum session_req_type {
+	SESSION_REQ_TYPE_GLOBAL = 0,
+	SESSION_REQ_TYPE_SESSION,
+};
+
 struct session_req {
 	struct btd_adapter	*adapter;
+	enum session_req_type	type;
 	DBusMessage		*msg;		/* Unreplied message ref */
 	char			*owner;		/* Bus name of the owner */
 	guint			id;		/* Listener id */
@@ -225,6 +231,7 @@ static struct session_req *session_ref(struct session_req *req)
 
 static struct session_req *create_session(struct btd_adapter *adapter,
 					DBusMessage *msg, uint8_t mode,
+					enum session_req_type type,
 					GDBusWatchFunction cb)
 {
 	const char *sender;
@@ -233,6 +240,7 @@ static struct session_req *create_session(struct btd_adapter *adapter,
 	req = g_new0(struct session_req, 1);
 	req->adapter = adapter;
 	req->mode = mode;
+	req->type = type;
 
 	if (msg == NULL)
 		return session_ref(req);
@@ -321,8 +329,8 @@ done:
 	return 0;
 }
 
-static void set_pending_mode(struct btd_adapter *adapter, uint8_t new_mode,
-							DBusMessage *msg)
+static void set_session_pending_mode(struct btd_adapter *adapter,
+					uint8_t new_mode, DBusMessage *msg)
 {
 	struct session_req *req;
 
@@ -336,7 +344,7 @@ static void set_pending_mode(struct btd_adapter *adapter, uint8_t new_mode,
 		session_ref(req);
 	} else
 		adapter->pending_mode = create_session(adapter, msg, new_mode,
-									NULL);
+					SESSION_REQ_TYPE_SESSION, NULL);
 }
 
 static DBusMessage *set_discoverable(DBusMessage *msg,
@@ -357,7 +365,8 @@ static DBusMessage *set_discoverable(DBusMessage *msg,
 	if (err < 0)
 		return btd_error_failed(msg, strerror(-err));
 
-	set_pending_mode(adapter, mode, msg);
+	adapter->pending_mode = create_session(adapter, msg, mode,
+						SESSION_REQ_TYPE_GLOBAL, NULL);
 
 	return NULL;
 }
@@ -384,7 +393,8 @@ static DBusMessage *set_powered(DBusMessage *msg, gboolean powered, void *data)
 	if (err < 0)
 		return btd_error_failed(msg, strerror(-err));
 
-	set_pending_mode(adapter, mode, msg);
+	adapter->pending_mode = create_session(adapter, msg, mode,
+						SESSION_REQ_TYPE_GLOBAL, NULL);
 
 	return NULL;
 }
@@ -535,8 +545,8 @@ static void session_remove(struct session_req *req)
 {
 	struct btd_adapter *adapter = req->adapter;
 
-	/* Ignore set_mode session */
-	if (req->owner == NULL && adapter->pending_mode)
+	/* Ignore global requests */
+	if (req->type == SESSION_REQ_TYPE_GLOBAL)
 		return;
 
 	DBG("%s session %p with %s deactivated",
@@ -628,7 +638,7 @@ static void confirm_mode_cb(struct agent *agent, DBusError *derr, void *data)
 
 	err = set_mode(req->adapter, req->mode);
 	if (err >= 0 && req->adapter->mode != req->mode) {
-		set_pending_mode(req->adapter, req->mode, req->msg);
+		set_session_pending_mode(req->adapter, req->mode, req->msg);
 		goto done;
 	}
 
@@ -1089,7 +1099,8 @@ static DBusMessage *adapter_start_discovery(DBusConnection *conn,
 		return btd_error_failed(msg, strerror(-err));
 
 done:
-	req = create_session(adapter, msg, 0, session_owner_exit);
+	req = create_session(adapter, msg, 0, SESSION_REQ_TYPE_GLOBAL,
+							session_owner_exit);
 
 	adapter->disc_sessions = g_slist_append(adapter->disc_sessions, req);
 
@@ -1403,7 +1414,7 @@ static DBusMessage *request_session(DBusConnection *conn,
 		return dbus_message_new_method_return(msg);
 	} else {
 		req = create_session(adapter, msg, new_mode,
-							session_owner_exit);
+				SESSION_REQ_TYPE_SESSION, session_owner_exit);
 		adapter->mode_sessions = g_slist_append(adapter->mode_sessions,
 							req);
 	}
@@ -2401,7 +2412,7 @@ void adapter_connect_list_add(struct btd_adapter *adapter,
 	if (adapter->disc_sessions == NULL)
 		adapter->discov_id = g_idle_add(discovery_cb, adapter);
 
-	req = create_session(adapter, NULL, 0, NULL);
+	req = create_session(adapter, NULL, 0, SESSION_REQ_TYPE_GLOBAL, NULL);
 	adapter->disc_sessions = g_slist_append(adapter->disc_sessions, req);
 	adapter->scanning_session = req;
 }
@@ -2454,7 +2465,7 @@ void btd_adapter_start(struct btd_adapter *adapter)
 					adapter->disc_sessions != NULL)
 		return;
 
-	req = create_session(adapter, NULL, 0, NULL);
+	req = create_session(adapter, NULL, 0, SESSION_REQ_TYPE_GLOBAL, NULL);
 	adapter->disc_sessions = g_slist_append(adapter->disc_sessions, req);
 	adapter->scanning_session = req;
 
@@ -2538,8 +2549,7 @@ static void set_mode_complete(struct btd_adapter *adapter)
 		if (err < 0)
 			reply = btd_error_failed(msg, strerror(-err));
 		else {
-			if (strcmp(dbus_message_get_member(msg),
-						"SetProperty") == 0)
+			if (pending->type == SESSION_REQ_TYPE_GLOBAL)
 				adapter->global_mode = adapter->mode;
 			reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
 		}
-- 
1.7.12.2


^ permalink raw reply related

* [PATCH BlueZ 4/8] adapter: Refactor set_mode() in 2 functions
From: Lucas De Marchi @ 2012-10-09  7:59 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lucas De Marchi
In-Reply-To: <1349769596-6050-1-git-send-email-lucas.demarchi@profusion.mobi>

From: Lucas De Marchi <lucas.de.marchi@gmail.com>

Separate the handling of pending_mode from setting mode. This way it's
simpler to set the pending_mode only when needed. Half of callers were
passing NULL to this parameter.
---
 src/adapter.c | 78 +++++++++++++++++++++++++++++++----------------------------
 1 file changed, 41 insertions(+), 37 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index cc0ec3b..c9ae8ca 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -278,8 +278,7 @@ static struct session_req *find_session_by_msg(GSList *list, const DBusMessage *
 	return NULL;
 }
 
-static int set_mode(struct btd_adapter *adapter, uint8_t new_mode,
-			DBusMessage *msg)
+static int set_mode(struct btd_adapter *adapter, uint8_t new_mode)
 {
 	int err;
 	const char *modestr;
@@ -319,22 +318,25 @@ done:
 
 	DBG("%s", modestr);
 
-	if (msg != NULL) {
-		struct session_req *req;
+	return 0;
+}
 
-		req = find_session_by_msg(adapter->mode_sessions, msg);
-		if (req) {
-			adapter->pending_mode = req;
-			session_ref(req);
-		} else
-			/* Wait for mode change to reply */
-			adapter->pending_mode = create_session(adapter, msg,
-								new_mode, NULL);
-	} else
-		/* Nothing to reply just write the new mode */
-		adapter->mode = new_mode;
+static void set_pending_mode(struct btd_adapter *adapter, uint8_t new_mode,
+							DBusMessage *msg)
+{
+	struct session_req *req;
 
-	return 0;
+	/*
+	 * Schedule the reply to be sent when a mode-change notification
+	 * arrives. The reply will be sent by set_mode_complete().
+	 */
+	req = find_session_by_msg(adapter->mode_sessions, msg);
+	if (req) {
+		adapter->pending_mode = req;
+		session_ref(req);
+	} else
+		adapter->pending_mode = create_session(adapter, msg, new_mode,
+									NULL);
 }
 
 static DBusMessage *set_discoverable(DBusMessage *msg,
@@ -351,10 +353,12 @@ static DBusMessage *set_discoverable(DBusMessage *msg,
 		return dbus_message_new_method_return(msg);
 	}
 
-	err = set_mode(adapter, mode, msg);
+	err = set_mode(adapter, mode);
 	if (err < 0)
 		return btd_error_failed(msg, strerror(-err));
 
+	set_pending_mode(adapter, mode, msg);
+
 	return NULL;
 }
 
@@ -376,10 +380,12 @@ static DBusMessage *set_powered(DBusMessage *msg, gboolean powered, void *data)
 		return dbus_message_new_method_return(msg);
 	}
 
-	err = set_mode(adapter, mode, msg);
+	err = set_mode(adapter, mode);
 	if (err < 0)
 		return btd_error_failed(msg, strerror(-err));
 
+	set_pending_mode(adapter, mode, msg);
+
 	return NULL;
 }
 
@@ -398,7 +404,7 @@ static DBusMessage *set_pairable(DBusMessage *msg,
 	if (!(adapter->scan_mode & SCAN_INQUIRY))
 		goto store;
 
-	err = set_mode(adapter, MODE_DISCOVERABLE, NULL);
+	err = set_mode(adapter, MODE_DISCOVERABLE);
 	if (err < 0 && msg)
 		return btd_error_failed(msg, strerror(-err));
 
@@ -549,7 +555,7 @@ static void session_remove(struct session_req *req)
 
 		DBG("Switching to '%s' mode", mode2str(mode));
 
-		set_mode(adapter, mode, NULL);
+		set_mode(adapter, mode);
 	} else {
 		adapter->disc_sessions = g_slist_remove(adapter->disc_sessions,
 							req);
@@ -620,28 +626,26 @@ static void confirm_mode_cb(struct agent *agent, DBusError *derr, void *data)
 		return;
 	}
 
-	err = set_mode(req->adapter, req->mode, req->msg);
+	err = set_mode(req->adapter, req->mode);
+	if (err >= 0 && req->adapter->mode != req->mode) {
+		set_pending_mode(req->adapter, req->mode, req->msg);
+		goto done;
+	}
+
 	if (err < 0)
 		reply = btd_error_failed(req->msg, strerror(-err));
-	else if (!req->adapter->pending_mode)
-		reply = dbus_message_new_method_return(req->msg);
 	else
-		reply = NULL;
-
-	if (reply) {
-		/*
-		 * Send reply immediately only if there was an error changing
-		 * mode, or change is not needed. Otherwise, reply is sent in
-		 * set_mode_complete.
-		 */
-		g_dbus_send_message(conn, reply);
+		reply = dbus_message_new_method_return(req->msg);
 
-		dbus_message_unref(req->msg);
-		req->msg = NULL;
-	}
+	/*
+	 * Send reply immediately only if there was an error changing mode, or
+	 * change is not needed. Otherwise, reply is sent in
+	 * set_mode_complete.
+	 */
+	g_dbus_send_message(conn, reply);
 
-	if (!find_session(req->adapter->mode_sessions, req->owner))
-		session_unref(req);
+done:
+	session_unref(req);
 }
 
 static void set_discoverable_timeout(struct btd_adapter *adapter,
-- 
1.7.12.2


^ permalink raw reply related

* [PATCH BlueZ 3/8] adapter: Set *Timeout through DBus.Properties
From: Lucas De Marchi @ 2012-10-09  7:59 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lucas De Marchi
In-Reply-To: <1349769596-6050-1-git-send-email-lucas.demarchi@profusion.mobi>

---
 src/adapter.c | 93 +++++++++++++++++++++++++++++++----------------------------
 1 file changed, 49 insertions(+), 44 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 512e2df..cc0ec3b 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -644,14 +644,13 @@ static void confirm_mode_cb(struct agent *agent, DBusError *derr, void *data)
 		session_unref(req);
 }
 
-static DBusMessage *set_discoverable_timeout(DBusMessage *msg,
-						uint32_t timeout, void *data)
+static void set_discoverable_timeout(struct btd_adapter *adapter,
+				uint32_t timeout, GDBusPendingPropertySet id)
 {
-	struct btd_adapter *adapter = data;
-	const char *path;
+	DBusConnection *conn = btd_get_dbus_connection();
 
 	if (adapter->discov_timeout == timeout && timeout == 0)
-		return dbus_message_new_method_return(msg);
+		return g_dbus_pending_property_success(conn, id);
 
 	if (adapter->scan_mode & SCAN_INQUIRY)
 		mgmt_set_discoverable(adapter->dev_id, TRUE, timeout);
@@ -660,23 +659,18 @@ static DBusMessage *set_discoverable_timeout(DBusMessage *msg,
 
 	write_discoverable_timeout(&adapter->bdaddr, timeout);
 
-	path = dbus_message_get_path(msg);
-
-	emit_property_changed(path,
-				ADAPTER_INTERFACE, "DiscoverableTimeout",
-				DBUS_TYPE_UINT32, &timeout);
-
-	return dbus_message_new_method_return(msg);
+	g_dbus_emit_property_changed(conn, adapter->path, ADAPTER_INTERFACE,
+						"DiscoverableTimeout");
+	g_dbus_pending_property_success(conn, id);
 }
 
-static DBusMessage *set_pairable_timeout(DBusMessage *msg,
-						uint32_t timeout, void *data)
+static void set_pairable_timeout(struct btd_adapter *adapter,
+				uint32_t timeout, GDBusPendingPropertySet id)
 {
-	struct btd_adapter *adapter = data;
-	const char *path;
+	DBusConnection *conn = btd_get_dbus_connection();
 
 	if (adapter->pairable_timeout == timeout && timeout == 0)
-		return dbus_message_new_method_return(msg);
+		return g_dbus_pending_property_success(conn, id);
 
 	if (adapter->pairable)
 		adapter_set_pairable_timeout(adapter, timeout);
@@ -685,13 +679,9 @@ static DBusMessage *set_pairable_timeout(DBusMessage *msg,
 
 	write_pairable_timeout(&adapter->bdaddr, timeout);
 
-	path = dbus_message_get_path(msg);
-
-	emit_property_changed(path,
-				ADAPTER_INTERFACE, "PairableTimeout",
-				DBUS_TYPE_UINT32, &timeout);
-
-	return dbus_message_new_method_return(msg);
+	g_dbus_emit_property_changed(conn, adapter->path, ADAPTER_INTERFACE,
+							"PairableTimeout");
+	g_dbus_pending_property_success(conn, id);
 }
 
 void btd_adapter_class_changed(struct btd_adapter *adapter, uint8_t *new_class)
@@ -1228,6 +1218,22 @@ static gboolean adapter_property_get_discoverable_timeout(
 	return TRUE;
 }
 
+
+static void adapter_property_set_discoverable_timeout(
+		const GDBusPropertyTable *property, DBusMessageIter *value,
+		GDBusPendingPropertySet id, void *data)
+{
+	uint32_t timeout;
+
+	if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_UINT32)
+		return g_dbus_pending_property_error(btd_get_dbus_connection(),
+				id, ERROR_INTERFACE ".InvalidArguments",
+				"Invalid arguments in method call");
+
+	dbus_message_iter_get_basic(value, &timeout);
+	set_discoverable_timeout(data, timeout, id);
+}
+
 static gboolean adapter_property_get_pairable_timeout(
 					const GDBusPropertyTable *property,
 					DBusMessageIter *iter, void *data)
@@ -1240,6 +1246,21 @@ static gboolean adapter_property_get_pairable_timeout(
 	return TRUE;
 }
 
+static void adapter_property_set_pairable_timeout(
+		const GDBusPropertyTable *property, DBusMessageIter *value,
+		GDBusPendingPropertySet id, void *data)
+{
+	uint32_t timeout;
+
+	if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_UINT32)
+		return g_dbus_pending_property_error(btd_get_dbus_connection(),
+				id, ERROR_INTERFACE ".InvalidArguments",
+				"Invalid arguments in method call");
+
+	dbus_message_iter_get_basic(value, &timeout);
+	set_pairable_timeout(data, timeout, id);
+}
+
 static gboolean adapter_property_get_discovering(
 					const GDBusPropertyTable *property,
 					DBusMessageIter *iter, void *data)
@@ -1341,15 +1362,6 @@ static DBusMessage *set_property(DBusConnection *conn,
 		dbus_message_iter_get_basic(&sub, &discoverable);
 
 		return set_discoverable(msg, discoverable, data);
-	} else if (g_str_equal("DiscoverableTimeout", property)) {
-		uint32_t timeout;
-
-		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_UINT32)
-			return btd_error_invalid_args(msg);
-
-		dbus_message_iter_get_basic(&sub, &timeout);
-
-		return set_discoverable_timeout(msg, timeout, data);
 	} else if (g_str_equal("Pairable", property)) {
 		gboolean pairable;
 
@@ -1359,15 +1371,6 @@ static DBusMessage *set_property(DBusConnection *conn,
 		dbus_message_iter_get_basic(&sub, &pairable);
 
 		return set_pairable(msg, pairable, data);
-	} else if (g_str_equal("PairableTimeout", property)) {
-		uint32_t timeout;
-
-		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_UINT32)
-			return btd_error_invalid_args(msg);
-
-		dbus_message_iter_get_basic(&sub, &timeout);
-
-		return set_pairable_timeout(msg, timeout, data);
 	}
 
 	return btd_error_invalid_args(msg);
@@ -1801,8 +1804,10 @@ static const GDBusPropertyTable adapter_properties[] = {
 	{ "Discoverable", "b", adapter_property_get_discoverable },
 	{ "Pairable", "b", adapter_property_get_pairable },
 	{ "DiscoverableTimeout", "u",
-			adapter_property_get_discoverable_timeout },
-	{ "PairableTimeout", "u", adapter_property_get_pairable_timeout },
+			adapter_property_get_discoverable_timeout,
+			adapter_property_set_discoverable_timeout },
+	{ "PairableTimeout", "u", adapter_property_get_pairable_timeout,
+				adapter_property_set_pairable_timeout },
 	{ "Discovering", "b", adapter_property_get_discovering },
 	{ "Devices", "ao", adapter_property_get_devices },
 	{ "UUIDs", "as", adapter_property_get_uuids },
-- 
1.7.12.2


^ permalink raw reply related

* [PATCH BlueZ 2/8] adapter: Set Name through DBus.Properties
From: Lucas De Marchi @ 2012-10-09  7:59 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lucas De Marchi
In-Reply-To: <1349769596-6050-1-git-send-email-lucas.demarchi@profusion.mobi>

---
 src/adapter.c | 59 +++++++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 39 insertions(+), 20 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index eb5fc83..512e2df 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -730,9 +730,8 @@ void adapter_name_changed(struct btd_adapter *adapter, const char *name)
 	g_free(adapter->name);
 	adapter->name = g_strdup(name);
 
-	emit_property_changed(adapter->path,
-				ADAPTER_INTERFACE, "Name",
-				DBUS_TYPE_STRING, &name);
+	g_dbus_emit_property_changed(btd_get_dbus_connection(), adapter->path,
+						ADAPTER_INTERFACE, "Name");
 
 	if (main_opts.gatt_enabled)
 		attrib_gap_set(adapter, GATT_CHARAC_DEVICE_NAME,
@@ -767,21 +766,30 @@ int adapter_set_name(struct btd_adapter *adapter, const char *name)
 	return 0;
 }
 
-static DBusMessage *set_name(DBusMessage *msg, const char *name, void *data)
+static void set_name(struct btd_adapter *adapter, const char *name,
+						GDBusPendingPropertySet id)
 {
-	struct btd_adapter *adapter = data;
 	int ret;
 
 	if (adapter->allow_name_changes == FALSE)
-		return btd_error_failed(msg, strerror(EPERM));
+		return g_dbus_pending_property_error(btd_get_dbus_connection(),
+						id, ERROR_INTERFACE ".Failed",
+						strerror(EPERM));
 
 	ret = adapter_set_name(adapter, name);
-	if (ret == -EINVAL)
-		return btd_error_invalid_args(msg);
-	else if (ret < 0)
-		return btd_error_failed(msg, strerror(-ret));
+	if (ret >= 0) {
+		g_dbus_pending_property_success(btd_get_dbus_connection(), id);
+		return;
+	}
 
-	return dbus_message_new_method_return(msg);
+	if (ret == -EINVAL)
+		g_dbus_pending_property_error(btd_get_dbus_connection(),
+				id, ERROR_INTERFACE ".InvalidArguments",
+				"Invalid arguments in method call");
+	else
+		g_dbus_pending_property_error(btd_get_dbus_connection(),
+						id, ERROR_INTERFACE ".Failed",
+						strerror(-ret));
 }
 
 struct btd_device *adapter_find_device(struct btd_adapter *adapter,
@@ -1142,6 +1150,24 @@ static gboolean adapter_property_get_name(const GDBusPropertyTable *property,
 	return TRUE;
 }
 
+static void adapter_property_set_name(const GDBusPropertyTable *property,
+					DBusMessageIter *value,
+					GDBusPendingPropertySet id, void *data)
+{
+	const char *name;
+
+	if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_STRING) {
+		g_dbus_pending_property_error(btd_get_dbus_connection(),
+				id, ERROR_INTERFACE ".InvalidArguments",
+				"Invalid arguments in method call");
+		return;
+	}
+
+	dbus_message_iter_get_basic(value, &name);
+
+	set_name(data, name, id);
+}
+
 static gboolean adapter_property_get_class(const GDBusPropertyTable *property,
 					DBusMessageIter *iter, void *data)
 {
@@ -1296,15 +1322,8 @@ static DBusMessage *set_property(DBusConnection *conn,
 		return btd_error_invalid_args(msg);
 	dbus_message_iter_recurse(&iter, &sub);
 
-	if (g_str_equal("Name", property)) {
-		const char *name;
-
-		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_STRING)
-			return btd_error_invalid_args(msg);
-		dbus_message_iter_get_basic(&sub, &name);
 
-		return set_name(msg, name, data);
-	} else if (g_str_equal("Powered", property)) {
+	if (g_str_equal("Powered", property)) {
 		gboolean powered;
 
 		if (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_BOOLEAN)
@@ -1776,7 +1795,7 @@ static const GDBusSignalTable adapter_signals[] = {
 
 static const GDBusPropertyTable adapter_properties[] = {
 	{ "Address", "s", adapter_property_get_address },
-	{ "Name", "s", adapter_property_get_name },
+	{ "Name", "s", adapter_property_get_name, adapter_property_set_name },
 	{ "Class", "u", adapter_property_get_class },
 	{ "Powered", "b", adapter_property_get_powered },
 	{ "Discoverable", "b", adapter_property_get_discoverable },
-- 
1.7.12.2


^ permalink raw reply related

* [PATCH BlueZ 1/8] adapter: Add DBus.Properties getters
From: Lucas De Marchi @ 2012-10-09  7:59 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Lucas De Marchi

From: Lucas De Marchi <lucas.de.marchi@gmail.com>

---
 src/adapter.c | 221 +++++++++++++++++++++++++++++++++++++++-------------------
 1 file changed, 149 insertions(+), 72 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 2f8c8a3..eb5fc83 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1113,106 +1113,169 @@ static DBusMessage *adapter_stop_discovery(DBusConnection *conn,
 	return dbus_message_new_method_return(msg);
 }
 
-static DBusMessage *get_properties(DBusConnection *conn,
-					DBusMessage *msg, void *data)
+static gboolean adapter_property_get_address(
+					const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
 {
 	struct btd_adapter *adapter = data;
-	const char *property;
-	DBusMessage *reply;
-	DBusMessageIter iter;
-	DBusMessageIter dict;
 	char srcaddr[18];
-	gboolean value;
-	char **devices, **uuids;
-	int i;
-	GSList *l;
-	sdp_list_t *list;
+	const char *ptr;
 
 	ba2str(&adapter->bdaddr, srcaddr);
+	ptr = srcaddr;
 
-	if (check_address(srcaddr) < 0)
-		return btd_error_invalid_args(msg);
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr);
 
-	reply = dbus_message_new_method_return(msg);
-	if (!reply)
-		return NULL;
+	return TRUE;
+}
 
-	dbus_message_iter_init_append(reply, &iter);
+static gboolean adapter_property_get_name(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct btd_adapter *adapter = data;
+	const char *ptr;
 
-	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
-			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
-			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
-			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+	ptr = adapter->name ?: "";
 
-	/* Address */
-	property = srcaddr;
-	dict_append_entry(&dict, "Address", DBUS_TYPE_STRING, &property);
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr);
 
-	/* Name */
-	property = adapter->name ? : "";
+	return TRUE;
+}
 
-	dict_append_entry(&dict, "Name", DBUS_TYPE_STRING, &property);
+static gboolean adapter_property_get_class(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct btd_adapter *adapter = data;
 
-	/* Class */
-	dict_append_entry(&dict, "Class",
-				DBUS_TYPE_UINT32, &adapter->dev_class);
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32,
+							&adapter->dev_class);
+
+	return TRUE;
+}
+
+static gboolean adapter_property_get_powered(
+					const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct btd_adapter *adapter = data;
+	dbus_bool_t value;
 
-	/* Powered */
 	value = (adapter->up && !adapter->off_requested) ? TRUE : FALSE;
-	dict_append_entry(&dict, "Powered", DBUS_TYPE_BOOLEAN, &value);
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &value);
+
+	return TRUE;
+}
+
+static gboolean adapter_property_get_discoverable(
+					const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct btd_adapter *adapter = data;
+	dbus_bool_t value;
 
-	/* Discoverable */
 	value = adapter->scan_mode & SCAN_INQUIRY ? TRUE : FALSE;
-	dict_append_entry(&dict, "Discoverable", DBUS_TYPE_BOOLEAN, &value);
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &value);
 
-	/* Pairable */
-	dict_append_entry(&dict, "Pairable", DBUS_TYPE_BOOLEAN,
-				&adapter->pairable);
+	return TRUE;
+}
 
-	/* DiscoverableTimeout */
-	dict_append_entry(&dict, "DiscoverableTimeout",
-				DBUS_TYPE_UINT32, &adapter->discov_timeout);
+static gboolean adapter_property_get_pairable(
+					const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct btd_adapter *adapter = data;
 
-	/* PairableTimeout */
-	dict_append_entry(&dict, "PairableTimeout",
-				DBUS_TYPE_UINT32, &adapter->pairable_timeout);
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
+							&adapter->pairable);
+	return TRUE;
+}
 
+static gboolean adapter_property_get_discoverable_timeout(
+					const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct btd_adapter *adapter = data;
 
-	/* Discovering */
-	dict_append_entry(&dict, "Discovering", DBUS_TYPE_BOOLEAN,
-							&adapter->discovering);
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32,
+						&adapter->discov_timeout);
 
-	/* Devices */
-	devices = g_new0(char *, g_slist_length(adapter->devices) + 1);
-	for (i = 0, l = adapter->devices; l; l = l->next, i++) {
-		struct btd_device *dev = l->data;
-		devices[i] = (char *) device_get_path(dev);
+	return TRUE;
+}
+
+static gboolean adapter_property_get_pairable_timeout(
+					const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct btd_adapter *adapter = data;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32,
+						&adapter->pairable_timeout);
+
+	return TRUE;
+}
+
+static gboolean adapter_property_get_discovering(
+					const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct btd_adapter *adapter = data;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
+						&adapter->discovering);
+
+	return TRUE;
+}
+
+static gboolean adapter_property_get_devices(
+					const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct btd_adapter *adapter = data;
+	DBusMessageIter entry;
+	GSList *l;
+
+	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
+				DBUS_TYPE_OBJECT_PATH_AS_STRING, &entry);
+
+	for (l = adapter->devices; l != NULL; l = l->next) {
+		const char *path = device_get_path(l->data);
+
+		dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
+								&path);
 	}
-	dict_append_array(&dict, "Devices", DBUS_TYPE_OBJECT_PATH,
-								&devices, i);
-	g_free(devices);
 
-	/* UUIDs */
-	uuids = g_new0(char *, sdp_list_len(adapter->services) + 1);
+	dbus_message_iter_close_container(iter, &entry);
 
-	for (i = 0, list = adapter->services; list; list = list->next) {
-		sdp_record_t *rec = list->data;
+	return TRUE;
+}
+
+static gboolean adapter_property_get_uuids(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct btd_adapter *adapter = data;
+	DBusMessageIter entry;
+	sdp_list_t *l;
+
+	dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
+					DBUS_TYPE_STRING_AS_STRING, &entry);
+
+	for (l = adapter->services; l != NULL; l = l->next) {
+		sdp_record_t *rec = l->data;
 		char *uuid;
 
 		uuid = bt_uuid2string(&rec->svclass);
-		if (uuid)
-			uuids[i++] = uuid;
-	}
-
-	dict_append_array(&dict, "UUIDs", DBUS_TYPE_STRING, &uuids, i);
+		if (uuid == NULL)
+			continue;
 
-	g_strfreev(uuids);
+		dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
+								&uuid);
+		g_free(uuid);
+	}
 
-	dbus_message_iter_close_container(&iter, &dict);
+	dbus_message_iter_close_container(iter, &entry);
 
-	return reply;
+	return TRUE;
 }
-
 static DBusMessage *set_property(DBusConnection *conn,
 					DBusMessage *msg, void *data)
 {
@@ -1656,9 +1719,6 @@ static DBusMessage *unregister_agent(DBusConnection *conn, DBusMessage *msg,
 }
 
 static const GDBusMethodTable adapter_methods[] = {
-	{ GDBUS_METHOD("GetProperties",
-			NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
-			get_properties) },
 	{ GDBUS_ASYNC_METHOD("SetProperty",
 			GDBUS_ARGS({ "name", "s" }, { "value", "v" }), NULL,
 			set_property) },
@@ -1714,6 +1774,22 @@ static const GDBusSignalTable adapter_signals[] = {
 	{ }
 };
 
+static const GDBusPropertyTable adapter_properties[] = {
+	{ "Address", "s", adapter_property_get_address },
+	{ "Name", "s", adapter_property_get_name },
+	{ "Class", "u", adapter_property_get_class },
+	{ "Powered", "b", adapter_property_get_powered },
+	{ "Discoverable", "b", adapter_property_get_discoverable },
+	{ "Pairable", "b", adapter_property_get_pairable },
+	{ "DiscoverableTimeout", "u",
+			adapter_property_get_discoverable_timeout },
+	{ "PairableTimeout", "u", adapter_property_get_pairable_timeout },
+	{ "Discovering", "b", adapter_property_get_discovering },
+	{ "Devices", "ao", adapter_property_get_devices },
+	{ "UUIDs", "as", adapter_property_get_uuids },
+	{ }
+};
+
 static void create_stored_device_from_profiles(char *key, char *value,
 						void *user_data)
 {
@@ -2624,8 +2700,9 @@ struct btd_adapter *adapter_create(int id)
 
 	if (!g_dbus_register_interface(btd_get_dbus_connection(),
 					path, ADAPTER_INTERFACE,
-					adapter_methods, adapter_signals, NULL,
-					adapter, adapter_free)) {
+					adapter_methods, adapter_signals,
+					adapter_properties, adapter,
+					adapter_free)) {
 		error("Adapter interface init failed on path %s", path);
 		adapter_free(adapter);
 		return NULL;
-- 
1.7.12.2


^ permalink raw reply related

* [RFC BlueZ 5/5] gas: Add the per handle GATT event notifier
From: Vinicius Costa Gomes @ 2012-10-09  0:26 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1349742372-18420-1-git-send-email-vinicius.gomes@openbossa.org>

---
 profiles/gatt/gas.c | 72 +++++++++++++++++++++++++----------------------------
 1 file changed, 34 insertions(+), 38 deletions(-)

diff --git a/profiles/gatt/gas.c b/profiles/gatt/gas.c
index 35a9152..d913df5 100644
--- a/profiles/gatt/gas.c
+++ b/profiles/gatt/gas.c
@@ -166,39 +166,10 @@ done:
 	att_data_list_free(list);
 }
 
-static void ccc_written_cb(guint8 status, const guint8 *pdu, guint16 plen,
-							gpointer user_data)
-{
-	struct gas *gas = user_data;
-
-	if (status) {
-		error("Write Service Changed CCC failed: %s",
-						att_ecode2str(status));
-		return;
-	}
-
-	DBG("Service Changed indications enabled");
-
-	write_ctp_handle(adapter_get_address(device_get_adapter(gas->device)),
-					device_get_address(gas->device),
-					device_get_addr_type(gas->device),
-					GATT_CHARAC_SERVICE_CHANGED,
-					gas->changed_handle);
-}
-
-static void write_ccc(GAttrib *attrib, uint16_t handle, gpointer user_data)
-{
-	uint8_t value[2];
-
-	att_put_u16(GATT_CLIENT_CHARAC_CFG_IND_BIT, value);
-	gatt_write_char(attrib, handle, value, sizeof(value), ccc_written_cb,
-								user_data);
-}
-
 static void indication_cb(const uint8_t *pdu, uint16_t len, gpointer user_data)
 {
 	struct gas *gas = user_data;
-	uint16_t handle, start, end, olen;
+	uint16_t start, end, olen;
 	size_t plen;
 	uint8_t *opdu;
 
@@ -207,13 +178,9 @@ static void indication_cb(const uint8_t *pdu, uint16_t len, gpointer user_data)
 		return;
 	}
 
-	handle = att_get_u16(&pdu[1]);
 	start = att_get_u16(&pdu[3]);
 	end = att_get_u16(&pdu[5]);
 
-	if (handle != gas->changed_handle)
-		return;
-
 	DBG("Service Changed start: 0x%04X end: 0x%04X", start, end);
 
 	if (device_is_bonded(gas->device) == FALSE) {
@@ -229,6 +196,39 @@ static void indication_cb(const uint8_t *pdu, uint16_t len, gpointer user_data)
 	btd_device_gatt_set_service_changed(gas->device, start, end);
 }
 
+static void ccc_written_cb(guint8 status, const guint8 *pdu, guint16 plen,
+							gpointer user_data)
+{
+	struct gas *gas = user_data;
+
+	if (status) {
+		error("Write Service Changed CCC failed: %s",
+						att_ecode2str(status));
+		return;
+	}
+
+	DBG("Service Changed indications enabled");
+
+	gas->changed_ind = g_attrib_register(gas->attrib, ATT_OP_HANDLE_IND,
+						gas->changed_handle,
+						indication_cb, gas, NULL);
+
+	write_ctp_handle(adapter_get_address(device_get_adapter(gas->device)),
+					device_get_address(gas->device),
+					device_get_addr_type(gas->device),
+					GATT_CHARAC_SERVICE_CHANGED,
+					gas->changed_handle);
+}
+
+static void write_ccc(GAttrib *attrib, uint16_t handle, gpointer user_data)
+{
+	uint8_t value[2];
+
+	att_put_u16(GATT_CLIENT_CHARAC_CFG_IND_BIT, value);
+	gatt_write_char(attrib, handle, value, sizeof(value), ccc_written_cb,
+								user_data);
+}
+
 static void gatt_descriptors_cb(guint8 status, const guint8 *pdu, guint16 len,
 							gpointer user_data)
 {
@@ -332,10 +332,6 @@ static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
 		DBG("MTU Exchange: Requesting %d", imtu);
 	}
 
-	gas->changed_ind = g_attrib_register(gas->attrib, ATT_OP_HANDLE_IND,
-						GATTRIB_ALL_HANDLES,
-						indication_cb, gas, NULL);
-
 	if (device_get_appearance(gas->device, &app) < 0) {
 		bt_uuid_t uuid;
 
-- 
1.7.12.2


^ permalink raw reply related

* [RFC BlueZ 4/5] heartrate: Use the per handle GATT event notifier
From: Vinicius Costa Gomes @ 2012-10-09  0:26 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1349742372-18420-1-git-send-email-vinicius.gomes@openbossa.org>

---
 profiles/heartrate/heartrate.c | 287 +++++++++++++++++++++--------------------
 1 file changed, 145 insertions(+), 142 deletions(-)

diff --git a/profiles/heartrate/heartrate.c b/profiles/heartrate/heartrate.c
index d9d6c03..871b74e 100644
--- a/profiles/heartrate/heartrate.c
+++ b/profiles/heartrate/heartrate.c
@@ -260,6 +260,150 @@ static void char_write_cb(guint8 status, const guint8 *pdu, guint16 len,
 	g_free(msg);
 }
 
+static void update_watcher(gpointer data, gpointer user_data)
+{
+	struct watcher *w = data;
+	struct measurement *m = user_data;
+	struct heartrate *hr = m->hr;
+	const gchar *path = device_get_path(hr->dev);
+	DBusMessageIter iter;
+	DBusMessageIter dict;
+	DBusMessage *msg;
+
+	msg = dbus_message_new_method_call(w->srv, w->path,
+			HEART_RATE_WATCHER_INTERFACE, "MeasurementReceived");
+	if (msg == NULL)
+		return;
+
+	dbus_message_iter_init_append(msg, &iter);
+
+	dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH , &path);
+
+	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+	dict_append_entry(&dict, "Value", DBUS_TYPE_UINT16, &m->value);
+
+	if (m->has_energy)
+		dict_append_entry(&dict, "Energy", DBUS_TYPE_UINT16,
+								&m->energy);
+
+	if (m->has_contact)
+		dict_append_entry(&dict, "Contact", DBUS_TYPE_BOOLEAN,
+								&m->contact);
+
+	if (m->num_interval > 0)
+		dict_append_array(&dict, "Interval", DBUS_TYPE_UINT16,
+						&m->interval, m->num_interval);
+
+	dbus_message_iter_close_container(&iter, &dict);
+
+	dbus_message_set_no_reply(msg, TRUE);
+	g_dbus_send_message(btd_get_dbus_connection(), msg);
+}
+
+static void process_measurement(struct heartrate *hr, const uint8_t *pdu,
+								uint16_t len)
+{
+	struct measurement m;
+	uint8_t flags;
+
+	flags = *pdu;
+
+	pdu++;
+	len--;
+
+	memset(&m, 0, sizeof(m));
+
+	if (flags & HR_VALUE_FORMAT) {
+		if (len < 2) {
+			error("Heart Rate Measurement field missing");
+			return;
+		}
+
+		m.value = att_get_u16(pdu);
+		pdu += 2;
+		len -= 2;
+	} else {
+		if (len < 1) {
+			error("Heart Rate Measurement field missing");
+			return;
+		}
+
+		m.value = *pdu;
+		pdu++;
+		len--;
+	}
+
+	if (flags & ENERGY_EXP_STATUS) {
+		if (len < 2) {
+			error("Energy Expended field missing");
+			return;
+		}
+
+		m.has_energy = TRUE;
+		m.energy = att_get_u16(pdu);
+		pdu += 2;
+		len -= 2;
+	}
+
+	if (flags & RR_INTERVAL) {
+		int i;
+
+		if (len == 0 || (len % 2 != 0)) {
+			error("RR-Interval field malformed");
+			return;
+		}
+
+		m.num_interval = len / 2;
+		m.interval = g_new(uint16_t, m.num_interval);
+
+		for (i = 0; i < m.num_interval; pdu += 2, i++)
+			m.interval[i] = att_get_u16(pdu);
+	}
+
+	if (flags & SENSOR_CONTACT_SUPPORT) {
+		m.has_contact = TRUE;
+		m.contact = !!(flags & SENSOR_CONTACT_DETECTED);
+	}
+
+	/* Notify all registered watchers */
+	m.hr = hr;
+	g_slist_foreach(hr->hradapter->watchers, update_watcher, &m);
+
+	g_free(m.interval);
+}
+
+static void notify_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
+{
+	struct heartrate *hr = user_data;
+
+	/* should be at least opcode (1b) + handle (2b) */
+	if (len < 3) {
+		error("Invalid PDU received");
+		return;
+	}
+
+	process_measurement(hr, pdu + 3, len - 3);
+}
+
+static void ccc_write_cb(guint8 status, const guint8 *pdu, guint16 len,
+							gpointer user_data)
+{
+	struct heartrate *hr = user_data;
+
+	if (status != 0) {
+		error("Enable measurement failed");
+		return;
+	}
+
+	hr->attionotid = g_attrib_register(hr->attrib, ATT_OP_HANDLE_NOTIFY,
+						hr->measurement_val_handle,
+						notify_handler, hr, NULL);
+}
+
 static void discover_ccc_cb(guint8 status, const guint8 *pdu,
 						guint16 len, gpointer user_data)
 {
@@ -291,7 +435,6 @@ static void discover_ccc_cb(guint8 status, const guint8 *pdu,
 
 		if (uuid == GATT_CLIENT_CHARAC_CFG_UUID) {
 			uint8_t value[2];
-			char *msg;
 
 			hr->measurement_ccc_handle = handle;
 
@@ -299,10 +442,9 @@ static void discover_ccc_cb(guint8 status, const guint8 *pdu,
 				break;
 
 			att_put_u16(GATT_CLIENT_CHARAC_CFG_NOTIF_BIT, value);
-			msg = g_strdup("Enable measurement");
 
 			gatt_write_char(hr->attrib, handle, value,
-					sizeof(value), char_write_cb, msg);
+					sizeof(value), ccc_write_cb, hr);
 
 			break;
 		}
@@ -399,142 +541,6 @@ static void disable_measurement(gpointer data, gpointer user_data)
 							char_write_cb, msg);
 }
 
-static void update_watcher(gpointer data, gpointer user_data)
-{
-	struct watcher *w = data;
-	struct measurement *m = user_data;
-	struct heartrate *hr = m->hr;
-	const gchar *path = device_get_path(hr->dev);
-	DBusMessageIter iter;
-	DBusMessageIter dict;
-	DBusMessage *msg;
-
-	msg = dbus_message_new_method_call(w->srv, w->path,
-			HEART_RATE_WATCHER_INTERFACE, "MeasurementReceived");
-	if (msg == NULL)
-		return;
-
-	dbus_message_iter_init_append(msg, &iter);
-
-	dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH , &path);
-
-	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
-			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
-			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
-			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
-
-	dict_append_entry(&dict, "Value", DBUS_TYPE_UINT16, &m->value);
-
-	if (m->has_energy)
-		dict_append_entry(&dict, "Energy", DBUS_TYPE_UINT16,
-								&m->energy);
-
-	if (m->has_contact)
-		dict_append_entry(&dict, "Contact", DBUS_TYPE_BOOLEAN,
-								&m->contact);
-
-	if (m->num_interval > 0)
-		dict_append_array(&dict, "Interval", DBUS_TYPE_UINT16,
-						&m->interval, m->num_interval);
-
-	dbus_message_iter_close_container(&iter, &dict);
-
-	dbus_message_set_no_reply(msg, TRUE);
-	g_dbus_send_message(btd_get_dbus_connection(), msg);
-}
-
-static void process_measurement(struct heartrate *hr, const uint8_t *pdu,
-								uint16_t len)
-{
-	struct measurement m;
-	uint8_t flags;
-
-	flags = *pdu;
-
-	pdu++;
-	len--;
-
-	memset(&m, 0, sizeof(m));
-
-	if (flags & HR_VALUE_FORMAT) {
-		if (len < 2) {
-			error("Heart Rate Measurement field missing");
-			return;
-		}
-
-		m.value = att_get_u16(pdu);
-		pdu += 2;
-		len -= 2;
-	} else {
-		if (len < 1) {
-			error("Heart Rate Measurement field missing");
-			return;
-		}
-
-		m.value = *pdu;
-		pdu++;
-		len--;
-	}
-
-	if (flags & ENERGY_EXP_STATUS) {
-		if (len < 2) {
-			error("Energy Expended field missing");
-			return;
-		}
-
-		m.has_energy = TRUE;
-		m.energy = att_get_u16(pdu);
-		pdu += 2;
-		len -= 2;
-	}
-
-	if (flags & RR_INTERVAL) {
-		int i;
-
-		if (len == 0 || (len % 2 != 0)) {
-			error("RR-Interval field malformed");
-			return;
-		}
-
-		m.num_interval = len / 2;
-		m.interval = g_new(uint16_t, m.num_interval);
-
-		for (i = 0; i < m.num_interval; pdu += 2, i++)
-			m.interval[i] = att_get_u16(pdu);
-	}
-
-	if (flags & SENSOR_CONTACT_SUPPORT) {
-		m.has_contact = TRUE;
-		m.contact = !!(flags & SENSOR_CONTACT_DETECTED);
-	}
-
-	/* Notify all registered watchers */
-	m.hr = hr;
-	g_slist_foreach(hr->hradapter->watchers, update_watcher, &m);
-
-	g_free(m.interval);
-}
-
-static void notify_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
-{
-	struct heartrate *hr = user_data;
-	uint16_t handle;
-
-	/* should be at least opcode (1b) + handle (2b) */
-	if (len < 3) {
-		error("Invalid PDU received");
-		return;
-	}
-
-	handle = att_get_u16(pdu + 1);
-	if (handle != hr->measurement_val_handle) {
-		error("Unexpected handle: 0x%04x", handle);
-		return;
-	}
-
-	process_measurement(hr, pdu + 3, len - 3);
-}
-
 static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
 {
 	struct heartrate *hr = user_data;
@@ -543,9 +549,6 @@ static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
 
 	hr->attrib = g_attrib_ref(attrib);
 
-	hr->attionotid = g_attrib_register(hr->attrib, ATT_OP_HANDLE_NOTIFY,
-				GATTRIB_ALL_HANDLES, notify_handler, hr, NULL);
-
 	gatt_discover_char(hr->attrib, hr->svc_range->start, hr->svc_range->end,
 						NULL, discover_char_cb, hr);
 }
-- 
1.7.12.2


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox