* [PATCH BlueZ 2/2] audio: Move to profiles directory
From: Luiz Augusto von Dentz @ 2012-11-08 15:25 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1352388350-29194-1-git-send-email-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
In addiction fix the include path to profiles and change avinfo to use
audio path when including a2dp-codecs.h
---
Makefile.am | 52 +++++++++++++++-------------
{audio => profiles/audio}/a2dp-codecs.h | 0
{audio => profiles/audio}/a2dp.c | 0
{audio => profiles/audio}/a2dp.h | 0
{audio => profiles/audio}/audio.conf | 0
{audio => profiles/audio}/avctp.c | 0
{audio => profiles/audio}/avctp.h | 0
{audio => profiles/audio}/avdtp.c | 0
{audio => profiles/audio}/avdtp.h | 0
{audio => profiles/audio}/avrcp.c | 0
{audio => profiles/audio}/avrcp.h | 0
{audio => profiles/audio}/control.c | 0
{audio => profiles/audio}/control.h | 0
{audio => profiles/audio}/device.c | 0
{audio => profiles/audio}/device.h | 0
{audio => profiles/audio}/gateway.c | 0
{audio => profiles/audio}/gateway.h | 0
{audio => profiles/audio}/headset.c | 0
{audio => profiles/audio}/headset.h | 0
{audio => profiles/audio}/main.c | 0
{audio => profiles/audio}/manager.c | 0
{audio => profiles/audio}/manager.h | 0
{audio => profiles/audio}/media.c | 0
{audio => profiles/audio}/media.h | 0
{audio => profiles/audio}/player.c | 0
{audio => profiles/audio}/player.h | 0
{audio => profiles/audio}/rtp.h | 0
{audio => profiles/audio}/sink.c | 0
{audio => profiles/audio}/sink.h | 0
{audio => profiles/audio}/source.c | 0
{audio => profiles/audio}/source.h | 0
{audio => profiles/audio}/telephony-dummy.c | 0
{audio => profiles/audio}/telephony-maemo5.c | 0
{audio => profiles/audio}/telephony-maemo6.c | 0
{audio => profiles/audio}/telephony-ofono.c | 0
{audio => profiles/audio}/telephony.h | 0
{audio => profiles/audio}/transport.c | 0
{audio => profiles/audio}/transport.h | 0
tools/avinfo.c | 2 +-
39 files changed, 28 insertions(+), 26 deletions(-)
rename {audio => profiles/audio}/a2dp-codecs.h (100%)
rename {audio => profiles/audio}/a2dp.c (100%)
rename {audio => profiles/audio}/a2dp.h (100%)
rename {audio => profiles/audio}/audio.conf (100%)
rename {audio => profiles/audio}/avctp.c (100%)
rename {audio => profiles/audio}/avctp.h (100%)
rename {audio => profiles/audio}/avdtp.c (100%)
rename {audio => profiles/audio}/avdtp.h (100%)
rename {audio => profiles/audio}/avrcp.c (100%)
rename {audio => profiles/audio}/avrcp.h (100%)
rename {audio => profiles/audio}/control.c (100%)
rename {audio => profiles/audio}/control.h (100%)
rename {audio => profiles/audio}/device.c (100%)
rename {audio => profiles/audio}/device.h (100%)
rename {audio => profiles/audio}/gateway.c (100%)
rename {audio => profiles/audio}/gateway.h (100%)
rename {audio => profiles/audio}/headset.c (100%)
rename {audio => profiles/audio}/headset.h (100%)
rename {audio => profiles/audio}/main.c (100%)
rename {audio => profiles/audio}/manager.c (100%)
rename {audio => profiles/audio}/manager.h (100%)
rename {audio => profiles/audio}/media.c (100%)
rename {audio => profiles/audio}/media.h (100%)
rename {audio => profiles/audio}/player.c (100%)
rename {audio => profiles/audio}/player.h (100%)
rename {audio => profiles/audio}/rtp.h (100%)
rename {audio => profiles/audio}/sink.c (100%)
rename {audio => profiles/audio}/sink.h (100%)
rename {audio => profiles/audio}/source.c (100%)
rename {audio => profiles/audio}/source.h (100%)
rename {audio => profiles/audio}/telephony-dummy.c (100%)
rename {audio => profiles/audio}/telephony-maemo5.c (100%)
rename {audio => profiles/audio}/telephony-maemo6.c (100%)
rename {audio => profiles/audio}/telephony-ofono.c (100%)
rename {audio => profiles/audio}/telephony.h (100%)
rename {audio => profiles/audio}/transport.c (100%)
rename {audio => profiles/audio}/transport.h (100%)
diff --git a/Makefile.am b/Makefile.am
index b069c03..47c24ed 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -105,29 +105,31 @@ endif
if AUDIOPLUGIN
builtin_modules += audio
-builtin_sources += audio/main.c \
- audio/manager.h audio/manager.c \
- audio/gateway.h audio/gateway.c \
- audio/headset.h audio/headset.c \
- audio/control.h audio/control.c \
- audio/avctp.h audio/avctp.c \
- audio/avrcp.h audio/avrcp.c \
- audio/device.h audio/device.c \
- audio/source.h audio/source.c \
- audio/sink.h audio/sink.c \
- audio/a2dp.h audio/a2dp.c \
- audio/avdtp.h audio/avdtp.c \
- audio/media.h audio/media.c \
- audio/transport.h audio/transport.c \
- audio/player.h audio/player.c \
- audio/telephony.h audio/a2dp-codecs.h
-builtin_nodist += audio/telephony.c
-
-noinst_LIBRARIES += audio/libtelephony.a
-
-audio_libtelephony_a_SOURCES = audio/telephony.h audio/telephony-dummy.c \
- audio/telephony-maemo5.c audio/telephony-ofono.c \
- audio/telephony-maemo6.c
+builtin_sources += profiles/audio/main.c \
+ profiles/audio/manager.h profiles/audio/manager.c \
+ profiles/audio/gateway.h profiles/audio/gateway.c \
+ profiles/audio/headset.h profiles/audio/headset.c \
+ profiles/audio/control.h profiles/audio/control.c \
+ profiles/audio/avctp.h profiles/audio/avctp.c \
+ profiles/audio/avrcp.h profiles/audio/avrcp.c \
+ profiles/audio/device.h profiles/audio/device.c \
+ profiles/audio/source.h profiles/audio/source.c \
+ profiles/audio/sink.h profiles/audio/sink.c \
+ profiles/audio/a2dp.h profiles/audio/a2dp.c \
+ profiles/audio/avdtp.h profiles/audio/avdtp.c \
+ profiles/audio/media.h profiles/audio/media.c \
+ profiles/audio/transport.h profiles/audio/transport.c \
+ profiles/audio/player.h profiles/audio/player.c \
+ profiles/audio/telephony.h profiles/audio/a2dp-codecs.h
+builtin_nodist += profiles/audio/telephony.c
+
+noinst_LIBRARIES += profiles/audio/libtelephony.a
+
+profiles_audio_libtelephony_a_SOURCES = profiles/audio/telephony.h
+ profiles/audio/telephony-dummy.c \
+ profiles/audio/telephony-maemo5.c \
+ profiles/audio/telephony-ofono.c \
+ profiles/audio/telephony-maemo6.c
endif
if SAPPLUGIN
@@ -360,7 +362,7 @@ EXTRA_DIST += doc/manager-api.txt \
AM_CFLAGS += @DBUS_CFLAGS@ @GLIB_CFLAGS@
AM_CPPFLAGS = -I$(builddir)/lib -I$(builddir)/src -I$(srcdir)/src \
- -I$(srcdir)/audio -I$(srcdir)/gdbus \
+ -I$(srcdir)/profiles -I$(srcdir)/gdbus \
-I$(srcdir)/attrib -I$(srcdir)/btio \
-I$(srcdir)/tools -I$(builddir)/tools \
-I$(srcdir)/monitor
@@ -401,7 +403,7 @@ MAINTAINERCLEANFILES = Makefile.in \
src/builtin.h: src/genbuiltin $(builtin_sources)
$(AM_V_GEN)$(srcdir)/src/genbuiltin $(builtin_modules) > $@
-audio/telephony.c: audio/@TELEPHONY_DRIVER@
+profiles/audio/telephony.c: profiles/audio/@TELEPHONY_DRIVER@
$(AM_V_GEN)$(LN_S) $(abs_top_builddir)/$< $@
profiles/sap/sap.c: profiles/sap/@SAP_DRIVER@
diff --git a/audio/a2dp-codecs.h b/profiles/audio/a2dp-codecs.h
similarity index 100%
rename from audio/a2dp-codecs.h
rename to profiles/audio/a2dp-codecs.h
diff --git a/audio/a2dp.c b/profiles/audio/a2dp.c
similarity index 100%
rename from audio/a2dp.c
rename to profiles/audio/a2dp.c
diff --git a/audio/a2dp.h b/profiles/audio/a2dp.h
similarity index 100%
rename from audio/a2dp.h
rename to profiles/audio/a2dp.h
diff --git a/audio/audio.conf b/profiles/audio/audio.conf
similarity index 100%
rename from audio/audio.conf
rename to profiles/audio/audio.conf
diff --git a/audio/avctp.c b/profiles/audio/avctp.c
similarity index 100%
rename from audio/avctp.c
rename to profiles/audio/avctp.c
diff --git a/audio/avctp.h b/profiles/audio/avctp.h
similarity index 100%
rename from audio/avctp.h
rename to profiles/audio/avctp.h
diff --git a/audio/avdtp.c b/profiles/audio/avdtp.c
similarity index 100%
rename from audio/avdtp.c
rename to profiles/audio/avdtp.c
diff --git a/audio/avdtp.h b/profiles/audio/avdtp.h
similarity index 100%
rename from audio/avdtp.h
rename to profiles/audio/avdtp.h
diff --git a/audio/avrcp.c b/profiles/audio/avrcp.c
similarity index 100%
rename from audio/avrcp.c
rename to profiles/audio/avrcp.c
diff --git a/audio/avrcp.h b/profiles/audio/avrcp.h
similarity index 100%
rename from audio/avrcp.h
rename to profiles/audio/avrcp.h
diff --git a/audio/control.c b/profiles/audio/control.c
similarity index 100%
rename from audio/control.c
rename to profiles/audio/control.c
diff --git a/audio/control.h b/profiles/audio/control.h
similarity index 100%
rename from audio/control.h
rename to profiles/audio/control.h
diff --git a/audio/device.c b/profiles/audio/device.c
similarity index 100%
rename from audio/device.c
rename to profiles/audio/device.c
diff --git a/audio/device.h b/profiles/audio/device.h
similarity index 100%
rename from audio/device.h
rename to profiles/audio/device.h
diff --git a/audio/gateway.c b/profiles/audio/gateway.c
similarity index 100%
rename from audio/gateway.c
rename to profiles/audio/gateway.c
diff --git a/audio/gateway.h b/profiles/audio/gateway.h
similarity index 100%
rename from audio/gateway.h
rename to profiles/audio/gateway.h
diff --git a/audio/headset.c b/profiles/audio/headset.c
similarity index 100%
rename from audio/headset.c
rename to profiles/audio/headset.c
diff --git a/audio/headset.h b/profiles/audio/headset.h
similarity index 100%
rename from audio/headset.h
rename to profiles/audio/headset.h
diff --git a/audio/main.c b/profiles/audio/main.c
similarity index 100%
rename from audio/main.c
rename to profiles/audio/main.c
diff --git a/audio/manager.c b/profiles/audio/manager.c
similarity index 100%
rename from audio/manager.c
rename to profiles/audio/manager.c
diff --git a/audio/manager.h b/profiles/audio/manager.h
similarity index 100%
rename from audio/manager.h
rename to profiles/audio/manager.h
diff --git a/audio/media.c b/profiles/audio/media.c
similarity index 100%
rename from audio/media.c
rename to profiles/audio/media.c
diff --git a/audio/media.h b/profiles/audio/media.h
similarity index 100%
rename from audio/media.h
rename to profiles/audio/media.h
diff --git a/audio/player.c b/profiles/audio/player.c
similarity index 100%
rename from audio/player.c
rename to profiles/audio/player.c
diff --git a/audio/player.h b/profiles/audio/player.h
similarity index 100%
rename from audio/player.h
rename to profiles/audio/player.h
diff --git a/audio/rtp.h b/profiles/audio/rtp.h
similarity index 100%
rename from audio/rtp.h
rename to profiles/audio/rtp.h
diff --git a/audio/sink.c b/profiles/audio/sink.c
similarity index 100%
rename from audio/sink.c
rename to profiles/audio/sink.c
diff --git a/audio/sink.h b/profiles/audio/sink.h
similarity index 100%
rename from audio/sink.h
rename to profiles/audio/sink.h
diff --git a/audio/source.c b/profiles/audio/source.c
similarity index 100%
rename from audio/source.c
rename to profiles/audio/source.c
diff --git a/audio/source.h b/profiles/audio/source.h
similarity index 100%
rename from audio/source.h
rename to profiles/audio/source.h
diff --git a/audio/telephony-dummy.c b/profiles/audio/telephony-dummy.c
similarity index 100%
rename from audio/telephony-dummy.c
rename to profiles/audio/telephony-dummy.c
diff --git a/audio/telephony-maemo5.c b/profiles/audio/telephony-maemo5.c
similarity index 100%
rename from audio/telephony-maemo5.c
rename to profiles/audio/telephony-maemo5.c
diff --git a/audio/telephony-maemo6.c b/profiles/audio/telephony-maemo6.c
similarity index 100%
rename from audio/telephony-maemo6.c
rename to profiles/audio/telephony-maemo6.c
diff --git a/audio/telephony-ofono.c b/profiles/audio/telephony-ofono.c
similarity index 100%
rename from audio/telephony-ofono.c
rename to profiles/audio/telephony-ofono.c
diff --git a/audio/telephony.h b/profiles/audio/telephony.h
similarity index 100%
rename from audio/telephony.h
rename to profiles/audio/telephony.h
diff --git a/audio/transport.c b/profiles/audio/transport.c
similarity index 100%
rename from audio/transport.c
rename to profiles/audio/transport.c
diff --git a/audio/transport.h b/profiles/audio/transport.h
similarity index 100%
rename from audio/transport.h
rename to profiles/audio/transport.h
diff --git a/tools/avinfo.c b/tools/avinfo.c
index f036cf8..b01068d 100644
--- a/tools/avinfo.c
+++ b/tools/avinfo.c
@@ -39,7 +39,7 @@
#include <sys/ioctl.h>
#include <sys/socket.h>
-#include <a2dp-codecs.h>
+#include <audio/a2dp-codecs.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
--
1.7.11.7
^ permalink raw reply related
* Re: Moving bluetooth plugin to gstreamer
From: Tim-Philipp Müller @ 2012-11-08 15:32 UTC (permalink / raw)
To: Luiz Augusto von Dentz
Cc: Discussion of the development of and with GStreamer,
linux-bluetooth, Thiago Sousa Santos
In-Reply-To: <CABBYNZ+vGYoj+0VpAb_9HAbCSRZ+F_-5zbd+WODG4_Qrz_vcaw@mail.gmail.com>
On Thu, 2012-11-08 at 17:20 +0200, Luiz Augusto von Dentz wrote:
Hi Luiz,
> Im about to send a patch to remove this from BlueZ, I hope somebody
> from gstreamer community can step up and take the task to move this to
> gstreamer tree, if nobody does I will eventually do it but this might
> take some time for me since Im quite busy with upcoming BlueZ 5.0
> (which is also the reason why we are cleaning up the tree).
This is the plan for the current GStreamer dev cycle (1.1.x) [0], so
should happen really soon now. (I'll do it if no one else is faster.)
Cheers
-Tim
[0] http://gstreamer.freedesktop.org/wiki/ReleasePlanning/RoadMap
^ permalink raw reply
* Feedback on potential fix for issue while advertising Feature List
From: Bart Westgeest @ 2012-11-08 15:34 UTC (permalink / raw)
To: linux-bluetooth
Hi folks,
I've tracked down the root cause of an issue, and am looking for
input/feedback on what the acceptable/preferred fix is.
The code of interest is in sdp_set_supp_feat. The bug is exposed by
registering a feature list (SDP_ATTR_SUPPORTED_FEATURES_LIST) of a
length greater than 256. The attribute sequence type in one of the
resulting attribute sequences is hard-coded to be SDP_SEQ8. When the
list grows beyond 256 bytes, the size descriptor type is not corrected
to SDP_SEQ16.
Henceforth, the indicated size of this attribute sequence in an SDP
response PDU is whatever the lower byte of the feature list size is.
However, the complete list data is written in the SDP response, hence
forming a corrupted PDU.
This bug can easily be reproduced by registering a number of Health
Applications (including a description string) such that the size of the
advertised feature list attribute is greater than 256 bytes.
Subsequently querying for this SDP record with sdptool, will result in
indicated errors about unknown data due to parsing errors.
The quick and dirty fix is to change the return statement in
sdp_seq_alloc (lib/sdp.c:563) from:
return sdp_data_alloc(SDP_SEQ8, seq);
to
return sdp_data_alloc(SDP_SEQ16, seq);
However, it really looks like the data type should be determined
dynamically, or perhaps (a more involved fix,) instead of using nested
data sequences for the outer data type, perhaps it should be changed to
a list i.e. to use sdp_list_t instead sdp_data_t for the feature list.
In addition, this problem (hard coded sequence length for a variable
length list) seems be repeated at various places throughout the code, so
this problem does not appear to be isolated to sdp_set_supp_feat/HDP.
For example sdp_set_lang_attr, sdp_set_uuidseq_attr, and
sdp_set_profile_descs all appear to form corrupted PDU if their
specified list grows beyond 256.
I appreciate any input from anybody more familiar with the SDP code on
what the accepted/preferred approach is to get this issue fixed.
Thanks,
Bart
^ permalink raw reply
* Re: [PATCH BlueZ 1/2] audio: Fix headset NULL pointer dereference during AT+BLDN response
From: Syam Sidhardhan @ 2012-11-09 3:32 UTC (permalink / raw)
To: Syam Sidhardhan; +Cc: linux-bluetooth
In-Reply-To: <1351000626-22632-1-git-send-email-s.syam@samsung.com>
Hi,
On Tue, Oct 23, 2012 at 7:27 PM, Syam Sidhardhan <s.syam@samsung.com> wrote:
> While waiting for the AT+BLDN asynchronous response, if RFCOMM got
> disconnected, then respose will cause NULL pointer dereference.
>
> During headset disconnection, the headset state changes from
> HEADSET_STATE_CONNECTED to HEADSET_STATE_DISCONNECTED along with
> freeing the dev->headset. During the response, in telephony_generic_rsp
> its dereferencing.
>
> Log:
> bluetoothd[5573]: audio/headset.c:handle_event() Received AT+BLDN
> bluetoothd[5573]: audio/telephony.c:telephony_last_dialed_number_req()
> telephony-tizen: last dialed number request
> bluetoothd[5573]: audio/telephony.c:dbus_method_call_send() +
> bluetoothd[5573]: audio/telephony.c:dbus_method_call_send() -
> bluetoothd[5573]: Endpoint replied with an error: org.freedesktop.DBus\
> .Error.NoReply
> bluetoothd[5573]: audio/telephony.c:telephony_device_disconnected()
> telephony-tizen: device 0x40439b60 disconnected
> bluetoothd[5573]: audio/headset.c:headset_set_state() State changed
> /org/bluez/5573/hci0/dev_BC_47_60_F5_88_89:
> HEADSET_STATE_CONNECTED -> HEADSET_STATE_DISCONNECTED
> bluetoothd[5573]: audio/media.c:headset_state_changed()
> bluetoothd[5573]: audio/media.c:headset_state_changed() Clear endpoint
> 0x40430620
> bluetoothd[5573]: audio/telephony.c:telephony_dial_number_reply()
> redial_reply
> bluetoothd[5573]: audio/telephony.c:telephony_dial_number_reply()
> dial_reply reply: No Call log
> ---
> audio/headset.c | 3 +++
> 1 files changed, 3 insertions(+), 0 deletions(-)
>
> diff --git a/audio/headset.c b/audio/headset.c
> index bd83a65..30d24cf 100644
> --- a/audio/headset.c
> +++ b/audio/headset.c
> @@ -689,6 +689,9 @@ static int telephony_generic_rsp(struct audio_device *device, cme_error_t err)
> struct headset *hs = device->headset;
> struct headset_slc *slc = hs->slc;
>
> + if (!slc)
> + return -EIO;
> +
> if ((err != CME_ERROR_NONE) && slc->cme_enabled)
> return headset_send(hs, "\r\n+CME ERROR: %d\r\n", err);
>
ping.
Thanks,
Syam
^ permalink raw reply
* Re: BLE issue - Reusing Existing LE physical link
From: Vinicius Costa Gomes @ 2012-11-09 8:11 UTC (permalink / raw)
To: Ajay; +Cc: linux-bluetooth
In-Reply-To: <509A8FD4.1080800@globaledgesoft.com>
Hi,
On 22:14 Wed 07 Nov, Ajay wrote:
> Hi ,
> I came across an issue as part of my "BLE test tool project" .
> After the first successful connection of BLE l2cap connection
> (client server) , we just retains the physical link without calling
> le_connection cancel() (logical link is closed) (patch has been
> added). But second time i wanted to use the existing connection ,
> without calling hci_le_connect() . but here l2cap connect fails . I
> noticed in normal acl link , the same scenario is working on
> existing link. so can we do the same working on BLE link .
> (ubuntu 11.10 and kernel 3.2.5)
Could you please test with a recent kernel, 3.6.x preferably. LE support has
improved a lot in recent kernels.
> --
> Thanks & regards
>
> AJAY KV
> GlobalEdge software Ltd
> 8892753703
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Cheers,
--
Vinicius
^ permalink raw reply
* [PATCH BlueZ 1/2] build: Require D-Bus 1.5 or later
From: Syam Sidhardhan @ 2012-11-09 8:31 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Syam Sidhardhan
The gdbus require D-Bus 1.5 version.
Log:
CC gdbus/object.o
gdbus/object.c: In function ‘properties_set’:
gdbus/object.c:876:7: error: ‘DBUS_ERROR_UNKNOWN_PROPERTY’ undeclared
(first use in this function)
gdbus/object.c:876:7: note: each undeclared identifier is reported
only once for each function it appears in
gdbus/object.c:881:6: error: ‘DBUS_ERROR_PROPERTY_READ_ONLY’
undeclared (first use in this function)
make[1]: *** [gdbus/object.o] Error 1
make: *** [all] Error 2
---
acinclude.m4 | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/acinclude.m4 b/acinclude.m4
index ddc8183..1ae402c 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -92,8 +92,8 @@ AC_DEFUN([AC_INIT_BLUEZ], [
])
AC_DEFUN([AC_PATH_DBUS], [
- PKG_CHECK_MODULES(DBUS, dbus-1 >= 1.4, dummy=yes,
- AC_MSG_ERROR(D-Bus >= 1.4 is required))
+ PKG_CHECK_MODULES(DBUS, dbus-1 >= 1.5, dummy=yes,
+ AC_MSG_ERROR(D-Bus >= 1.5 is required))
AC_SUBST(DBUS_CFLAGS)
AC_SUBST(DBUS_LIBS)
])
--
1.7.4.1
^ permalink raw reply related
* [PATCH BlueZ 2/2] l2test: Add support to test auto select PSM
From: Syam Sidhardhan @ 2012-11-09 8:31 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Syam Sidhardhan
In-Reply-To: <1352449889-5149-1-git-send-email-s.syam@samsung.com>
This patch enable us to test the auto select PSM by passing
PSM value as 0.
Ex: l2test -d -P 0
l2test[2585]: Waiting for connection on psm 4099 ...
---
test/l2test.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/test/l2test.c b/test/l2test.c
index 7645681..72ad4ba 100644
--- a/test/l2test.c
+++ b/test/l2test.c
@@ -87,7 +87,7 @@ static long buffer_size = 2048;
/* Default addr and psm and cid */
static bdaddr_t bdaddr;
-static unsigned short psm = 0x1011;
+static unsigned short psm = 0;
static unsigned short cid = 0;
/* Default number of frames to send (-1 = infinite) */
@@ -375,8 +375,6 @@ static int do_connect(char *svr)
addr.l2_cid = htobs(cid);
else if (psm)
addr.l2_psm = htobs(psm);
- else
- goto error;
if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0 ) {
syslog(LOG_ERR, "Can't connect: %s (%d)",
--
1.7.4.1
^ permalink raw reply related
* [PATCH 00/15] thermometer plugin updates
From: Andrzej Kaczmarek @ 2012-11-09 8:55 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
Hi,
Here are few patches to update thermometer plugin with features already
implemented in other plugins:
- store attributes handles directly in thermometer structure instead of
nested lists of structures which we need to traverse later (and we
only need 3 handles stored to support all use cases)
- register attio handlers for specific handles instead of one ind and
notif handler globally
- change properties handling to DBus.Properties
- and some minor fixes
This is tested with PTS 4.5.3. There's only problem with patch #9 which
"breaks" testcase TP/THF/CO/BV-09-I - this is because PTS sends invalid
properties for Measurement Interval characteristic (it does not have
indicate property so we do not register ind handler for it). I already
filled issue on PTS.
Comments are welcome.
Andrzej Kaczmarek (15):
thermometer: Store Temperature Measurement CCC handle in struct
thermometer: Store Intermediate Temperature CCC handle in struct
thermometer: Store Measurement Interval value handle in struct
thermometer: Use dedicated handler for Intermediate Temperature
thermometer: Use dedicated handler for Temperature Measurement
thermometer: Use dedicated handler for Measurement Interval
thermometer: Remove descriptor structure
thermometer: Remove storage of all discovered characteristics
thermometer: Discover Measurement Interval descriptors only if needed
thermometer: Always write CCC value when connecting
thermometer: Make temp_type array static
thermometer: Add DBus.Properties support
thermometer: Remove legacy properties code
doc: Update thermometer API document
test: Update test-thermometer for DBus.Properties
doc/thermometer-api.txt | 18 -
profiles/thermometer/thermometer.c | 1008 +++++++++++++++++-------------------
test/test-thermometer | 13 +-
3 files changed, 478 insertions(+), 561 deletions(-)
--
1.8.0
^ permalink raw reply
* [PATCH 01/15] thermometer: Store Temperature Measurement CCC handle in struct
From: Andrzej Kaczmarek @ 2012-11-09 8:55 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1352451357-22097-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch adds Temperature Measurement CCC handle value directly into
thermometer struct. This way there's no need to traverse nested lists
looking for value.
---
profiles/thermometer/thermometer.c | 29 ++++++++++++++++++++++++++---
1 file changed, 26 insertions(+), 3 deletions(-)
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index 4d1df1d..3ea6e96 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -80,6 +80,8 @@ struct thermometer {
uint16_t min;
gboolean has_type;
gboolean has_interval;
+
+ uint16_t measurement_ccc_handle;
};
struct characteristic {
@@ -403,6 +405,8 @@ static void process_thermometer_desc(struct descriptor *desc)
if (g_strcmp0(ch->attr.uuid,
TEMPERATURE_MEASUREMENT_UUID) == 0) {
+ desc->ch->t->measurement_ccc_handle = desc->handle;
+
if (g_slist_length(ch->t->tadapter->fwatchers) == 0)
return;
@@ -759,9 +763,18 @@ static void write_ccc(struct thermometer *t, const char *uuid, uint16_t value)
static void enable_final_measurement(gpointer data, gpointer user_data)
{
struct thermometer *t = data;
+ uint16_t handle = t->measurement_ccc_handle;
+ uint8_t value[2];
+ char *msg;
+
+ if (t->attrib == NULL || !handle)
+ return;
+
+ att_put_u16(GATT_CLIENT_CHARAC_CFG_IND_BIT, value);
+ msg = g_strdup("Enable Temperature Measurement indications");
- write_ccc(t, TEMPERATURE_MEASUREMENT_UUID,
- GATT_CLIENT_CHARAC_CFG_IND_BIT);
+ gatt_write_char(t->attrib, handle, value, sizeof(value),
+ write_ccc_cb, msg);
}
static void enable_intermediate_measurement(gpointer data, gpointer user_data)
@@ -775,8 +788,18 @@ static void enable_intermediate_measurement(gpointer data, gpointer user_data)
static void disable_final_measurement(gpointer data, gpointer user_data)
{
struct thermometer *t = data;
+ uint16_t handle = t->measurement_ccc_handle;
+ uint8_t value[2];
+ char *msg;
+
+ if (t->attrib == NULL || !handle)
+ return;
+
+ att_put_u16(0x0000, value);
+ msg = g_strdup("Disable Temperature Measurement indications");
- write_ccc(t, TEMPERATURE_MEASUREMENT_UUID, 0x0000);
+ gatt_write_char(t->attrib, handle, value, sizeof(value),
+ write_ccc_cb, msg);
}
static void disable_intermediate_measurement(gpointer data, gpointer user_data)
--
1.8.0
^ permalink raw reply related
* [PATCH 02/15] thermometer: Store Intermediate Temperature CCC handle in struct
From: Andrzej Kaczmarek @ 2012-11-09 8:55 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1352451357-22097-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch adds Intermediate Measurement CCC handle value directly into
thermometer struct. This way there's no need to traverse nested lists
looking for value.
write_ccc() function and related helpers are now unused so can be
removed.
---
profiles/thermometer/thermometer.c | 80 ++++++++++++--------------------------
1 file changed, 25 insertions(+), 55 deletions(-)
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index 3ea6e96..d836462 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -82,6 +82,7 @@ struct thermometer {
gboolean has_interval;
uint16_t measurement_ccc_handle;
+ uint16_t intermediate_ccc_handle;
};
struct characteristic {
@@ -255,14 +256,6 @@ static gint cmp_char_val_handle(gconstpointer a, gconstpointer b)
return ch->attr.value_handle - *handle;
}
-static gint cmp_descriptor(gconstpointer a, gconstpointer b)
-{
- const struct descriptor *desc = a;
- const bt_uuid_t *uuid = b;
-
- return bt_uuid_cmp(&desc->uuid, uuid);
-}
-
static struct thermometer_adapter *
find_thermometer_adapter(struct btd_adapter *adapter)
{
@@ -286,18 +279,6 @@ static struct characteristic *get_characteristic(struct thermometer *t,
return l->data;
}
-static struct descriptor *get_descriptor(struct characteristic *ch,
- const bt_uuid_t *uuid)
-{
- GSList *l;
-
- l = g_slist_find_custom(ch->desc, uuid, cmp_descriptor);
- if (l == NULL)
- return NULL;
-
- return l->data;
-}
-
static void change_property(struct thermometer *t, const char *name,
gpointer value) {
if (g_strcmp0(name, "Intermediate") == 0) {
@@ -415,6 +396,8 @@ static void process_thermometer_desc(struct descriptor *desc)
"indication");
} else if (g_strcmp0(ch->attr.uuid,
INTERMEDIATE_TEMPERATURE_UUID) == 0) {
+ desc->ch->t->intermediate_ccc_handle = desc->handle;
+
if (g_slist_length(ch->t->tadapter->iwatchers) == 0)
return;
@@ -728,38 +711,6 @@ static DBusMessage *set_property(DBusConnection *conn, DBusMessage *msg,
return write_attr_interval(t, msg, value);
}
-static void write_ccc(struct thermometer *t, const char *uuid, uint16_t value)
-{
- 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, uuid);
- if (ch == NULL) {
- 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("CCC descriptor for %s not found", uuid);
- return;
- }
-
- 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_final_measurement(gpointer data, gpointer user_data)
{
struct thermometer *t = data;
@@ -780,9 +731,18 @@ static void enable_final_measurement(gpointer data, gpointer user_data)
static void enable_intermediate_measurement(gpointer data, gpointer user_data)
{
struct thermometer *t = data;
+ uint16_t handle = t->intermediate_ccc_handle;
+ uint8_t value[2];
+ char *msg;
+
+ if (t->attrib == NULL || !handle)
+ return;
+
+ att_put_u16(GATT_CLIENT_CHARAC_CFG_NOTIF_BIT, value);
+ msg = g_strdup("Enable Intermediate Temperature notifications");
- write_ccc(t, INTERMEDIATE_TEMPERATURE_UUID,
- GATT_CLIENT_CHARAC_CFG_NOTIF_BIT);
+ gatt_write_char(t->attrib, handle, value, sizeof(value),
+ write_ccc_cb, msg);
}
static void disable_final_measurement(gpointer data, gpointer user_data)
@@ -805,8 +765,18 @@ static void disable_final_measurement(gpointer data, gpointer user_data)
static void disable_intermediate_measurement(gpointer data, gpointer user_data)
{
struct thermometer *t = data;
+ uint16_t handle = t->intermediate_ccc_handle;
+ uint8_t value[2];
+ char *msg;
- write_ccc(t, INTERMEDIATE_TEMPERATURE_UUID, 0x0000);
+ if (t->attrib == NULL || !handle)
+ return;
+
+ att_put_u16(0x0000, value);
+ msg = g_strdup("Disable Intermediate Temperature notifications");
+
+ gatt_write_char(t->attrib, handle, value, sizeof(value),
+ write_ccc_cb, msg);
}
static void remove_int_watcher(struct thermometer_adapter *tadapter,
--
1.8.0
^ permalink raw reply related
* [PATCH 03/15] thermometer: Store Measurement Interval value handle in struct
From: Andrzej Kaczmarek @ 2012-11-09 8:55 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1352451357-22097-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch adds Measurement Interval value handle directly into
thermometer struct. This way there's no need to traverse list
looking for value.
get_characteristic() function and related helpers are now unused
so can be removed.
---
profiles/thermometer/thermometer.c | 29 +++++------------------------
1 file changed, 5 insertions(+), 24 deletions(-)
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index d836462..d65fc0d 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -83,6 +83,7 @@ struct thermometer {
uint16_t measurement_ccc_handle;
uint16_t intermediate_ccc_handle;
+ uint16_t interval_val_handle;
};
struct characteristic {
@@ -240,14 +241,6 @@ static gint cmp_watcher(gconstpointer a, gconstpointer b)
return g_strcmp0(watcher->path, match->path);
}
-static gint cmp_char_uuid(gconstpointer a, gconstpointer b)
-{
- const struct characteristic *ch = a;
- const char *uuid = b;
-
- return g_strcmp0(ch->attr.uuid, uuid);
-}
-
static gint cmp_char_val_handle(gconstpointer a, gconstpointer b)
{
const struct characteristic *ch = a;
@@ -267,18 +260,6 @@ find_thermometer_adapter(struct btd_adapter *adapter)
return l->data;
}
-static struct characteristic *get_characteristic(struct thermometer *t,
- const char *uuid)
-{
- GSList *l;
-
- l = g_slist_find_custom(t->chars, uuid, cmp_char_uuid);
- if (l == NULL)
- return NULL;
-
- return l->data;
-}
-
static void change_property(struct thermometer *t, const char *name,
gpointer value) {
if (g_strcmp0(name, "Intermediate") == 0) {
@@ -541,6 +522,8 @@ static void process_thermometer_char(struct characteristic *ch)
gatt_read_char(ch->t->attrib, ch->attr.value_handle,
read_temp_type_cb, ch);
} else if (g_strcmp0(ch->attr.uuid, MEASUREMENT_INTERVAL_UUID) == 0) {
+ ch->t->interval_val_handle = ch->attr.value_handle;
+
gatt_read_char(ch->t->attrib, ch->attr.value_handle,
read_interval_cb, ch);
}
@@ -651,14 +634,12 @@ static DBusMessage *write_attr_interval(struct thermometer *t, DBusMessage *msg,
uint16_t value)
{
struct tmp_interval_data *data;
- struct characteristic *ch;
uint8_t atval[2];
if (t->attrib == NULL)
return btd_error_not_connected(msg);
- ch = get_characteristic(t, MEASUREMENT_INTERVAL_UUID);
- if (ch == NULL)
+ if (t->interval_val_handle == 0)
return btd_error_not_available(msg);
if (value < t->min || value > t->max)
@@ -669,7 +650,7 @@ static DBusMessage *write_attr_interval(struct thermometer *t, DBusMessage *msg,
data = g_new0(struct tmp_interval_data, 1);
data->thermometer = t;
data->interval = value;
- gatt_write_char(t->attrib, ch->attr.value_handle, atval, 2,
+ gatt_write_char(t->attrib, t->interval_val_handle, atval, 2,
write_interval_cb, data);
return dbus_message_new_method_return(msg);
--
1.8.0
^ permalink raw reply related
* [PATCH 04/15] thermometer: Use dedicated handler for Intermediate Temperature
From: Andrzej Kaczmarek @ 2012-11-09 8:55 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1352451357-22097-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch replaces global notifications handler with one registered only
for Intermediate Temperature value notifications.
---
profiles/thermometer/thermometer.c | 345 ++++++++++++++++++-------------------
1 file changed, 168 insertions(+), 177 deletions(-)
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index d65fc0d..5ed0553 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -71,7 +71,8 @@ struct thermometer {
struct att_range *svc_range; /* Thermometer range */
guint attioid; /* Att watcher id */
guint attindid; /* Att incications id */
- guint attnotid; /* Att notif id */
+ /* attio id for Intermediate Temperature value notifications */
+ guint attio_intermediate_id;
GSList *chars; /* Characteristics */
gboolean intermediate;
uint8_t type;
@@ -179,8 +180,7 @@ static void destroy_thermometer(gpointer user_data)
if (t->attindid > 0)
g_attrib_unregister(t->attrib, t->attindid);
- if (t->attnotid > 0)
- g_attrib_unregister(t->attrib, t->attnotid);
+ g_attrib_unregister(t->attrib, t->attio_intermediate_id);
if (t->attrib != NULL)
g_attrib_unref(t->attrib);
@@ -304,6 +304,162 @@ static void change_property(struct thermometer *t, const char *name,
}
}
+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;
+
+ msg = dbus_message_new_method_call(w->srv, w->path,
+ THERMOMETER_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, "Exponent", DBUS_TYPE_INT16, &m->exp);
+ dict_append_entry(&dict, "Mantissa", DBUS_TYPE_INT32, &m->mant);
+ dict_append_entry(&dict, "Unit", DBUS_TYPE_STRING, &m->unit);
+
+ if (m->suptime)
+ dict_append_entry(&dict, "Time", DBUS_TYPE_UINT64, &m->time);
+
+ dict_append_entry(&dict, "Type", DBUS_TYPE_STRING, &m->type);
+ dict_append_entry(&dict, "Measurement", DBUS_TYPE_STRING, &m->value);
+
+ 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 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
+ wlist = t->tadapter->fwatchers;
+
+ g_slist_foreach(wlist, update_watcher, m);
+}
+
+static void proc_measurement(struct thermometer *t, const uint8_t *pdu,
+ uint16_t len, gboolean final)
+{
+ struct measurement m;
+ const char *type = NULL;
+ uint8_t flags;
+ uint32_t raw;
+
+ /* skip opcode and handle */
+ pdu += 3;
+ len -= 3;
+
+ if (len < 1) {
+ DBG("Mandatory flags are not provided");
+ return;
+ }
+
+ memset(&m, 0, sizeof(m));
+
+ flags = *pdu;
+
+ if (flags & TEMP_UNITS)
+ m.unit = "fahrenheit";
+ else
+ m.unit = "celsius";
+
+ pdu++;
+ len--;
+
+ if (len < 4) {
+ DBG("Mandatory temperature measurement value is not provided");
+ return;
+ }
+
+ raw = att_get_u32(pdu);
+ m.mant = raw & 0x00FFFFFF;
+ m.exp = ((int32_t) raw) >> 24;
+
+ if (m.mant & 0x00800000) {
+ /* convert to C2 negative value */
+ m.mant = m.mant - FLOAT_MAX_MANTISSA;
+ }
+
+ pdu += 4;
+ len -= 4;
+
+ if (flags & TEMP_TIME_STAMP) {
+ struct tm ts;
+ time_t time;
+
+ if (len < 7) {
+ DBG("Time stamp is not provided");
+ return;
+ }
+
+ ts.tm_year = att_get_u16(pdu) - 1900;
+ ts.tm_mon = *(pdu + 2) - 1;
+ ts.tm_mday = *(pdu + 3);
+ ts.tm_hour = *(pdu + 4);
+ ts.tm_min = *(pdu + 5);
+ ts.tm_sec = *(pdu + 6);
+ ts.tm_isdst = -1;
+
+ time = mktime(&ts);
+ m.time = (uint64_t) time;
+ m.suptime = TRUE;
+
+ pdu += 7;
+ len -= 7;
+ }
+
+ if (flags & TEMP_TYPE) {
+ if (len < 1) {
+ DBG("Temperature type is not provided");
+ return;
+ }
+
+ type = temptype2str(*pdu);
+ } else if (t->has_type) {
+ type = temptype2str(t->type);
+ }
+
+ m.type = g_strdup(type);
+ m.value = final ? "final" : "intermediate";
+
+ recv_measurement(t, &m);
+ g_free(m.type);
+}
+
+static void intermediate_notify_handler(const uint8_t *pdu, uint16_t len,
+ gpointer user_data)
+{
+ struct thermometer *t = user_data;
+
+ if (len < 3) {
+ DBG("Bad pdu received");
+ return;
+ }
+
+ proc_measurement(t, pdu, len, FALSE);
+}
+
static void valid_range_desc_cb(guint8 status, const guint8 *pdu, guint16 len,
gpointer user_data)
{
@@ -514,10 +670,15 @@ static void read_interval_cb(guint8 status, const guint8 *pdu, guint16 len,
static void process_thermometer_char(struct characteristic *ch)
{
+ struct thermometer *t = ch->t;
+
if (g_strcmp0(ch->attr.uuid, INTERMEDIATE_TEMPERATURE_UUID) == 0) {
gboolean intermediate = TRUE;
change_property(ch->t, "Intermediate", &intermediate);
- return;
+
+ t->attio_intermediate_id = g_attrib_register(t->attrib,
+ ATT_OP_HANDLE_NOTIFY, ch->attr.value_handle,
+ intermediate_notify_handler, t, NULL);
} else if (g_strcmp0(ch->attr.uuid, TEMPERATURE_TYPE_UUID) == 0) {
gatt_read_char(ch->t->attrib, ch->attr.value_handle,
read_temp_type_cb, ch);
@@ -941,149 +1102,6 @@ static const GDBusSignalTable thermometer_signals[] = {
{ }
};
-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;
-
- msg = dbus_message_new_method_call(w->srv, w->path,
- THERMOMETER_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, "Exponent", DBUS_TYPE_INT16, &m->exp);
- dict_append_entry(&dict, "Mantissa", DBUS_TYPE_INT32, &m->mant);
- dict_append_entry(&dict, "Unit", DBUS_TYPE_STRING, &m->unit);
-
- if (m->suptime)
- dict_append_entry(&dict, "Time", DBUS_TYPE_UINT64, &m->time);
-
- dict_append_entry(&dict, "Type", DBUS_TYPE_STRING, &m->type);
- dict_append_entry(&dict, "Measurement", DBUS_TYPE_STRING, &m->value);
-
- 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 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
- wlist = t->tadapter->fwatchers;
-
- g_slist_foreach(wlist, update_watcher, m);
-}
-
-static void proc_measurement(struct thermometer *t, const uint8_t *pdu,
- uint16_t len, gboolean final)
-{
- struct measurement m;
- const char *type = NULL;
- uint8_t flags;
- uint32_t raw;
-
- /* skip opcode and handle */
- pdu += 3;
- len -= 3;
-
- if (len < 1) {
- DBG("Mandatory flags are not provided");
- return;
- }
-
- memset(&m, 0, sizeof(m));
-
- flags = *pdu;
-
- if (flags & TEMP_UNITS)
- m.unit = "fahrenheit";
- else
- m.unit = "celsius";
-
- pdu++;
- len--;
-
- if (len < 4) {
- DBG("Mandatory temperature measurement value is not provided");
- return;
- }
-
- raw = att_get_u32(pdu);
- m.mant = raw & 0x00FFFFFF;
- m.exp = ((int32_t) raw) >> 24;
-
- if (m.mant & 0x00800000) {
- /* convert to C2 negative value */
- m.mant = m.mant - FLOAT_MAX_MANTISSA;
- }
-
- pdu += 4;
- len -= 4;
-
- if (flags & TEMP_TIME_STAMP) {
- struct tm ts;
- time_t time;
-
- if (len < 7) {
- DBG("Time stamp is not provided");
- return;
- }
-
- ts.tm_year = att_get_u16(pdu) - 1900;
- ts.tm_mon = *(pdu + 2) - 1;
- ts.tm_mday = *(pdu + 3);
- ts.tm_hour = *(pdu + 4);
- ts.tm_min = *(pdu + 5);
- ts.tm_sec = *(pdu + 6);
- ts.tm_isdst = -1;
-
- time = mktime(&ts);
- m.time = (uint64_t) time;
- m.suptime = TRUE;
-
- pdu += 7;
- len -= 7;
- }
-
- if (flags & TEMP_TYPE) {
- if (len < 1) {
- DBG("Temperature type is not provided");
- return;
- }
-
- type = temptype2str(*pdu);
- } else if (t->has_type) {
- type = temptype2str(t->type);
- }
-
- m.type = g_strdup(type);
- m.value = final ? "final" : "intermediate";
-
- recv_measurement(t, &m);
- g_free(m.type);
-}
-
static void proc_measurement_interval(struct thermometer *t, const uint8_t *pdu,
uint16_t len)
{
@@ -1134,30 +1152,6 @@ static void ind_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
g_attrib_send(t->attrib, 0, opdu, olen, NULL, NULL, NULL);
}
-static void notif_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
-{
- struct thermometer *t = user_data;
- const struct characteristic *ch;
- uint16_t handle;
- GSList *l;
-
- if (len < 3) {
- DBG("Bad pdu received");
- return;
- }
-
- handle = att_get_u16(&pdu[1]);
- l = g_slist_find_custom(t->chars, &handle, cmp_char_val_handle);
- if (l == NULL) {
- DBG("Unexpected handle: 0x%04x", handle);
- return;
- }
-
- ch = l->data;
- if (g_strcmp0(ch->attr.uuid, INTERMEDIATE_TEMPERATURE_UUID) == 0)
- proc_measurement(t, pdu, len, FALSE);
-}
-
static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
{
struct thermometer *t = user_data;
@@ -1167,9 +1161,6 @@ static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
t->attindid = g_attrib_register(t->attrib, ATT_OP_HANDLE_IND,
GATTRIB_ALL_HANDLES,
ind_handler, t, NULL);
- t->attnotid = g_attrib_register(t->attrib, ATT_OP_HANDLE_NOTIFY,
- GATTRIB_ALL_HANDLES,
- notif_handler, t, NULL);
gatt_discover_char(t->attrib, t->svc_range->start, t->svc_range->end,
NULL, configure_thermometer_cb, t);
}
@@ -1185,9 +1176,9 @@ static void attio_disconnected_cb(gpointer user_data)
t->attindid = 0;
}
- if (t->attnotid > 0) {
- g_attrib_unregister(t->attrib, t->attnotid);
- t->attnotid = 0;
+ if (t->attio_intermediate_id > 0) {
+ g_attrib_unregister(t->attrib, t->attio_intermediate_id);
+ t->attio_intermediate_id = 0;
}
g_attrib_unref(t->attrib);
--
1.8.0
^ permalink raw reply related
* [PATCH 05/15] thermometer: Use dedicated handler for Temperature Measurement
From: Andrzej Kaczmarek @ 2012-11-09 8:55 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1352451357-22097-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch moves Temperature Measurement value indications handler into
separate callback registered for particular handle only.
---
profiles/thermometer/thermometer.c | 41 +++++++++++++++++++++++++++++++++++---
1 file changed, 38 insertions(+), 3 deletions(-)
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index 5ed0553..c5fdb94 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -71,6 +71,8 @@ struct thermometer {
struct att_range *svc_range; /* Thermometer range */
guint attioid; /* Att watcher id */
guint attindid; /* Att incications id */
+ /* attio id for Temperature Measurement value indications */
+ guint attio_measurement_id;
/* attio id for Intermediate Temperature value notifications */
guint attio_intermediate_id;
GSList *chars; /* Characteristics */
@@ -180,6 +182,7 @@ static void destroy_thermometer(gpointer user_data)
if (t->attindid > 0)
g_attrib_unregister(t->attrib, t->attindid);
+ g_attrib_unregister(t->attrib, t->attio_measurement_id);
g_attrib_unregister(t->attrib, t->attio_intermediate_id);
if (t->attrib != NULL)
@@ -447,6 +450,29 @@ static void proc_measurement(struct thermometer *t, const uint8_t *pdu,
g_free(m.type);
}
+
+static void measurement_ind_handler(const uint8_t *pdu, uint16_t len,
+ gpointer user_data)
+{
+ struct thermometer *t = user_data;
+ uint8_t *opdu;
+ uint16_t olen;
+ size_t plen;
+
+ if (len < 3) {
+ DBG("Bad pdu received");
+ return;
+ }
+
+ proc_measurement(t, pdu, len, TRUE);
+
+ opdu = g_attrib_get_buffer(t->attrib, &plen);
+ olen = enc_confirmation(opdu, plen);
+
+ if (olen > 0)
+ g_attrib_send(t->attrib, 0, opdu, olen, NULL, NULL, NULL);
+}
+
static void intermediate_notify_handler(const uint8_t *pdu, uint16_t len,
gpointer user_data)
{
@@ -679,6 +705,12 @@ static void process_thermometer_char(struct characteristic *ch)
t->attio_intermediate_id = g_attrib_register(t->attrib,
ATT_OP_HANDLE_NOTIFY, ch->attr.value_handle,
intermediate_notify_handler, t, NULL);
+ } else if (g_strcmp0(ch->attr.uuid,
+ TEMPERATURE_MEASUREMENT_UUID) == 0) {
+
+ t->attio_measurement_id = g_attrib_register(t->attrib,
+ ATT_OP_HANDLE_IND, ch->attr.value_handle,
+ measurement_ind_handler, t, NULL);
} else if (g_strcmp0(ch->attr.uuid, TEMPERATURE_TYPE_UUID) == 0) {
gatt_read_char(ch->t->attrib, ch->attr.value_handle,
read_temp_type_cb, ch);
@@ -1140,9 +1172,7 @@ static void ind_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
ch = l->data;
- if (g_strcmp0(ch->attr.uuid, TEMPERATURE_MEASUREMENT_UUID) == 0)
- proc_measurement(t, pdu, len, TRUE);
- else if (g_strcmp0(ch->attr.uuid, MEASUREMENT_INTERVAL_UUID) == 0)
+ if (g_strcmp0(ch->attr.uuid, MEASUREMENT_INTERVAL_UUID) == 0)
proc_measurement_interval(t, pdu, len);
opdu = g_attrib_get_buffer(t->attrib, &plen);
@@ -1176,6 +1206,11 @@ static void attio_disconnected_cb(gpointer user_data)
t->attindid = 0;
}
+ if (t->attio_measurement_id > 0) {
+ g_attrib_unregister(t->attrib, t->attio_measurement_id);
+ t->attio_measurement_id = 0;
+ }
+
if (t->attio_intermediate_id > 0) {
g_attrib_unregister(t->attrib, t->attio_intermediate_id);
t->attio_intermediate_id = 0;
--
1.8.0
^ permalink raw reply related
* [PATCH 06/15] thermometer: Use dedicated handler for Measurement Interval
From: Andrzej Kaczmarek @ 2012-11-09 8:55 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1352451357-22097-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch replaces global indications handler with one registered only
for Measurement Interval value indications.
---
profiles/thermometer/thermometer.c | 104 +++++++++++++------------------------
1 file changed, 36 insertions(+), 68 deletions(-)
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index c5fdb94..b01ac7a 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -70,11 +70,12 @@ struct thermometer {
GAttrib *attrib; /* GATT connection */
struct att_range *svc_range; /* Thermometer range */
guint attioid; /* Att watcher id */
- guint attindid; /* Att incications id */
/* attio id for Temperature Measurement value indications */
guint attio_measurement_id;
/* attio id for Intermediate Temperature value notifications */
guint attio_intermediate_id;
+ /* attio id for Measurement Interval value indications */
+ guint attio_interval_id;
GSList *chars; /* Characteristics */
gboolean intermediate;
uint8_t type;
@@ -179,11 +180,9 @@ static void destroy_thermometer(gpointer user_data)
if (t->attioid > 0)
btd_device_remove_attio_callback(t->dev, t->attioid);
- if (t->attindid > 0)
- g_attrib_unregister(t->attrib, t->attindid);
-
g_attrib_unregister(t->attrib, t->attio_measurement_id);
g_attrib_unregister(t->attrib, t->attio_intermediate_id);
+ g_attrib_unregister(t->attrib, t->attio_interval_id);
if (t->attrib != NULL)
g_attrib_unref(t->attrib);
@@ -244,14 +243,6 @@ static gint cmp_watcher(gconstpointer a, gconstpointer b)
return g_strcmp0(watcher->path, match->path);
}
-static gint cmp_char_val_handle(gconstpointer a, gconstpointer b)
-{
- const struct characteristic *ch = a;
- const uint16_t *handle = b;
-
- return ch->attr.value_handle - *handle;
-}
-
static struct thermometer_adapter *
find_thermometer_adapter(struct btd_adapter *adapter)
{
@@ -486,6 +477,30 @@ static void intermediate_notify_handler(const uint8_t *pdu, uint16_t len,
proc_measurement(t, pdu, len, FALSE);
}
+static void interval_ind_handler(const uint8_t *pdu, uint16_t len,
+ gpointer user_data)
+{
+ struct thermometer *t = user_data;
+ uint16_t interval;
+ uint8_t *opdu;
+ uint16_t olen;
+ size_t plen;
+
+ if (len < 5) {
+ DBG("Bad pdu received");
+ return;
+ }
+
+ interval = att_get_u16(pdu + 3);
+ change_property(t, "Interval", &interval);
+
+ opdu = g_attrib_get_buffer(t->attrib, &plen);
+ olen = enc_confirmation(opdu, plen);
+
+ if (olen > 0)
+ g_attrib_send(t->attrib, 0, opdu, olen, NULL, NULL, NULL);
+}
+
static void valid_range_desc_cb(guint8 status, const guint8 *pdu, guint16 len,
gpointer user_data)
{
@@ -719,6 +734,10 @@ static void process_thermometer_char(struct characteristic *ch)
gatt_read_char(ch->t->attrib, ch->attr.value_handle,
read_interval_cb, ch);
+
+ t->attio_interval_id = g_attrib_register(t->attrib,
+ ATT_OP_HANDLE_IND, ch->attr.value_handle,
+ interval_ind_handler, t, NULL);
}
}
@@ -1134,63 +1153,12 @@ static const GDBusSignalTable thermometer_signals[] = {
{ }
};
-static void proc_measurement_interval(struct thermometer *t, const uint8_t *pdu,
- uint16_t len)
-{
- uint16_t interval;
-
- if (len < 5) {
- DBG("Measurement interval value is not provided");
- return;
- }
-
- interval = att_get_u16(&pdu[3]);
-
- change_property(t, "Interval", &interval);
-}
-
-static void ind_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
-{
- struct thermometer *t = user_data;
- const struct characteristic *ch;
- uint8_t *opdu;
- uint16_t handle, olen;
- GSList *l;
- size_t plen;
-
- if (len < 3) {
- DBG("Bad pdu received");
- return;
- }
-
- handle = att_get_u16(&pdu[1]);
- l = g_slist_find_custom(t->chars, &handle, cmp_char_val_handle);
- if (l == NULL) {
- DBG("Unexpected handle: 0x%04x", handle);
- return;
- }
-
- ch = l->data;
-
- if (g_strcmp0(ch->attr.uuid, MEASUREMENT_INTERVAL_UUID) == 0)
- proc_measurement_interval(t, pdu, len);
-
- opdu = g_attrib_get_buffer(t->attrib, &plen);
- olen = enc_confirmation(opdu, plen);
-
- if (olen > 0)
- g_attrib_send(t->attrib, 0, opdu, olen, NULL, NULL, NULL);
-}
-
static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
{
struct thermometer *t = user_data;
t->attrib = g_attrib_ref(attrib);
- t->attindid = g_attrib_register(t->attrib, ATT_OP_HANDLE_IND,
- GATTRIB_ALL_HANDLES,
- ind_handler, t, NULL);
gatt_discover_char(t->attrib, t->svc_range->start, t->svc_range->end,
NULL, configure_thermometer_cb, t);
}
@@ -1201,11 +1169,6 @@ static void attio_disconnected_cb(gpointer user_data)
DBG("GATT Disconnected");
- if (t->attindid > 0) {
- g_attrib_unregister(t->attrib, t->attindid);
- t->attindid = 0;
- }
-
if (t->attio_measurement_id > 0) {
g_attrib_unregister(t->attrib, t->attio_measurement_id);
t->attio_measurement_id = 0;
@@ -1216,6 +1179,11 @@ static void attio_disconnected_cb(gpointer user_data)
t->attio_intermediate_id = 0;
}
+ if (t->attio_interval_id > 0) {
+ g_attrib_unregister(t->attrib, t->attio_interval_id);
+ t->attio_interval_id = 0;
+ }
+
g_attrib_unref(t->attrib);
t->attrib = NULL;
}
--
1.8.0
^ permalink raw reply related
* [PATCH 07/15] thermometer: Remove descriptor structure
From: Andrzej Kaczmarek @ 2012-11-09 8:55 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1352451357-22097-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch removes descriptor structure which is now redundant since
useful data are now kept directly in thermometer structure.
---
profiles/thermometer/thermometer.c | 114 ++++++++++++++-----------------------
1 file changed, 43 insertions(+), 71 deletions(-)
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index b01ac7a..462173d 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -92,16 +92,9 @@ struct thermometer {
struct characteristic {
struct gatt_char attr; /* Characteristic */
- GSList *desc; /* Descriptors */
struct thermometer *t; /* Thermometer where the char belongs */
};
-struct descriptor {
- struct characteristic *ch;
- uint16_t handle;
- bt_uuid_t uuid;
-};
-
struct watcher {
struct thermometer_adapter *tadapter;
guint id;
@@ -169,7 +162,6 @@ static void destroy_char(gpointer user_data)
{
struct characteristic *c = user_data;
- g_slist_free_full(c->desc, g_free);
g_free(c);
}
@@ -504,7 +496,7 @@ static void interval_ind_handler(const uint8_t *pdu, uint16_t len,
static void valid_range_desc_cb(guint8 status, const guint8 *pdu, guint16 len,
gpointer user_data)
{
- struct descriptor *desc = user_data;
+ struct thermometer *t = user_data;
uint8_t value[VALID_RANGE_DESC_SIZE];
uint16_t max, min;
ssize_t vlen;
@@ -534,8 +526,8 @@ static void valid_range_desc_cb(guint8 status, const guint8 *pdu, guint16 len,
return;
}
- change_property(desc->ch->t, "Maximum", &max);
- change_property(desc->ch->t, "Minimum", &min);
+ change_property(t, "Maximum", &max);
+ change_property(t, "Minimum", &min);
}
static void write_ccc_cb(guint8 status, const guint8 *pdu,
@@ -549,67 +541,50 @@ static void write_ccc_cb(guint8 status, const guint8 *pdu,
g_free(msg);
}
-static void process_thermometer_desc(struct descriptor *desc)
+static void process_thermometer_desc(struct characteristic *ch, uint16_t uuid,
+ uint16_t handle)
{
- struct characteristic *ch = desc->ch;
- char uuidstr[MAX_LEN_UUID_STR];
- bt_uuid_t btuuid;
+ uint8_t atval[2];
+ uint16_t val;
+ char *msg;
- bt_uuid16_create(&btuuid, GATT_CLIENT_CHARAC_CFG_UUID);
+ if (uuid == GATT_CHARAC_VALID_RANGE_UUID) {
+ if (g_strcmp0(ch->attr.uuid, MEASUREMENT_INTERVAL_UUID) == 0)
+ gatt_read_char(ch->t->attrib, handle,
+ valid_range_desc_cb, ch->t);
+ return;
+ }
- if (bt_uuid_cmp(&desc->uuid, &btuuid) == 0) {
- uint8_t atval[2];
- uint16_t val;
- char *msg;
+ if (uuid != GATT_CLIENT_CHARAC_CFG_UUID)
+ return;
- if (g_strcmp0(ch->attr.uuid,
- TEMPERATURE_MEASUREMENT_UUID) == 0) {
- desc->ch->t->measurement_ccc_handle = desc->handle;
+ if (g_strcmp0(ch->attr.uuid, TEMPERATURE_MEASUREMENT_UUID) == 0) {
+ ch->t->measurement_ccc_handle = handle;
- if (g_slist_length(ch->t->tadapter->fwatchers) == 0)
- return;
+ if (g_slist_length(ch->t->tadapter->fwatchers) == 0)
+ return;
- val = GATT_CLIENT_CHARAC_CFG_IND_BIT;
- msg = g_strdup("Enable Temperature Measurement "
- "indication");
- } else if (g_strcmp0(ch->attr.uuid,
+ val = GATT_CLIENT_CHARAC_CFG_IND_BIT;
+ msg = g_strdup("Enable Temperature Measurement indication");
+ } else if (g_strcmp0(ch->attr.uuid,
INTERMEDIATE_TEMPERATURE_UUID) == 0) {
- desc->ch->t->intermediate_ccc_handle = desc->handle;
-
- if (g_slist_length(ch->t->tadapter->iwatchers) == 0)
- return;
-
- val = GATT_CLIENT_CHARAC_CFG_NOTIF_BIT;
- msg = g_strdup("Enable Intermediate Temperature "
- "notification");
- } else if (g_strcmp0(ch->attr.uuid,
- MEASUREMENT_INTERVAL_UUID) == 0) {
- val = GATT_CLIENT_CHARAC_CFG_IND_BIT;
- msg = g_strdup("Enable Measurement Interval "
- "indication");
- } else {
- goto done;
- }
+ ch->t->intermediate_ccc_handle = handle;
- att_put_u16(val, atval);
- gatt_write_char(ch->t->attrib, desc->handle, atval, 2,
- write_ccc_cb, msg);
- return;
- }
-
- bt_uuid16_create(&btuuid, GATT_CHARAC_VALID_RANGE_UUID);
+ if (g_slist_length(ch->t->tadapter->iwatchers) == 0)
+ return;
- if (bt_uuid_cmp(&desc->uuid, &btuuid) == 0 && g_strcmp0(ch->attr.uuid,
- MEASUREMENT_INTERVAL_UUID) == 0) {
- gatt_read_char(ch->t->attrib, desc->handle, valid_range_desc_cb,
- desc);
+ val = GATT_CLIENT_CHARAC_CFG_NOTIF_BIT;
+ msg = g_strdup("Enable Intermediate Temperature notification");
+ } else if (g_strcmp0(ch->attr.uuid, MEASUREMENT_INTERVAL_UUID) == 0) {
+ val = GATT_CLIENT_CHARAC_CFG_IND_BIT;
+ msg = g_strdup("Enable Measurement Interval indication");
+ } else {
return;
}
-done:
- bt_uuid_to_string(&desc->uuid, uuidstr, MAX_LEN_UUID_STR);
- DBG("Ignored descriptor %s in characteristic %s", uuidstr,
- ch->attr.uuid);
+ att_put_u16(val, atval);
+ gatt_write_char(ch->t->attrib, handle, atval, sizeof(atval),
+ write_ccc_cb, msg);
}
static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len,
@@ -630,24 +605,21 @@ static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len,
if (list == NULL)
return;
+ if (format != ATT_FIND_INFO_RESP_FMT_16BIT)
+ goto done;
+
for (i = 0; i < list->num; i++) {
- struct descriptor *desc;
uint8_t *value;
+ uint16_t handle, uuid;
value = list->data[i];
- desc = g_new0(struct descriptor, 1);
- desc->handle = att_get_u16(value);
- desc->ch = ch;
-
- if (format == ATT_FIND_INFO_RESP_FMT_16BIT)
- desc->uuid = att_get_uuid16(&value[2]);
- else
- desc->uuid = att_get_uuid128(&value[2]);
+ handle = att_get_u16(value);
+ uuid = att_get_u16(value + 2);
- ch->desc = g_slist_append(ch->desc, desc);
- process_thermometer_desc(desc);
+ process_thermometer_desc(ch, uuid, handle);
}
+done:
att_data_list_free(list);
}
--
1.8.0
^ permalink raw reply related
* [PATCH 08/15] thermometer: Remove storage of all discovered characteristics
From: Andrzej Kaczmarek @ 2012-11-09 8:55 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1352451357-22097-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch removes structures used to keep all discovered characteristics
in thermometer structure. Useful values are already stored directly in
this structure.
characteristic structure is now only used as temporary user data when
discovering descriptors for particular characteristic.
---
profiles/thermometer/thermometer.c | 138 +++++++++++++++++--------------------
1 file changed, 65 insertions(+), 73 deletions(-)
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index 462173d..63d9c1e 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -76,7 +76,6 @@ struct thermometer {
guint attio_intermediate_id;
/* attio id for Measurement Interval value indications */
guint attio_interval_id;
- GSList *chars; /* Characteristics */
gboolean intermediate;
uint8_t type;
uint16_t interval;
@@ -91,8 +90,8 @@ struct thermometer {
};
struct characteristic {
- struct gatt_char attr; /* Characteristic */
struct thermometer *t; /* Thermometer where the char belongs */
+ char uuid[MAX_LEN_UUID_STR + 1];
};
struct watcher {
@@ -158,13 +157,6 @@ static void remove_watcher(gpointer user_data)
g_dbus_remove_watch(btd_get_dbus_connection(), watcher->id);
}
-static void destroy_char(gpointer user_data)
-{
- struct characteristic *c = user_data;
-
- g_free(c);
-}
-
static void destroy_thermometer(gpointer user_data)
{
struct thermometer *t = user_data;
@@ -179,9 +171,6 @@ static void destroy_thermometer(gpointer user_data)
if (t->attrib != NULL)
g_attrib_unref(t->attrib);
- if (t->chars != NULL)
- g_slist_free_full(t->chars, destroy_char);
-
btd_device_unref(t->dev);
g_free(t->svc_range);
g_free(t);
@@ -549,7 +538,7 @@ static void process_thermometer_desc(struct characteristic *ch, uint16_t uuid,
char *msg;
if (uuid == GATT_CHARAC_VALID_RANGE_UUID) {
- if (g_strcmp0(ch->attr.uuid, MEASUREMENT_INTERVAL_UUID) == 0)
+ if (g_strcmp0(ch->uuid, MEASUREMENT_INTERVAL_UUID) == 0)
gatt_read_char(ch->t->attrib, handle,
valid_range_desc_cb, ch->t);
return;
@@ -558,7 +547,7 @@ static void process_thermometer_desc(struct characteristic *ch, uint16_t uuid,
if (uuid != GATT_CLIENT_CHARAC_CFG_UUID)
return;
- if (g_strcmp0(ch->attr.uuid, TEMPERATURE_MEASUREMENT_UUID) == 0) {
+ if (g_strcmp0(ch->uuid, TEMPERATURE_MEASUREMENT_UUID) == 0) {
ch->t->measurement_ccc_handle = handle;
if (g_slist_length(ch->t->tadapter->fwatchers) == 0)
@@ -566,8 +555,7 @@ static void process_thermometer_desc(struct characteristic *ch, uint16_t uuid,
val = GATT_CLIENT_CHARAC_CFG_IND_BIT;
msg = g_strdup("Enable Temperature Measurement indication");
- } else if (g_strcmp0(ch->attr.uuid,
- INTERMEDIATE_TEMPERATURE_UUID) == 0) {
+ } else if (g_strcmp0(ch->uuid, INTERMEDIATE_TEMPERATURE_UUID) == 0) {
ch->t->intermediate_ccc_handle = handle;
if (g_slist_length(ch->t->tadapter->iwatchers) == 0)
@@ -575,7 +563,7 @@ static void process_thermometer_desc(struct characteristic *ch, uint16_t uuid,
val = GATT_CLIENT_CHARAC_CFG_NOTIF_BIT;
msg = g_strdup("Enable Intermediate Temperature notification");
- } else if (g_strcmp0(ch->attr.uuid, MEASUREMENT_INTERVAL_UUID) == 0) {
+ } else if (g_strcmp0(ch->uuid, MEASUREMENT_INTERVAL_UUID) == 0) {
val = GATT_CLIENT_CHARAC_CFG_IND_BIT;
msg = g_strdup("Enable Measurement Interval indication");
} else {
@@ -591,19 +579,19 @@ static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len,
gpointer user_data)
{
struct characteristic *ch = user_data;
- struct att_data_list *list;
+ struct att_data_list *list = NULL;
uint8_t format;
int i;
if (status != 0) {
error("Discover all characteristic descriptors failed [%s]: %s",
- ch->attr.uuid, att_ecode2str(status));
- return;
+ ch->uuid, att_ecode2str(status));
+ goto done;
}
list = dec_find_info_resp(pdu, len, &format);
if (list == NULL)
- return;
+ goto done;
if (format != ATT_FIND_INFO_RESP_FMT_16BIT)
goto done;
@@ -620,14 +608,40 @@ static void discover_desc_cb(guint8 status, const guint8 *pdu, guint16 len,
}
done:
- att_data_list_free(list);
+ if (list != NULL)
+ att_data_list_free(list);
+ g_free(ch);
+}
+
+static void discover_desc(struct thermometer *t, struct gatt_char *c,
+ struct gatt_char *c_next)
+{
+ struct characteristic *ch;
+ uint16_t start, end;
+
+ start = c->value_handle + 1;
+
+ if (c_next != NULL) {
+ if (start == c_next->handle)
+ return;
+ end = c_next->handle - 1;
+ } else if (c->value_handle != t->svc_range->end) {
+ end = t->svc_range->end;
+ } else {
+ return;
+ }
+
+ ch = g_new0(struct characteristic, 1);
+ ch->t = t;
+ memcpy(ch->uuid, c->uuid, sizeof(c->uuid));
+
+ gatt_find_info(t->attrib, start, end, discover_desc_cb, ch);
}
static void read_temp_type_cb(guint8 status, const guint8 *pdu, guint16 len,
gpointer user_data)
{
- struct characteristic *ch = user_data;
- struct thermometer *t = ch->t;
+ struct thermometer *t = user_data;
uint8_t value[TEMPERATURE_TYPE_SIZE];
ssize_t vlen;
@@ -655,7 +669,7 @@ static void read_temp_type_cb(guint8 status, const guint8 *pdu, guint16 len,
static void read_interval_cb(guint8 status, const guint8 *pdu, guint16 len,
gpointer user_data)
{
- struct characteristic *ch = user_data;
+ struct thermometer *t = user_data;
uint8_t value[MEASUREMENT_INTERVAL_SIZE];
uint16_t interval;
ssize_t vlen;
@@ -678,38 +692,41 @@ static void read_interval_cb(guint8 status, const guint8 *pdu, guint16 len,
}
interval = att_get_u16(&value[0]);
- change_property(ch->t, "Interval", &interval);
+ change_property(t, "Interval", &interval);
}
-static void process_thermometer_char(struct characteristic *ch)
+static void process_thermometer_char(struct thermometer *t,
+ struct gatt_char *c, struct gatt_char *c_next)
{
- struct thermometer *t = ch->t;
-
- if (g_strcmp0(ch->attr.uuid, INTERMEDIATE_TEMPERATURE_UUID) == 0) {
+ if (g_strcmp0(c->uuid, INTERMEDIATE_TEMPERATURE_UUID) == 0) {
gboolean intermediate = TRUE;
- change_property(ch->t, "Intermediate", &intermediate);
+ change_property(t, "Intermediate", &intermediate);
t->attio_intermediate_id = g_attrib_register(t->attrib,
- ATT_OP_HANDLE_NOTIFY, ch->attr.value_handle,
- intermediate_notify_handler, t, NULL);
- } else if (g_strcmp0(ch->attr.uuid,
- TEMPERATURE_MEASUREMENT_UUID) == 0) {
+ ATT_OP_HANDLE_NOTIFY, c->value_handle,
+ intermediate_notify_handler, t, NULL);
+
+ discover_desc(t, c, c_next);
+ } else if (g_strcmp0(c->uuid, TEMPERATURE_MEASUREMENT_UUID) == 0) {
t->attio_measurement_id = g_attrib_register(t->attrib,
- ATT_OP_HANDLE_IND, ch->attr.value_handle,
- measurement_ind_handler, t, NULL);
- } else if (g_strcmp0(ch->attr.uuid, TEMPERATURE_TYPE_UUID) == 0) {
- gatt_read_char(ch->t->attrib, ch->attr.value_handle,
- read_temp_type_cb, ch);
- } else if (g_strcmp0(ch->attr.uuid, MEASUREMENT_INTERVAL_UUID) == 0) {
- ch->t->interval_val_handle = ch->attr.value_handle;
+ ATT_OP_HANDLE_IND, c->value_handle,
+ measurement_ind_handler, t, NULL);
- gatt_read_char(ch->t->attrib, ch->attr.value_handle,
- read_interval_cb, ch);
+ discover_desc(t, c, c_next);
+ } else if (g_strcmp0(c->uuid, TEMPERATURE_TYPE_UUID) == 0) {
+ gatt_read_char(t->attrib, c->value_handle,
+ read_temp_type_cb, t);
+ } else if (g_strcmp0(c->uuid, MEASUREMENT_INTERVAL_UUID) == 0) {
+ gatt_read_char(t->attrib, c->value_handle, read_interval_cb, t);
+
+ t->interval_val_handle = c->value_handle;
t->attio_interval_id = g_attrib_register(t->attrib,
- ATT_OP_HANDLE_IND, ch->attr.value_handle,
- interval_ind_handler, t, NULL);
+ ATT_OP_HANDLE_IND, c->value_handle,
+ interval_ind_handler, t, NULL);
+
+ discover_desc(t, c, c_next);
}
}
@@ -727,34 +744,9 @@ static void configure_thermometer_cb(GSList *characteristics, guint8 status,
for (l = characteristics; l; l = l->next) {
struct gatt_char *c = l->data;
- struct characteristic *ch;
- uint16_t start, end;
-
- ch = g_new0(struct characteristic, 1);
- ch->attr.handle = c->handle;
- ch->attr.properties = c->properties;
- ch->attr.value_handle = c->value_handle;
- memcpy(ch->attr.uuid, c->uuid, MAX_LEN_UUID_STR + 1);
- ch->t = t;
-
- t->chars = g_slist_append(t->chars, ch);
-
- process_thermometer_char(ch);
-
- start = c->value_handle + 1;
-
- if (l->next != NULL) {
- struct gatt_char *c = l->next->data;
- if (start == c->handle)
- continue;
- end = c->handle - 1;
- } else if (c->value_handle != t->svc_range->end) {
- end = t->svc_range->end;
- } else {
- continue;
- }
+ struct gatt_char *c_next = (l->next ? l->next->data : NULL);
- gatt_find_info(t->attrib, start, end, discover_desc_cb, ch);
+ process_thermometer_char(t, c, c_next);
}
}
--
1.8.0
^ permalink raw reply related
* [PATCH 09/15] thermometer: Discover Measurement Interval descriptors only if needed
From: Andrzej Kaczmarek @ 2012-11-09 8:55 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1352451357-22097-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch will make descriptor discovery started only if Measurement
Interval characteristic properties are either write or indicate, otherwise
there are no known descriptors to be discovered.
---
profiles/thermometer/thermometer.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index 63d9c1e..30f79b0 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -718,15 +718,24 @@ static void process_thermometer_char(struct thermometer *t,
gatt_read_char(t->attrib, c->value_handle,
read_temp_type_cb, t);
} else if (g_strcmp0(c->uuid, MEASUREMENT_INTERVAL_UUID) == 0) {
+ bool need_desc = false;
+
gatt_read_char(t->attrib, c->value_handle, read_interval_cb, t);
- t->interval_val_handle = c->value_handle;
+ if (c->properties & ATT_CHAR_PROPER_WRITE) {
+ t->interval_val_handle = c->value_handle;
+ need_desc = true;
+ }
- t->attio_interval_id = g_attrib_register(t->attrib,
+ if (c->properties & ATT_CHAR_PROPER_INDICATE) {
+ t->attio_interval_id = g_attrib_register(t->attrib,
ATT_OP_HANDLE_IND, c->value_handle,
interval_ind_handler, t, NULL);
+ need_desc = true;
+ }
- discover_desc(t, c, c_next);
+ if (need_desc)
+ discover_desc(t, c, c_next);
}
}
--
1.8.0
^ permalink raw reply related
* [PATCH 10/15] thermometer: Always write CCC value when connecting
From: Andrzej Kaczmarek @ 2012-11-09 8:55 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1352451357-22097-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch ensures that CCC values for Intermediate Temperature and
Termperature Measurement are always written when connecting to device.
This is to i.e. disable notifications and/or indications in case they
are already enabled (reconnection scenario) but we don't have watcher
registered so it's pointless for remote to send us data.
---
profiles/thermometer/thermometer.c | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index 30f79b0..ad1a41d 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -550,19 +550,23 @@ static void process_thermometer_desc(struct characteristic *ch, uint16_t uuid,
if (g_strcmp0(ch->uuid, TEMPERATURE_MEASUREMENT_UUID) == 0) {
ch->t->measurement_ccc_handle = handle;
- if (g_slist_length(ch->t->tadapter->fwatchers) == 0)
- return;
-
- val = GATT_CLIENT_CHARAC_CFG_IND_BIT;
- msg = g_strdup("Enable Temperature Measurement indication");
+ if (g_slist_length(ch->t->tadapter->fwatchers) == 0) {
+ val = 0x0000;
+ msg = g_strdup("Disable Temperature Measurement ind");
+ } else {
+ val = GATT_CLIENT_CHARAC_CFG_IND_BIT;
+ msg = g_strdup("Enable Temperature Measurement ind");
+ }
} else if (g_strcmp0(ch->uuid, INTERMEDIATE_TEMPERATURE_UUID) == 0) {
ch->t->intermediate_ccc_handle = handle;
- if (g_slist_length(ch->t->tadapter->iwatchers) == 0)
- return;
-
- val = GATT_CLIENT_CHARAC_CFG_NOTIF_BIT;
- msg = g_strdup("Enable Intermediate Temperature notification");
+ if (g_slist_length(ch->t->tadapter->iwatchers) == 0) {
+ val = 0x0000;
+ msg = g_strdup("Disable Intermediate Temperature noti");
+ } else {
+ val = GATT_CLIENT_CHARAC_CFG_NOTIF_BIT;
+ msg = g_strdup("Enable Intermediate Temperature noti");
+ }
} else if (g_strcmp0(ch->uuid, MEASUREMENT_INTERVAL_UUID) == 0) {
val = GATT_CLIENT_CHARAC_CFG_IND_BIT;
msg = g_strdup("Enable Measurement Interval indication");
--
1.8.0
^ permalink raw reply related
* [PATCH 11/15] thermometer: Make temp_type array static
From: Andrzej Kaczmarek @ 2012-11-09 8:55 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1352451357-22097-1-git-send-email-andrzej.kaczmarek@tieto.com>
---
profiles/thermometer/thermometer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index ad1a41d..446f011 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -119,7 +119,7 @@ struct tmp_interval_data {
static GSList *thermometer_adapters = NULL;
-const char *temp_type[] = {
+static const char * const temp_type[] = {
"<reserved>",
"armpit",
"body",
--
1.8.0
^ permalink raw reply related
* [PATCH 12/15] thermometer: Add DBus.Properties support
From: Andrzej Kaczmarek @ 2012-11-09 8:55 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1352451357-22097-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch adds handlers required to support generic DBus.Properties
interface.
---
profiles/thermometer/thermometer.c | 116 ++++++++++++++++++++++++++++++++++++-
1 file changed, 115 insertions(+), 1 deletion(-)
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index 446f011..b98fe88 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -276,7 +276,12 @@ static void change_property(struct thermometer *t, const char *name,
DBUS_TYPE_UINT16, &t->min);
} else {
DBG("%s is not a thermometer property", name);
+ return;
}
+
+ g_dbus_emit_property_changed(btd_get_dbus_connection(),
+ device_get_path(t->dev),
+ THERMOMETER_INTERFACE, name);
}
static void update_watcher(gpointer data, gpointer user_data)
@@ -1114,6 +1119,114 @@ static DBusMessage *disable_intermediate(DBusConnection *conn, DBusMessage *msg,
return dbus_message_new_method_return(msg);
}
+static gboolean property_get_intermediate(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct thermometer *t = data;
+ dbus_bool_t val;
+
+ val = !!t->intermediate;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
+
+ return TRUE;
+}
+
+static gboolean property_get_interval(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct thermometer *t = data;
+
+ if (!t->has_interval)
+ return FALSE;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &t->interval);
+
+ return TRUE;
+}
+
+static void property_set_interval(const GDBusPropertyTable *property,
+ DBusMessageIter *iter,
+ GDBusPendingPropertySet id, void *data)
+{
+ struct thermometer *t = data;
+ struct tmp_interval_data *interval_data;
+ uint16_t val;
+ uint8_t atval[2];
+
+ if (t->interval_val_handle == 0)
+ return g_dbus_pending_property_error(id,
+ ERROR_INTERFACE ".NotSupported",
+ "Operation is not supported");
+
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_UINT16)
+ return g_dbus_pending_property_error(id,
+ ERROR_INTERFACE ".InvalidArguments",
+ "Invalid arguments in method call");
+
+ dbus_message_iter_get_basic(iter, &val);
+
+ if (val < t->min || val > t->max)
+ return g_dbus_pending_property_error(id,
+ ERROR_INTERFACE ".InvalidArguments",
+ "Invalid arguments in method call");
+
+ att_put_u16(val, &atval[0]);
+
+ interval_data = g_new0(struct tmp_interval_data, 1);
+ interval_data->thermometer = t;
+ interval_data->interval = val;
+ gatt_write_char(t->attrib, t->interval_val_handle, atval, sizeof(atval),
+ write_interval_cb, interval_data);
+
+ g_dbus_pending_property_success(id);
+}
+
+static gboolean property_exists_interval(const GDBusPropertyTable *property,
+ void *data)
+{
+ struct thermometer *t = data;
+
+ return t->has_interval;
+}
+
+static gboolean property_get_maximum(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct thermometer *t = data;
+
+ if (!t->has_interval)
+ return FALSE;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &t->max);
+
+ return TRUE;
+}
+
+static gboolean property_get_minimum(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct thermometer *t = data;
+
+ if (!t->has_interval)
+ return FALSE;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &t->min);
+
+ return TRUE;
+}
+
+static const GDBusPropertyTable thermometer_properties[] = {
+ { "Intermediate", "b", property_get_intermediate },
+ { "Interval", "q", property_get_interval, property_set_interval,
+ property_exists_interval },
+ { "Maximum", "q", property_get_maximum, NULL,
+ property_exists_interval },
+ { "Minimum", "q", property_get_minimum, NULL,
+ property_exists_interval },
+ { }
+};
+
static const GDBusMethodTable thermometer_methods[] = {
{ GDBUS_METHOD("GetProperties",
NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
@@ -1191,7 +1304,8 @@ int thermometer_register(struct btd_device *device, struct gatt_primary *tattr)
if (!g_dbus_register_interface(btd_get_dbus_connection(),
path, THERMOMETER_INTERFACE,
thermometer_methods, thermometer_signals,
- NULL, t, destroy_thermometer)) {
+ thermometer_properties, t,
+ destroy_thermometer)) {
error("D-Bus failed to register %s interface",
THERMOMETER_INTERFACE);
destroy_thermometer(t);
--
1.8.0
^ permalink raw reply related
* [PATCH 13/15] thermometer: Remove legacy properties code
From: Andrzej Kaczmarek @ 2012-11-09 8:55 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1352451357-22097-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch removes Get-/SetProperties methods along with PropertyChanged
signal which are now redundant after moving to generic DBus.Properties
interface.
---
profiles/thermometer/thermometer.c | 129 +------------------------------------
1 file changed, 2 insertions(+), 127 deletions(-)
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index b98fe88..cb81da6 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -243,9 +243,6 @@ static void change_property(struct thermometer *t, const char *name,
return;
t->intermediate = *intermediate;
- emit_property_changed(device_get_path(t->dev),
- THERMOMETER_INTERFACE, name,
- DBUS_TYPE_BOOLEAN, &t->intermediate);
} else if (g_strcmp0(name, "Interval") == 0) {
uint16_t *interval = value;
if (t->has_interval && t->interval == *interval)
@@ -253,27 +250,18 @@ static void change_property(struct thermometer *t, const char *name,
t->has_interval = TRUE;
t->interval = *interval;
- emit_property_changed(device_get_path(t->dev),
- THERMOMETER_INTERFACE, name,
- DBUS_TYPE_UINT16, &t->interval);
} else if (g_strcmp0(name, "Maximum") == 0) {
uint16_t *max = value;
if (t->max == *max)
return;
t->max = *max;
- emit_property_changed(device_get_path(t->dev),
- THERMOMETER_INTERFACE, name,
- DBUS_TYPE_UINT16, &t->max);
} else if (g_strcmp0(name, "Minimum") == 0) {
uint16_t *min = value;
if (t->min == *min)
return;
t->min = *min;
- emit_property_changed(device_get_path(t->dev),
- THERMOMETER_INTERFACE, name,
- DBUS_TYPE_UINT16, &t->min);
} else {
DBG("%s is not a thermometer property", name);
return;
@@ -768,40 +756,6 @@ static void configure_thermometer_cb(GSList *characteristics, guint8 status,
}
}
-static DBusMessage *get_properties(DBusConnection *conn, DBusMessage *msg,
- void *data)
-{
- struct thermometer *t = data;
- DBusMessageIter iter;
- DBusMessageIter dict;
- DBusMessage *reply;
-
- reply = dbus_message_new_method_return(msg);
- if (reply == NULL)
- return NULL;
-
- dbus_message_iter_init_append(reply, &iter);
-
- 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, "Intermediate", DBUS_TYPE_BOOLEAN,
- &t->intermediate);
-
- if (t->has_interval) {
- dict_append_entry(&dict, "Interval", DBUS_TYPE_UINT16,
- &t->interval);
- dict_append_entry(&dict, "Maximum", DBUS_TYPE_UINT16, &t->max);
- dict_append_entry(&dict, "Minimum", DBUS_TYPE_UINT16, &t->min);
- }
-
- dbus_message_iter_close_container(&iter, &dict);
-
- return reply;
-}
-
static void write_interval_cb(guint8 status, const guint8 *pdu, guint16 len,
gpointer user_data)
{
@@ -824,68 +778,6 @@ done:
g_free(user_data);
}
-static DBusMessage *write_attr_interval(struct thermometer *t, DBusMessage *msg,
- uint16_t value)
-{
- struct tmp_interval_data *data;
- uint8_t atval[2];
-
- if (t->attrib == NULL)
- return btd_error_not_connected(msg);
-
- if (t->interval_val_handle == 0)
- return btd_error_not_available(msg);
-
- if (value < t->min || value > t->max)
- return btd_error_invalid_args(msg);
-
- att_put_u16(value, &atval[0]);
-
- data = g_new0(struct tmp_interval_data, 1);
- data->thermometer = t;
- data->interval = value;
- gatt_write_char(t->attrib, t->interval_val_handle, atval, 2,
- write_interval_cb, data);
-
- return dbus_message_new_method_return(msg);
-}
-
-static DBusMessage *set_property(DBusConnection *conn, DBusMessage *msg,
- void *data)
-{
- struct thermometer *t = data;
- const char *property;
- DBusMessageIter iter;
- DBusMessageIter sub;
- uint16_t value;
-
- 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);
- if (g_strcmp0("Interval", property) != 0)
- return btd_error_invalid_args(msg);
-
- if (!t->has_interval)
- return btd_error_not_available(msg);
-
- 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 (dbus_message_iter_get_arg_type(&sub) != DBUS_TYPE_UINT16)
- return btd_error_invalid_args(msg);
-
- dbus_message_iter_get_basic(&sub, &value);
-
- return write_attr_interval(t, msg, value);
-}
-
static void enable_final_measurement(gpointer data, gpointer user_data)
{
struct thermometer *t = data;
@@ -1227,22 +1119,6 @@ static const GDBusPropertyTable thermometer_properties[] = {
{ }
};
-static const GDBusMethodTable thermometer_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) },
- { }
-};
-
-static const GDBusSignalTable thermometer_signals[] = {
- { GDBUS_SIGNAL("PropertyChanged",
- GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
- { }
-};
-
static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
{
struct thermometer *t = user_data;
@@ -1303,9 +1179,8 @@ int thermometer_register(struct btd_device *device, struct gatt_primary *tattr)
if (!g_dbus_register_interface(btd_get_dbus_connection(),
path, THERMOMETER_INTERFACE,
- thermometer_methods, thermometer_signals,
- thermometer_properties, t,
- destroy_thermometer)) {
+ NULL, NULL, thermometer_properties,
+ t, destroy_thermometer)) {
error("D-Bus failed to register %s interface",
THERMOMETER_INTERFACE);
destroy_thermometer(t);
--
1.8.0
^ permalink raw reply related
* [PATCH 14/15] doc: Update thermometer API document
From: Andrzej Kaczmarek @ 2012-11-09 8:55 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1352451357-22097-1-git-send-email-andrzej.kaczmarek@tieto.com>
This patch updates thermometer-api.txt document to include changes in
properties handling.
---
doc/thermometer-api.txt | 18 ------------------
1 file changed, 18 deletions(-)
diff --git a/doc/thermometer-api.txt b/doc/thermometer-api.txt
index 7b99800..cab115f 100644
--- a/doc/thermometer-api.txt
+++ b/doc/thermometer-api.txt
@@ -48,24 +48,6 @@ 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
- property.
-
Properties boolean Intermediate [readonly]
True if the thermometer supports intermediate
--
1.8.0
^ permalink raw reply related
* [PATCH 15/15] test: Update test-thermometer for DBus.Properties
From: Andrzej Kaczmarek @ 2012-11-09 8:55 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Andrzej Kaczmarek
In-Reply-To: <1352451357-22097-1-git-send-email-andrzej.kaczmarek@tieto.com>
---
test/test-thermometer | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/test/test-thermometer b/test/test-thermometer
index 2ca260f..d56a8b2 100755
--- a/test/test-thermometer
+++ b/test/test-thermometer
@@ -29,9 +29,9 @@ class Watcher(dbus.service.Object):
if "Type" in measure:
print("Type: ", measure["Type"])
-def property_changed(name, value):
-
- print("PropertyChanged('%s', '%s')" % (name, value))
+def properties_changed(interface, changed, invalidated):
+ for name, value in changed.iteritems():
+ print("Property %s changed: %s" % (name, str(value)))
if __name__ == "__main__":
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
@@ -71,9 +71,10 @@ if __name__ == "__main__":
device_path = adapter.FindDevice(options.address)
- bus.add_signal_receiver(property_changed, bus_name="org.bluez",
- dbus_interface="org.bluez.Thermometer",
- signal_name="PropertyChanged")
+ bus.add_signal_receiver(properties_changed, bus_name="org.bluez",
+ path=device_path,
+ dbus_interface="org.freedesktop.DBus.Properties",
+ signal_name="PropertiesChanged")
path = "/test/watcher"
watcher = Watcher(bus, path)
--
1.8.0
^ permalink raw reply related
* Re: [PATCH 3/3 v2] Bluetooth: Fix updating advertising state flags and data
From: Gustavo Padovan @ 2012-11-09 9:41 UTC (permalink / raw)
To: Johan Hedberg; +Cc: linux-bluetooth
In-Reply-To: <1352334181-19198-3-git-send-email-johan.hedberg@gmail.com>
Hi Johan,
* Johan Hedberg <johan.hedberg@gmail.com> [2012-11-08 01:23:01 +0100]:
> From: Johan Hedberg <johan.hedberg@intel.com>
>
> This patch adds a callback for the HCI_LE_Set_Advertise_Enable command.
> The callback is responsible for updating the HCI_LE_PERIPHERAL flag
> updating as well as updating the advertising data flags field to
> indicate undirected connectable advertising.
>
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> Acked-by: Marcel Holtmann <marcel@holtmann.org>
> ---
> include/net/bluetooth/hci.h | 2 ++
> net/bluetooth/hci_event.c | 31 +++++++++++++++++++++++++++++++
> 2 files changed, 33 insertions(+)
All 3 patches have been applied to bluetooth-next. Thanks.
Gustavo
^ permalink raw reply
* Re: [PATCH] bluetooth: ath3k: Add support for VAIO VPCEH [0489:e027]
From: Gustavo Padovan @ 2012-11-09 9:43 UTC (permalink / raw)
To: Marcos Chaparro; +Cc: marcel, johan.hedberg, linux-bluetooth, linux-kernel
In-Reply-To: <1352229551-22842-1-git-send-email-marcos@mrkindustries.com.ar>
Hi Marcos,
* Marcos Chaparro <marcos@mrkindustries.com.ar> [2012-11-06 16:19:11 -0300]:
> Added Atheros AR3011 internal bluetooth device found in Sony VAIO VPCEH to the
> devices list.
> Before this, the bluetooth module was identified as an Foxconn / Hai bluetooth
> device [0489:e027], now it claims to be an AtherosAR3011 Bluetooth
> [0cf3:3005].
>
> T: Bus=01 Lev=02 Prnt=02 Port=04 Cnt=02 Dev#= 4 Spd=12 MxCh= 0
> D: Ver= 1.10 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1
> P: Vendor=0489 ProdID=e027 Rev= 0.01
> C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=100mA
> I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms
> E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
> E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
> I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms
> E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms
> I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms
> E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms
> I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms
> E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms
> I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms
> E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms
> I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms
> E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms
> I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb
> E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms
> E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms
>
> Signed-off-by: Marcos Chaparro <marcos@mrkindustries.com.ar>
> ---
> drivers/bluetooth/ath3k.c | 1 +
> drivers/bluetooth/btusb.c | 1 +
> 2 files changed, 2 insertions(+)
Patch has been applied to bluetooth.git. Thanks.
Gustavo
^ 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