* [PATCH v2 11/15] thermometer: Add common function to write characteristics CCC
From: Andrzej Kaczmarek @ 2012-10-01 9:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1349083437-23528-1-git-send-email-andrzej.kaczmarek@tieto.com>
There are now few separate functions to write CCC for measurement
characteristics which looks similar. This patch adds common function
to write given value into CCC for given characteristics and leaves
dedicated functions to act only as simple wrappers.
---
profiles/thermometer/thermometer.c | 108 ++++++++-----------------------------
1 file changed, 23 insertions(+), 85 deletions(-)
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index 27effc3..43c14b0 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -376,7 +376,7 @@ static void valid_range_desc_cb(guint8 status, const guint8 *pdu, guint16 len,
change_property(desc->ch->t, "Minimum", &min);
}
-static void measurement_cb(guint8 status, const guint8 *pdu,
+static void write_ccc_cb(guint8 status, const guint8 *pdu,
guint16 len, gpointer user_data)
{
char *msg = user_data;
@@ -426,7 +426,7 @@ static void process_thermometer_desc(struct descriptor *desc)
att_put_u16(val, atval);
gatt_write_char(ch->t->attrib, desc->handle, atval, 2,
- measurement_cb, msg);
+ write_ccc_cb, msg);
return;
}
@@ -720,9 +720,8 @@ static DBusMessage *set_property(DBusConnection *conn, DBusMessage *msg,
return write_attr_interval(t, msg, value);
}
-static void enable_final_measurement(gpointer data, gpointer user_data)
+static void write_ccc(struct thermometer *t, const char *uuid, uint16_t value)
{
- struct thermometer *t = data;
struct characteristic *ch;
struct descriptor *desc;
bt_uuid_t btuuid;
@@ -732,116 +731,55 @@ static void enable_final_measurement(gpointer data, gpointer user_data)
if (t->attrib == NULL)
return;
- ch = get_characteristic(t, TEMPERATURE_MEASUREMENT_UUID);
+ ch = get_characteristic(t, uuid);
if (ch == NULL) {
- DBG("Temperature measurement characteristic not found");
+ DBG("Characteristic %s not found", uuid);
return;
}
bt_uuid16_create(&btuuid, GATT_CLIENT_CHARAC_CFG_UUID);
desc = get_descriptor(ch, &btuuid);
if (desc == NULL) {
- DBG("Client characteristic configuration descriptor not found");
+ DBG("CCC descriptor for %s not found", uuid);
return;
}
- atval[0] = 0x02;
- atval[1] = 0x00;
- msg = g_strdup("Enable final measurement");
- gatt_write_char(t->attrib, desc->handle, atval, 2, measurement_cb, msg);
+ att_put_u16(value, atval);
+
+ msg = g_strdup_printf("Write CCC: %04x for %s", value, uuid);
+
+ gatt_write_char(t->attrib, desc->handle, atval, sizeof(atval),
+ write_ccc_cb, msg);
}
-static void enable_intermediate_measurement(gpointer data, gpointer user_data)
+static void enable_final_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 || !t->intermediate)
- return;
- ch = get_characteristic(t, INTERMEDIATE_TEMPERATURE_UUID);
- if (ch == NULL) {
- DBG("Intermediate measurement characteristic not found");
- return;
- }
+ write_ccc(t, TEMPERATURE_MEASUREMENT_UUID,
+ GATT_CLIENT_CHARAC_CFG_IND_BIT);
+}
- bt_uuid16_create(&btuuid, GATT_CLIENT_CHARAC_CFG_UUID);
- desc = get_descriptor(ch, &btuuid);
- if (desc == NULL) {
- DBG("Client characteristic configuration descriptor not found");
- return;
- }
+static void enable_intermediate_measurement(gpointer data, gpointer user_data)
+{
+ struct thermometer *t = data;
- atval[0] = 0x01;
- atval[1] = 0x00;
- msg = g_strdup("Enable intermediate measurement");
- gatt_write_char(t->attrib, desc->handle, atval, 2, measurement_cb, msg);
+ write_ccc(t, INTERMEDIATE_TEMPERATURE_UUID,
+ GATT_CLIENT_CHARAC_CFG_NOTIF_BIT);
}
static void disable_final_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)
- return;
-
- ch = get_characteristic(t, TEMPERATURE_MEASUREMENT_UUID);
- if (ch == NULL) {
- DBG("Temperature measurement characteristic not found");
- return;
- }
-
- bt_uuid16_create(&btuuid, GATT_CLIENT_CHARAC_CFG_UUID);
- desc = get_descriptor(ch, &btuuid);
- if (desc == NULL) {
- DBG("Client characteristic configuration descriptor not found");
- return;
- }
-
- atval[0] = 0x00;
- atval[1] = 0x00;
- msg = g_strdup("Disable final measurement");
- gatt_write_char(t->attrib, desc->handle, atval, 2, measurement_cb, msg);
+ write_ccc(t, TEMPERATURE_MEASUREMENT_UUID, 0x0000);
}
static void disable_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)
- return;
-
- ch = get_characteristic(t, INTERMEDIATE_TEMPERATURE_UUID);
- if (ch == NULL) {
- DBG("Intermediate measurement characteristic not found");
- return;
- }
-
- bt_uuid16_create(&btuuid, GATT_CLIENT_CHARAC_CFG_UUID);
- desc = get_descriptor(ch, &btuuid);
- if (desc == NULL) {
- DBG("Client characteristic configuration descriptor not found");
- return;
- }
- atval[0] = 0x00;
- atval[1] = 0x00;
- msg = g_strdup("Disable intermediate measurement");
- gatt_write_char(t->attrib, desc->handle, atval, 2, measurement_cb, msg);
+ write_ccc(t, INTERMEDIATE_TEMPERATURE_UUID, 0x0000);
}
static void remove_int_watcher(struct thermometer_adapter *tadapter,
--
1.7.11.3
^ permalink raw reply related
* [PATCH v2 10/15] thermometer: Add constant definition for watcher interface name
From: Andrzej Kaczmarek @ 2012-10-01 9:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1349083437-23528-1-git-send-email-andrzej.kaczmarek@tieto.com>
---
profiles/thermometer/thermometer.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index 6b5faa2..27effc3 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -44,6 +44,7 @@
#define THERMOMETER_INTERFACE "org.bluez.Thermometer"
#define THERMOMETER_MANAGER_INTERFACE "org.bluez.ThermometerManager"
+#define THERMOMETER_WATCHER_INTERFACE "org.bluez.ThermometerWatcher"
/* Temperature measurement flag fields */
#define TEMP_UNITS 0x01
@@ -1034,7 +1035,7 @@ static void update_watcher(gpointer data, gpointer user_data)
DBusMessage *msg;
msg = dbus_message_new_method_call(w->srv, w->path,
- "org.bluez.ThermometerWatcher",
+ THERMOMETER_WATCHER_INTERFACE,
"MeasurementReceived");
if (msg == NULL)
return;
--
1.7.11.3
^ permalink raw reply related
* [PATCH v2 09/15] thermometer: Update driver naming style
From: Andrzej Kaczmarek @ 2012-10-01 9:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1349083437-23528-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch changes device probe and remove functions name to include
'device' rather than 'driver' name as it better describes what both
do.
Also profile driver name is changed to better describe that it's now
profile driver rather than device driver only.
---
profiles/thermometer/manager.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/profiles/thermometer/manager.c b/profiles/thermometer/manager.c
index 86e3a0f..6057633 100644
--- a/profiles/thermometer/manager.c
+++ b/profiles/thermometer/manager.c
@@ -41,7 +41,7 @@ static gint primary_uuid_cmp(gconstpointer a, gconstpointer b)
return g_strcmp0(prim->uuid, uuid);
}
-static int thermometer_driver_probe(struct btd_profile *p,
+static int thermometer_device_probe(struct btd_profile *p,
struct btd_device *device,
GSList *uuids)
{
@@ -60,7 +60,7 @@ static int thermometer_driver_probe(struct btd_profile *p,
return thermometer_register(device, tattr);
}
-static void thermometer_driver_remove(struct btd_profile *p,
+static void thermometer_device_remove(struct btd_profile *p,
struct btd_device *device)
{
thermometer_unregister(device);
@@ -79,10 +79,10 @@ static void thermometer_adapter_remove(struct btd_profile *p,
}
static struct btd_profile thermometer_profile = {
- .name = "thermometer-device-driver",
+ .name = "Health Thermometer GATT driver",
.remote_uuids = BTD_UUIDS(HEALTH_THERMOMETER_UUID),
- .device_probe = thermometer_driver_probe,
- .device_remove = thermometer_driver_remove,
+ .device_probe = thermometer_device_probe,
+ .device_remove = thermometer_device_remove,
.adapter_probe = thermometer_adapter_probe,
.adapter_remove = thermometer_adapter_remove
};
--
1.7.11.3
^ permalink raw reply related
* [PATCH v2 08/15] thermometer: Change string properties to lower-case
From: Andrzej Kaczmarek @ 2012-10-01 9:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1349083437-23528-1-git-send-email-andrzej.kaczmarek@tieto.com>
---
doc/thermometer-api.txt | 10 +++++-----
profiles/thermometer/thermometer.c | 26 +++++++++++++-------------
2 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/doc/thermometer-api.txt b/doc/thermometer-api.txt
index 0fb28f5..7ae161c 100644
--- a/doc/thermometer-api.txt
+++ b/doc/thermometer-api.txt
@@ -116,7 +116,7 @@ Methods void MeasurementReceived(dict measurement)
string Unit:
- Possible values: "Celsius" or "Fahrenheit"
+ Possible values: "celsius" or "fahrenheit"
uint64 Time (optional):
@@ -127,10 +127,10 @@ Methods void MeasurementReceived(dict measurement)
Only present if measurement type is known.
- Possible values: "Armpit", "Body", "Ear",
- "Finger", "Intestines", "Mouth",
- "Rectum", "Toe", "Tympanum"
+ Possible values: "armpit", "body", "ear",
+ "finger", "intestines", "mouth",
+ "rectum", "toe", "tympanum"
string Measurement:
- Possible values: "Final" or "Intermediate"
+ Possible values: "final" or "intermediate"
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index f0c1d67..6b5faa2 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -120,15 +120,15 @@ static GSList *thermometer_adapters = NULL;
const char *temp_type[] = {
"<reserved>",
- "Armpit",
- "Body",
- "Ear",
- "Finger",
- "Intestines",
- "Mouth",
- "Rectum",
- "Toe",
- "Tympanum"
+ "armpit",
+ "body",
+ "ear",
+ "finger",
+ "intestines",
+ "mouth",
+ "rectum",
+ "toe",
+ "tympanum"
};
static const gchar *temptype2str(uint8_t value)
@@ -1070,7 +1070,7 @@ static void recv_measurement(struct thermometer *t, struct measurement *m)
m->t = t;
- if (g_strcmp0(m->value, "Intermediate") == 0)
+ if (g_strcmp0(m->value, "intermediate") == 0)
wlist = t->tadapter->iwatchers;
else
wlist = t->tadapter->fwatchers;
@@ -1093,9 +1093,9 @@ static void proc_measurement(struct thermometer *t, const uint8_t *pdu,
flags = pdu[3];
if (flags & TEMP_UNITS)
- m.unit = "Fahrenheit";
+ m.unit = "fahrenheit";
else
- m.unit = "Celsius";
+ m.unit = "celsius";
if (len < 8) {
DBG("Temperature measurement value is not provided");
@@ -1153,7 +1153,7 @@ static void proc_measurement(struct thermometer *t, const uint8_t *pdu,
type = NULL;
m.type = type ? g_strdup(type) : NULL;
- m.value = final ? "Final" : "Intermediate";
+ m.value = final ? "final" : "intermediate";
recv_measurement(t, &m);
g_free(m.type);
--
1.7.11.3
^ permalink raw reply related
* [PATCH v2 07/15] thermometer: Reformat MeasurementReceived description
From: Andrzej Kaczmarek @ 2012-10-01 9:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1349083437-23528-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 | 67 +++++++++++++++++++++++++++----------------------
1 file changed, 37 insertions(+), 30 deletions(-)
diff --git a/doc/thermometer-api.txt b/doc/thermometer-api.txt
index 1828811..0fb28f5 100644
--- a/doc/thermometer-api.txt
+++ b/doc/thermometer-api.txt
@@ -97,33 +97,40 @@ 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:
+
+ Measurement value is calculated as
+ (Mantissa) x (10^Exponent)
+
+ In case of invalid or missing data,
+ Exponent is set to 0 and Mantissa is
+ set to 2^23-1 (0x7FFFFF hexadecimal).
+
+ 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 v2 06/15] thermometer: Update test script
From: Andrzej Kaczmarek @ 2012-10-01 9:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1349083437-23528-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 v2 05/15] thermometer: Update API document
From: Andrzej Kaczmarek @ 2012-10-01 9:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1349083437-23528-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 v2 04/15] thermometer: Include remote device information in MeasurementReceived
From: Andrzej Kaczmarek @ 2012-10-01 9:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1349083437-23528-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 4eb67a7..f0c1d67 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 v2 03/15] thermometer: Move watcher logic to adapter interface
From: Andrzej Kaczmarek @ 2012-10-01 9:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1349083437-23528-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 f2568c9..4eb67a7 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 v2 02/15] thermometer: Register ThermometerManager interface on adapter path
From: Andrzej Kaczmarek @ 2012-10-01 9:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1349083437-23528-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 c8a6826..f2568c9 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 v2 01/15] thermometer: Store thermometer devices per-adapter
From: Andrzej Kaczmarek @ 2012-10-01 9:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1349083437-23528-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 77dcb26..c8a6826 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 v2 00/15] Thermometer watchers API changes + fixes
From: Andrzej Kaczmarek @ 2012-10-01 9:23 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
Hi,
Changes since v1:
- fixed inconsistencies and issues in API document formatting
- changed string properties to lower-case (new patch)
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 | 127 ++++-----
profiles/thermometer/manager.c | 24 +-
profiles/thermometer/thermometer.c | 512 +++++++++++++++++++++----------------
profiles/thermometer/thermometer.h | 2 +
test/test-thermometer | 16 +-
5 files changed, 386 insertions(+), 295 deletions(-)
--
1.7.11.3
^ permalink raw reply
* Re: [PATCH] client: Add Message.MarkAsRead and Message.MarkAsDeleted implementation and documentation.
From: Venkateswaran, Srinivasa Ragavan @ 2012-10-01 9:05 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <CABBYNZJLgciDDAjppOYZpeQRrtX7zWyePRyg7Jr3sCGJ=9xz_g@mail.gmail.com>
Hi,
On Mon, Oct 1, 2012 at 1:52 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> Hi Srinivasa,
>
> On Mon, Oct 1, 2012 at 10:14 AM, Venkateswaran, Srinivasa Ragavan
> <srinivasa.ragavan.venkateswaran@intel.com> wrote:
>> On Mon, Oct 1, 2012 at 12:33 PM,
>> <srinivasa.ragavan.venkateswaran@intel.com> wrote:
>>> From: Srinivasa Ragavan <srinivasa.ragavan.venkateswaran@intel.com>
>>>
>>> ---
>>> client/map.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++-
>>> client/transfer.c | 3 +-
>>> doc/client-api.txt | 11 +++++
>>> 3 files changed, 127 insertions(+), 2 deletions(-)
>>
>> Ignore this patch, this has a partial patch I was trying from Luiz.
>> Sorry for the mess, sent an updated one.
>>
>> -Srini.
>
> I just merged some fix last week so you would have to rebase your
> changes, but I got some suggestions:
Oh sorry, I will rebase with my updated patch after fixing the issues
mentioned below.
>
> 1. Use properties, so for setting delete/read the application should
> use SetProperty method and it can get the values with GetProperties
> and PropertyChanged to signal when the values has changed. (Note this
> may change if we add support to standard D-Bus Properties interface
> but the idea is the same just the interface change)
I'll do it as SetProperty ("read/deleted", true/false) . But I don't
see a support in MAP ('s spec) for getting a message status or being
notified for message update. If you can point me, I could do this also
and give a complete patch the Message object.
> 2. What is this filler byte and lseek for?
lseek was because, after just we write to the file, the read always
failed and I thought the position was the end of the file. I just seek
to the beginning of the file, it worked. I hope I didn't overlook
something.
> 3. We probably need to add support for non-body/apparam only PUT so we
> can pass NULL to filename. (maybe this is the reason for 2?)
For SetMessageStatus the spec mentioned that Body/End of Body,
specifying the filler byte 0x30 is mandatory. Quoting from the spec
below:
"To avoid PUT with empty Body leading to a 'delete' of the related message these
headers shall contain a filler byte. The value of this byte shall be
set to 0x30 (="0")."
If it wasn't for this, I would have updated PUT with support to empty
body. I assume, this is fine.
Thanks,
-Srini.
>
> --
> Luiz Augusto von Dentz
^ permalink raw reply
* Re: [RFCv1 17/20] Bluetooth: Ignore BR/EDR packet size constraints when fragmenting for AMP
From: Andrei Emeltchenko @ 2012-10-01 8:46 UTC (permalink / raw)
To: Mat Martineau; +Cc: linux-bluetooth, gustavo, sunnyk
In-Reply-To: <1347387691-5285-18-git-send-email-mathewm@codeaurora.org>
Hi,
On Tue, Sep 11, 2012 at 11:21:28AM -0700, Mat Martineau wrote:
> When operating over BR/EDR, ERTM accounts for the maximum over-the-air
> packet size when setting the PDU size. AMP controllers do not use the
> same over-the-air packets, so the PDU size should only be based on the
> HCI MTU of the AMP controller.
>
> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
Acked-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Best regards
Andrei Emeltchenko
^ permalink raw reply
* Re: [PATCH BlueZ v0 0/4] Fix losing Service Changed indication
From: Johan Hedberg @ 2012-10-01 8:42 UTC (permalink / raw)
To: Claudio Takahasi; +Cc: linux-bluetooth
In-Reply-To: <1348843674-10878-1-git-send-email-claudio.takahasi@openbossa.org>
Hi Claudio,
On Fri, Sep 28, 2012, Claudio Takahasi wrote:
> Apply after:
> "gatt: Remove reading Service Changed characteristic after connected"
> sent from Andrzej Kaczmarek
>
> This patch series adds Service Changed characteristic handle storage
> allowing GATT service to manage Service Changed indication when the
> connection is established.
>
> The patch to remove the entry from "gatt" file will be sent in the next
> patch series. It is unclear to me if we need to extend the device or
> profile drive to indicate that the device is being removed/purged from
> the system or if the expected implementation is to move to per-device
> storage(TODO file). At the moment, it is not possible to detect in the
> drivers remove callback if the device is being removed from the system
> or if it bluetoothd is exiting.
>
>
> Claudio Takahasi (4):
> gatt: Remove unneeded handle range check
> gatt: Ignore Service Changed if not bonded
> gatt: Add storing Service Changed handle
> gatt: Add reading stored Service Changed handle
>
> profiles/gatt/gas.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 83 insertions(+), 7 deletions(-)
All patches in this set have been applied. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH v4] HID: Add support for Sony PS3 BD Remote Control
From: Antonio Ospite @ 2012-10-01 8:40 UTC (permalink / raw)
To: Jiri Kosina
Cc: David Dillow, linux-bluetooth, David Herrmann,
Luiz Augusto von Dentz, Bastien Nocera, linux-input
In-Reply-To: <alpine.LNX.2.00.1210011023380.27440@pobox.suse.cz>
On Mon, 1 Oct 2012 10:24:01 +0200 (CEST)
Jiri Kosina <jkosina@suse.cz> wrote:
> On Mon, 1 Oct 2012, Antonio Ospite wrote:
>
> > Ping.
> >
> > Jiri, I see that linux-3.6 is out, can we have this in for 3.7-rc1?
>
> As replied earlier today, it's in my for-next branch and I'll be pushing
> that for 3.7-rc1.
>
Thanks. I've just seen your message, I hadn't got it yet when I wrote
mine :)
Regards,
Antonio
--
Antonio Ospite
http://ao2.it
A: Because it messes up the order in which people normally read text.
See http://en.wikipedia.org/wiki/Posting_style
Q: Why is top-posting such a bad thing?
^ permalink raw reply
* Re: [PATCH v2] gatt: Remove reading Service Changed characteristic after connected
From: Johan Hedberg @ 2012-10-01 8:38 UTC (permalink / raw)
To: Andrzej Kaczmarek; +Cc: linux-bluetooth
In-Reply-To: <1346939130-22075-1-git-send-email-andrzej.kaczmarek@tieto.com>
Hi Andrzej,
On Thu, Sep 06, 2012, Andrzej Kaczmarek wrote:
> Service Changed characteristic is a control-point attribute thus it
> cannot be read and attempting to do so will fail. Instead, server
> shall send indication once enabled in CCC.
>
> This change is due to "Erratum 3833 - Service Changed" (ESR05) which
> changed characteristic value properties from 0x26 to 0x20.
> ---
> profiles/gatt/gas.c | 37 -------------------------------------
> 1 file changed, 37 deletions(-)
Applied. Thanks.
Johan
^ permalink raw reply
* Re: [RFCv1 04/20] Bluetooth: Process create response and connect response identically
From: Andrei Emeltchenko @ 2012-10-01 8:37 UTC (permalink / raw)
To: Mat Martineau; +Cc: linux-bluetooth, gustavo, sunnyk
In-Reply-To: <1347387691-5285-5-git-send-email-mathewm@codeaurora.org>
Hi,
On Tue, Sep 11, 2012 at 11:21:15AM -0700, Mat Martineau wrote:
> This removes an intermediate function for sending a create response
> which added no functionality.
>
> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
Acked-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Best regards
Andrei Emeltchenko
^ permalink raw reply
* Re: [PATCH BlueZ v7 2/9] mgmt: Add LE scanning callback
From: Johan Hedberg @ 2012-10-01 8:36 UTC (permalink / raw)
To: Claudio Takahasi; +Cc: João Paulo Rechi Vita, linux-bluetooth
In-Reply-To: <CAKT1EBdhhqsEU9_zxcAHArtpwzzOo2hmwDmz91SrYNQeiEdEJw@mail.gmail.com>
Hi Claudio,
On Fri, Sep 28, 2012, Claudio Takahasi wrote:
> On Thu, Sep 27, 2012 at 4:43 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> > On Tue, Sep 25, 2012, João Paulo Rechi Vita wrote:
> >> +int mgmt_start_scanning(int index)
> >
> > Firstly I don't think the name is good since BR/EDR also has the concept
> > of scanning (page scan & inquiry scan). Secondly, maybe it'd be simpler
> > to reuse mgmt_start_discovery and simply add a new parameter which
> > provides the value for info->discov_type?
>
> My suggestions are:
> 1. rename to mgmt_start_le_scanning
> 2. add a new parameter to mgmt_start_discovery: gboolean le_only
> 3. add a new parameter to mgmt_start_discovery: informing the adapter
> operation mode(BREDR/LE/BREDR_LE)
>
> Option 3 will require to expose controller info/settings to adapter.c.
> It is necessary to know the controller features to send the right
> discover type. btd_adapter_start function could be extended to receive
> the supported features or a parameter specifying the operation mode.
> IMO, using this approach we are duplicating information.
>
> Which approach do you prefer?
I'd go with 1 for now. Booleans in places where it's not utterly clear
from the calling code what it means shouldn't be used (even enums are
better), i.e. if you don't know the implementation details of the
function there'd be no way for an outsider to know what exactly the
"TRUE" in mgmt_start_discovery(TRUE) means.
Johan
^ permalink raw reply
* Re: [RFCv1 02/20] Bluetooth: Factor out common L2CAP connection code
From: Andrei Emeltchenko @ 2012-10-01 8:30 UTC (permalink / raw)
To: Mat Martineau; +Cc: linux-bluetooth, gustavo, sunnyk
In-Reply-To: <1347387691-5285-3-git-send-email-mathewm@codeaurora.org>
Hi,
On Tue, Sep 11, 2012 at 11:21:13AM -0700, Mat Martineau wrote:
> L2CAP connect requests and create channel requests share a significant
> amount of code. This change moves common code to a new function.
>
> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
Acked-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Best regards
Andrei Emeltchenko
^ permalink raw reply
* Re: [RFC] Convert storage to use per-remote device directories
From: Johan Hedberg @ 2012-10-01 8:30 UTC (permalink / raw)
To: Anderson Lizardo; +Cc: Frederic Danis, linux-bluetooth@vger.kernel.org
In-Reply-To: <CAJdJm_O+8tWER69LEbz9oMeoadfp=gGT3_6V0=fY-LDZ8B90kA@mail.gmail.com>
Hi Lizardo,
On Fri, Sep 28, 2012, Anderson Lizardo wrote:
> > Is it possible to save it as we did for SDP records (record entry in profile
> > group) ?
>
> It seems the SDP records have the UUID as group on the INI file. This
> is not feasible for GATT/ATT because the UUID is not a unique key, but
> the attribute handle is.
>
> Are you sure that for SDP each record has its own UUID (i.e. no SDP
> record shares same UUID)?
There's no such restriction for BR/EDR. As with ATT the only unique
identifier is the SDP record handle, however (at least with SDP) I think
this is only guaranteed to have the same value for a single connection ,
i.e. in theory subsequent connections could have the same record behind
a different handle.
Johan
^ permalink raw reply
* Re: [RFCv1 01/20] Bluetooth: Add new l2cap_chan struct members for high speed channels
From: Andrei Emeltchenko @ 2012-10-01 8:29 UTC (permalink / raw)
To: Mat Martineau; +Cc: linux-bluetooth, gustavo, sunnyk
In-Reply-To: <1347387691-5285-2-git-send-email-mathewm@codeaurora.org>
Hi,
On Tue, Sep 11, 2012 at 11:21:12AM -0700, Mat Martineau wrote:
> An L2CAP channel using high speed continues to be associated with a
> BR/EDR l2cap_conn, while also tracking an additional hci_conn
> (representing a physical link on a high speed controller) and hci_chan
> (representing a logical link). There may only be one physical link
> between two high speed controllers. Each physical link may contain
> several logical links, with each logical link representing a channel
> with specific quality of service.
>
> During a channel move, the destination channel id, current move state,
> and role (initiator vs. responder) are tracked and used by the channel
> move state machine. The ident value associated with a move request
> must also be stored in order to use it in later move responses.
>
> The active channel is stored in local_amp_id.
>
> Signed-off-by: Mat Martineau <mathewm@codeaurora.org>
Acked-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Best regards
Andrei Emeltchenko
^ permalink raw reply
* Re: [PATCH v4] HID: Add support for Sony PS3 BD Remote Control
From: Jiri Kosina @ 2012-10-01 8:24 UTC (permalink / raw)
To: Antonio Ospite
Cc: David Dillow, linux-bluetooth, David Herrmann,
Luiz Augusto von Dentz, Bastien Nocera, linux-input
In-Reply-To: <20121001101938.d7736c5e1faf179cb06dcd9a@studenti.unina.it>
On Mon, 1 Oct 2012, Antonio Ospite wrote:
> Ping.
>
> Jiri, I see that linux-3.6 is out, can we have this in for 3.7-rc1?
As replied earlier today, it's in my for-next branch and I'll be pushing
that for 3.7-rc1.
--
Jiri Kosina
SUSE Labs
^ permalink raw reply
* Re: [PATCH] client: Add Message.MarkAsRead and Message.MarkAsDeleted implementation and documentation.
From: Luiz Augusto von Dentz @ 2012-10-01 8:22 UTC (permalink / raw)
To: Venkateswaran, Srinivasa Ragavan; +Cc: linux-bluetooth
In-Reply-To: <CAEd0BX9Mhz_SobzniiqXaXhEFC4gEaPfepubkY59TOpiCA+3ug@mail.gmail.com>
Hi Srinivasa,
On Mon, Oct 1, 2012 at 10:14 AM, Venkateswaran, Srinivasa Ragavan
<srinivasa.ragavan.venkateswaran@intel.com> wrote:
> On Mon, Oct 1, 2012 at 12:33 PM,
> <srinivasa.ragavan.venkateswaran@intel.com> wrote:
>> From: Srinivasa Ragavan <srinivasa.ragavan.venkateswaran@intel.com>
>>
>> ---
>> client/map.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++-
>> client/transfer.c | 3 +-
>> doc/client-api.txt | 11 +++++
>> 3 files changed, 127 insertions(+), 2 deletions(-)
>
> Ignore this patch, this has a partial patch I was trying from Luiz.
> Sorry for the mess, sent an updated one.
>
> -Srini.
I just merged some fix last week so you would have to rebase your
changes, but I got some suggestions:
1. Use properties, so for setting delete/read the application should
use SetProperty method and it can get the values with GetProperties
and PropertyChanged to signal when the values has changed. (Note this
may change if we add support to standard D-Bus Properties interface
but the idea is the same just the interface change)
2. What is this filler byte and lseek for?
3. We probably need to add support for non-body/apparam only PUT so we
can pass NULL to filename. (maybe this is the reason for 2?)
--
Luiz Augusto von Dentz
^ permalink raw reply
* Re: [PATCH v4] HID: Add support for Sony PS3 BD Remote Control
From: Antonio Ospite @ 2012-10-01 8:19 UTC (permalink / raw)
To: David Dillow
Cc: linux-bluetooth, David Herrmann, Luiz Augusto von Dentz,
Bastien Nocera, linux-input, Jiri Kosina, Antonio Ospite
In-Reply-To: <1348606947-3055-1-git-send-email-ospite@studenti.unina.it>
On Tue, 25 Sep 2012 23:02:27 +0200
Antonio Ospite <ospite@studenti.unina.it> wrote:
Ping.
Jiri, I see that linux-3.6 is out, can we have this in for 3.7-rc1?
Thanks,
Antonio
> From: David Dillow <dave@thedillows.org>
>
> The Sony PS3 Blue-ray Disc Remote Control used to be supported by the
> BlueZ project's user space, but the code that handled it was recently
> removed as its functionality conflicted with a real HSP implementation
> and the mapping was thought to be better handled in the kernel. This is
> a port of the mapping logic from the fakehid driver by Marcel Holtmann
> to the in-kernel HID layer.
>
> We also add support for the Logitech Harmony Adapter for PS3, which
> emulates the BD Remote.
>
> Signed-off-by: David Dillow <dave@thedillows.org>
> Signed-off-by: Antonio Ospite <ospite@studenti.unina.it>
> ---
>
> Changes since v3:
> - move the size check into the switch statement.
>
> Thanks,
> Antonio
>
> drivers/hid/Kconfig | 13 ++-
> drivers/hid/Makefile | 1 +
> drivers/hid/hid-core.c | 2 +
> drivers/hid/hid-ids.h | 2 +
> drivers/hid/hid-ps3remote.c | 215 +++++++++++++++++++++++++++++++++++++++++++
> 5 files changed, 232 insertions(+), 1 deletion(-)
> create mode 100644 drivers/hid/hid-ps3remote.c
>
> diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig
> index fbf4950..378be0b 100644
> --- a/drivers/hid/Kconfig
> +++ b/drivers/hid/Kconfig
> @@ -534,6 +534,15 @@ config HID_PRIMAX
> Support for Primax devices that are not fully compliant with the
> HID standard.
>
> +config HID_PS3REMOTE
> + tristate "Sony PS3 BD Remote Control"
> + depends on BT_HIDP
> + ---help---
> + Support for the Sony PS3 Blue-ray Disk Remote Control and Logitech
> + Harmony Adapter for PS3, which connect over Bluetooth.
> +
> + Support for the 6-axis controllers is provided by HID_SONY.
> +
> config HID_ROCCAT
> tristate "Roccat device support"
> depends on USB_HID
> @@ -561,7 +570,9 @@ config HID_SONY
> tristate "Sony PS3 controller"
> depends on USB_HID
> ---help---
> - Support for Sony PS3 controller.
> + Support for Sony PS3 6-axis controllers.
> +
> + Support for the Sony PS3 BD Remote is provided by HID_PS3REMOTE.
>
> config HID_SPEEDLINK
> tristate "Speedlink VAD Cezanne mouse support"
> diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile
> index f975485..333ed6c 100644
> --- a/drivers/hid/Makefile
> +++ b/drivers/hid/Makefile
> @@ -70,6 +70,7 @@ obj-$(CONFIG_HID_PANTHERLORD) += hid-pl.o
> obj-$(CONFIG_HID_PETALYNX) += hid-petalynx.o
> obj-$(CONFIG_HID_PICOLCD) += hid-picolcd.o
> obj-$(CONFIG_HID_PRIMAX) += hid-primax.o
> +obj-$(CONFIG_HID_PS3REMOTE) += hid-ps3remote.o
> obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \
> hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \
> hid-roccat-koneplus.o hid-roccat-kovaplus.o hid-roccat-pyra.o \
> diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
> index 8bcd168..e4275d4 100644
> --- a/drivers/hid/hid-core.c
> +++ b/drivers/hid/hid-core.c
> @@ -1566,6 +1566,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
> { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER) },
> { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_S510_RECEIVER_2) },
> { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_RECEIVER) },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) },
> { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_DESKTOP) },
> { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_EDGE) },
> { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_DINOVO_MINI) },
> @@ -1639,6 +1640,7 @@ static const struct hid_device_id hid_have_special_driver[] = {
> { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_IR_REMOTE) },
> { HID_USB_DEVICE(USB_VENDOR_ID_SAMSUNG, USB_DEVICE_ID_SAMSUNG_WIRELESS_KBD_MOUSE) },
> { HID_USB_DEVICE(USB_VENDOR_ID_SKYCABLE, USB_DEVICE_ID_SKYCABLE_WIRELESS_PRESENTER) },
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) },
> { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
> { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER) },
> { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER) },
> diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
> index 1dcb76f..40411c9 100644
> --- a/drivers/hid/hid-ids.h
> +++ b/drivers/hid/hid-ids.h
> @@ -496,6 +496,7 @@
> #define USB_DEVICE_ID_LOGITECH_RECEIVER 0xc101
> #define USB_DEVICE_ID_LOGITECH_HARMONY_FIRST 0xc110
> #define USB_DEVICE_ID_LOGITECH_HARMONY_LAST 0xc14f
> +#define USB_DEVICE_ID_LOGITECH_HARMONY_PS3 0x0306
> #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD_CORD 0xc20a
> #define USB_DEVICE_ID_LOGITECH_RUMBLEPAD 0xc211
> #define USB_DEVICE_ID_LOGITECH_EXTREME_3D 0xc215
> @@ -683,6 +684,7 @@
>
> #define USB_VENDOR_ID_SONY 0x054c
> #define USB_DEVICE_ID_SONY_VAIO_VGX_MOUSE 0x024b
> +#define USB_DEVICE_ID_SONY_PS3_BDREMOTE 0x0306
> #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268
> #define USB_DEVICE_ID_SONY_NAVIGATION_CONTROLLER 0x042f
>
> diff --git a/drivers/hid/hid-ps3remote.c b/drivers/hid/hid-ps3remote.c
> new file mode 100644
> index 0000000..03811e5
> --- /dev/null
> +++ b/drivers/hid/hid-ps3remote.c
> @@ -0,0 +1,215 @@
> +/*
> + * HID driver for Sony PS3 BD Remote Control
> + *
> + * Copyright (c) 2012 David Dillow <dave@thedillows.org>
> + * Based on a blend of the bluez fakehid user-space code by Marcel Holtmann
> + * and other kernel HID drivers.
> + */
> +
> +/*
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the Free
> + * Software Foundation; either version 2 of the License, or (at your option)
> + * any later version.
> + */
> +
> +/* NOTE: in order for the Sony PS3 BD Remote Control to be found by
> + * a Bluetooth host, the key combination Start+Enter has to be kept pressed
> + * for about 7 seconds with the Bluetooth Host Controller in discovering mode.
> + *
> + * There will be no PIN request from the device.
> + */
> +
> +#include <linux/device.h>
> +#include <linux/hid.h>
> +#include <linux/module.h>
> +
> +#include "hid-ids.h"
> +
> +static __u8 ps3remote_rdesc[] = {
> + 0x05, 0x01, /* GUsagePage Generic Desktop */
> + 0x09, 0x05, /* LUsage 0x05 [Game Pad] */
> + 0xA1, 0x01, /* MCollection Application (mouse, keyboard) */
> +
> + /* Use collection 1 for joypad buttons */
> + 0xA1, 0x02, /* MCollection Logical (interrelated data) */
> +
> + /* Ignore the 1st byte, maybe it is used for a controller
> + * number but it's not needed for correct operation */
> + 0x75, 0x08, /* GReportSize 0x08 [8] */
> + 0x95, 0x01, /* GReportCount 0x01 [1] */
> + 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
> +
> + /* Bytes from 2nd to 4th are a bitmap for joypad buttons, for these
> + * buttons multiple keypresses are allowed */
> + 0x05, 0x09, /* GUsagePage Button */
> + 0x19, 0x01, /* LUsageMinimum 0x01 [Button 1 (primary/trigger)] */
> + 0x29, 0x18, /* LUsageMaximum 0x18 [Button 24] */
> + 0x14, /* GLogicalMinimum [0] */
> + 0x25, 0x01, /* GLogicalMaximum 0x01 [1] */
> + 0x75, 0x01, /* GReportSize 0x01 [1] */
> + 0x95, 0x18, /* GReportCount 0x18 [24] */
> + 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
> +
> + 0xC0, /* MEndCollection */
> +
> + /* Use collection 2 for remote control buttons */
> + 0xA1, 0x02, /* MCollection Logical (interrelated data) */
> +
> + /* 5th byte is used for remote control buttons */
> + 0x05, 0x09, /* GUsagePage Button */
> + 0x18, /* LUsageMinimum [No button pressed] */
> + 0x29, 0xFE, /* LUsageMaximum 0xFE [Button 254] */
> + 0x14, /* GLogicalMinimum [0] */
> + 0x26, 0xFE, 0x00, /* GLogicalMaximum 0x00FE [254] */
> + 0x75, 0x08, /* GReportSize 0x08 [8] */
> + 0x95, 0x01, /* GReportCount 0x01 [1] */
> + 0x80, /* MInput */
> +
> + /* Ignore bytes from 6th to 11th, 6th to 10th are always constant at
> + * 0xff and 11th is for press indication */
> + 0x75, 0x08, /* GReportSize 0x08 [8] */
> + 0x95, 0x06, /* GReportCount 0x06 [6] */
> + 0x81, 0x01, /* MInput 0x01 (Const[0] Arr[1] Abs[2]) */
> +
> + /* 12th byte is for battery strength */
> + 0x05, 0x06, /* GUsagePage Generic Device Controls */
> + 0x09, 0x20, /* LUsage 0x20 [Battery Strength] */
> + 0x14, /* GLogicalMinimum [0] */
> + 0x25, 0x05, /* GLogicalMaximum 0x05 [5] */
> + 0x75, 0x08, /* GReportSize 0x08 [8] */
> + 0x95, 0x01, /* GReportCount 0x01 [1] */
> + 0x81, 0x02, /* MInput 0x02 (Data[0] Var[1] Abs[2]) */
> +
> + 0xC0, /* MEndCollection */
> +
> + 0xC0 /* MEndCollection [Game Pad] */
> +};
> +
> +static const unsigned int ps3remote_keymap_joypad_buttons[] = {
> + [0x01] = KEY_SELECT,
> + [0x02] = BTN_THUMBL, /* L3 */
> + [0x03] = BTN_THUMBR, /* R3 */
> + [0x04] = BTN_START,
> + [0x05] = KEY_UP,
> + [0x06] = KEY_RIGHT,
> + [0x07] = KEY_DOWN,
> + [0x08] = KEY_LEFT,
> + [0x09] = BTN_TL2, /* L2 */
> + [0x0a] = BTN_TR2, /* R2 */
> + [0x0b] = BTN_TL, /* L1 */
> + [0x0c] = BTN_TR, /* R1 */
> + [0x0d] = KEY_OPTION, /* options/triangle */
> + [0x0e] = KEY_BACK, /* back/circle */
> + [0x0f] = BTN_0, /* cross */
> + [0x10] = KEY_SCREEN, /* view/square */
> + [0x11] = KEY_HOMEPAGE, /* PS button */
> + [0x14] = KEY_ENTER,
> +};
> +static const unsigned int ps3remote_keymap_remote_buttons[] = {
> + [0x00] = KEY_1,
> + [0x01] = KEY_2,
> + [0x02] = KEY_3,
> + [0x03] = KEY_4,
> + [0x04] = KEY_5,
> + [0x05] = KEY_6,
> + [0x06] = KEY_7,
> + [0x07] = KEY_8,
> + [0x08] = KEY_9,
> + [0x09] = KEY_0,
> + [0x0e] = KEY_ESC, /* return */
> + [0x0f] = KEY_CLEAR,
> + [0x16] = KEY_EJECTCD,
> + [0x1a] = KEY_MENU, /* top menu */
> + [0x28] = KEY_TIME,
> + [0x30] = KEY_PREVIOUS,
> + [0x31] = KEY_NEXT,
> + [0x32] = KEY_PLAY,
> + [0x33] = KEY_REWIND, /* scan back */
> + [0x34] = KEY_FORWARD, /* scan forward */
> + [0x38] = KEY_STOP,
> + [0x39] = KEY_PAUSE,
> + [0x40] = KEY_CONTEXT_MENU, /* pop up/menu */
> + [0x60] = KEY_FRAMEBACK, /* slow/step back */
> + [0x61] = KEY_FRAMEFORWARD, /* slow/step forward */
> + [0x63] = KEY_SUBTITLE,
> + [0x64] = KEY_AUDIO,
> + [0x65] = KEY_ANGLE,
> + [0x70] = KEY_INFO, /* display */
> + [0x80] = KEY_BLUE,
> + [0x81] = KEY_RED,
> + [0x82] = KEY_GREEN,
> + [0x83] = KEY_YELLOW,
> +};
> +
> +static __u8 *ps3remote_fixup(struct hid_device *hdev, __u8 *rdesc,
> + unsigned int *rsize)
> +{
> + *rsize = sizeof(ps3remote_rdesc);
> + return ps3remote_rdesc;
> +}
> +
> +static int ps3remote_mapping(struct hid_device *hdev, struct hid_input *hi,
> + struct hid_field *field, struct hid_usage *usage,
> + unsigned long **bit, int *max)
> +{
> + unsigned int key = usage->hid & HID_USAGE;
> +
> + if ((usage->hid & HID_USAGE_PAGE) != HID_UP_BUTTON)
> + return -1;
> +
> + switch (usage->collection_index) {
> + case 1:
> + if (key >= ARRAY_SIZE(ps3remote_keymap_joypad_buttons))
> + return -1;
> +
> + key = ps3remote_keymap_joypad_buttons[key];
> + if (!key)
> + return -1;
> + break;
> + case 2:
> + if (key >= ARRAY_SIZE(ps3remote_keymap_remote_buttons))
> + return -1;
> +
> + key = ps3remote_keymap_remote_buttons[key];
> + if (!key)
> + return -1;
> + break;
> + default:
> + return -1;
> + }
> +
> + hid_map_usage_clear(hi, usage, bit, max, EV_KEY, key);
> + return 1;
> +}
> +
> +static const struct hid_device_id ps3remote_devices[] = {
> + /* PS3 BD Remote Control */
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_BDREMOTE) },
> + /* Logitech Harmony Adapter for PS3 */
> + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_HARMONY_PS3) },
> + { }
> +};
> +MODULE_DEVICE_TABLE(hid, ps3remote_devices);
> +
> +static struct hid_driver ps3remote_driver = {
> + .name = "ps3_remote",
> + .id_table = ps3remote_devices,
> + .report_fixup = ps3remote_fixup,
> + .input_mapping = ps3remote_mapping,
> +};
> +
> +static int __init ps3remote_init(void)
> +{
> + return hid_register_driver(&ps3remote_driver);
> +}
> +
> +static void __exit ps3remote_exit(void)
> +{
> + hid_unregister_driver(&ps3remote_driver);
> +}
> +
> +module_init(ps3remote_init);
> +module_exit(ps3remote_exit);
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("David Dillow <dave@thedillows.org>, Antonio Ospite <ospite@studenti.unina.it>");
> --
> 1.7.10.4
>
>
--
Antonio Ospite
http://ao2.it
A: Because it messes up the order in which people normally read text.
See http://en.wikipedia.org/wiki/Posting_style
Q: Why is top-posting such a bad thing?
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox