Merge lp:~morphis/bluez/vivid-5.36-upgrade into lp:~bluetooth/bluez/vivid-phone-overlay

Proposed by Simon Fels on 2015-11-23
Status: Needs review
Proposed branch: lp:~morphis/bluez/vivid-5.36-upgrade
Merge into: lp:~bluetooth/bluez/vivid-phone-overlay
Diff against target: 8468 lines (+3180/-1202)
82 files modified
ChangeLog (+8/-0)
Makefile.am (+1/-1)
Makefile.in (+15/-4)
Makefile.tools (+3/-1)
android/Android.mk (+2/-0)
android/README (+6/-1)
android/bluetoothd-snoop.c (+3/-0)
configure (+10/-10)
configure.ac (+1/-1)
debian/changelog (+8/-0)
debian/control (+2/-0)
debian/patches/0001-obexd-pbap-add-headers-correctly-for-size-query.patch (+0/-44)
debian/patches/series (+0/-1)
doc/media-api.txt (+14/-10)
doc/mgmt-api.txt (+1/-0)
emulator/btdev.c (+135/-25)
lib/bluetooth.c (+56/-0)
monitor/analyze.c (+3/-0)
monitor/avctp.c (+41/-0)
monitor/broadcom.c (+251/-0)
monitor/broadcom.h (+32/-0)
monitor/bt.h (+56/-0)
monitor/control.c (+20/-5)
monitor/display.h (+1/-0)
monitor/hcidump.c (+6/-4)
monitor/intel.c (+926/-0)
monitor/intel.h (+31/-0)
monitor/ll.c (+43/-22)
monitor/ll.h (+2/-2)
monitor/lmp.c (+125/-11)
monitor/lmp.h (+1/-1)
monitor/packet.c (+362/-96)
monitor/packet.h (+20/-10)
monitor/vendor.h (+19/-0)
obexd/plugins/pbap.c (+3/-2)
profiles/audio/a2dp.c (+1/-1)
profiles/audio/avrcp.c (+22/-11)
profiles/audio/control.c (+58/-9)
profiles/audio/control.h (+2/-0)
profiles/audio/player.c (+5/-0)
profiles/audio/player.h (+1/-0)
profiles/deviceinfo/deviceinfo.c (+74/-121)
profiles/gap/gas.c (+0/-42)
profiles/scanparam/scan.c (+187/-179)
src/advertising.c (+2/-2)
src/bluetooth.service.in (+1/-0)
src/device.c (+38/-33)
src/gatt-client.c (+1/-1)
src/profile.c (+6/-2)
src/service.c (+12/-0)
src/shared/ad.c (+11/-7)
src/shared/ad.h (+11/-7)
src/shared/btsnoop.c (+20/-6)
src/shared/btsnoop.h (+9/-0)
src/shared/util.h (+5/-0)
tools/hciconfig.c (+1/-1)
tools/mpris-proxy.c (+1/-1)
tools/parser/att.c (+46/-46)
tools/parser/avctp.c (+2/-2)
tools/parser/avdtp.c (+36/-36)
tools/parser/avrcp.c (+145/-145)
tools/parser/bnep.c (+25/-25)
tools/parser/bpa.c (+8/-8)
tools/parser/capi.c (+4/-4)
tools/parser/cmtp.c (+3/-3)
tools/parser/csr.c (+3/-3)
tools/parser/ericsson.c (+1/-1)
tools/parser/hci.c (+30/-30)
tools/parser/hcrp.c (+6/-6)
tools/parser/hidp.c (+1/-1)
tools/parser/lmp.c (+3/-3)
tools/parser/obex.c (+12/-12)
tools/parser/parser.h (+7/-7)
tools/parser/ppp.c (+4/-4)
tools/parser/sap.c (+12/-12)
tools/parser/sdp.c (+25/-25)
tools/parser/smp.c (+17/-17)
tools/sco-tester.c (+1/-0)
unit/test-gobex-header.c (+1/-1)
unit/test-hfp.c (+44/-47)
unit/test-sdp.c (+43/-54)
unit/test-uhid.c (+26/-36)
To merge this branch: bzr merge lp:~morphis/bluez/vivid-5.36-upgrade
Reviewer Review Type Date Requested Status
Bluetooth 2015-11-23 Pending
Review via email: mp+278302@code.launchpad.net

Description of the change

Upgrade to upstream release 5.36

To post a comment you must log in.
lp:~morphis/bluez/vivid-5.36-upgrade updated on 2015-11-23
10. By Simon Fels on 2015-11-23

Fix changelog to work better with citrain

Unmerged revisions

10. By Simon Fels on 2015-11-23

Fix changelog to work better with citrain

9. By Simon Fels on 2015-11-23

Prevent citrain from rewriting our version number

8. By Simon Fels on 2015-11-23

Update changelog

7. By Simon Fels on 2015-11-23

Drop upstreamed PBAP patch

6. By Simon Fels on 2015-11-23

Import upstream release 5.36

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'ChangeLog'
2--- ChangeLog 2015-10-06 11:46:27 +0000
3+++ ChangeLog 2015-11-23 18:34:05 +0000
4@@ -1,3 +1,11 @@
5+ver 5.36:
6+ Fix issue with PBAP headers for size query.
7+ Fix issue with AVRCP current player handling.
8+ Fix issue with device information handling.
9+ Fix issue with device disconnect handling.
10+ Fix issue with duplicate connect handling.
11+ Fix issue with attribute claiming for drivers.
12+
13 ver 5.35:
14 Fix issue with connected devices after discovery.
15 Fix issue with profile support and LTK loading.
16
17=== modified file 'Makefile.am'
18--- Makefile.am 2015-10-06 11:46:27 +0000
19+++ Makefile.am 2015-11-23 18:34:05 +0000
20@@ -80,7 +80,7 @@
21 lib_LTLIBRARIES += lib/libbluetooth.la
22
23 lib_libbluetooth_la_SOURCES = $(lib_headers) $(lib_sources)
24-lib_libbluetooth_la_LDFLAGS = $(AM_LDFLAGS) -version-info 21:8:18
25+lib_libbluetooth_la_LDFLAGS = $(AM_LDFLAGS) -version-info 21:9:18
26 lib_libbluetooth_la_DEPENDENCIES = $(local_headers)
27 endif
28
29
30=== modified file 'Makefile.in'
31--- Makefile.in 2015-10-06 11:46:27 +0000
32+++ Makefile.in 2015-11-23 18:34:05 +0000
33@@ -747,7 +747,8 @@
34 monitor/rfcomm.h monitor/rfcomm.c monitor/bnep.h \
35 monitor/bnep.c monitor/uuid.h monitor/uuid.c monitor/hwdb.h \
36 monitor/hwdb.c monitor/keys.h monitor/keys.c monitor/analyze.h \
37- monitor/analyze.c
38+ monitor/analyze.c monitor/intel.h monitor/intel.c \
39+ monitor/broadcom.h monitor/broadcom.c
40 @MONITOR_TRUE@am_monitor_btmon_OBJECTS = monitor/main.$(OBJEXT) \
41 @MONITOR_TRUE@ monitor/display.$(OBJEXT) \
42 @MONITOR_TRUE@ monitor/hcidump.$(OBJEXT) \
43@@ -760,7 +761,9 @@
44 @MONITOR_TRUE@ monitor/avctp.$(OBJEXT) monitor/rfcomm.$(OBJEXT) \
45 @MONITOR_TRUE@ monitor/bnep.$(OBJEXT) monitor/uuid.$(OBJEXT) \
46 @MONITOR_TRUE@ monitor/hwdb.$(OBJEXT) monitor/keys.$(OBJEXT) \
47-@MONITOR_TRUE@ monitor/analyze.$(OBJEXT)
48+@MONITOR_TRUE@ monitor/analyze.$(OBJEXT) \
49+@MONITOR_TRUE@ monitor/intel.$(OBJEXT) \
50+@MONITOR_TRUE@ monitor/broadcom.$(OBJEXT)
51 monitor_btmon_OBJECTS = $(am_monitor_btmon_OBJECTS)
52 @MONITOR_TRUE@monitor_btmon_DEPENDENCIES = \
53 @MONITOR_TRUE@ lib/libbluetooth-internal.la \
54@@ -2237,7 +2240,7 @@
55 local_headers = $(foreach file,$(lib_headers), lib/bluetooth/$(notdir $(file)))
56 BUILT_SOURCES = $(local_headers) src/builtin.h obexd/src/builtin.h
57 @LIBRARY_TRUE@lib_libbluetooth_la_SOURCES = $(lib_headers) $(lib_sources)
58-@LIBRARY_TRUE@lib_libbluetooth_la_LDFLAGS = $(AM_LDFLAGS) -version-info 21:8:18
59+@LIBRARY_TRUE@lib_libbluetooth_la_LDFLAGS = $(AM_LDFLAGS) -version-info 21:9:18
60 @LIBRARY_TRUE@lib_libbluetooth_la_DEPENDENCIES = $(local_headers)
61 lib_libbluetooth_internal_la_SOURCES = $(lib_headers) $(lib_sources) \
62 $(extra_headers) $(extra_sources)
63@@ -2427,7 +2430,9 @@
64 @MONITOR_TRUE@ monitor/uuid.h monitor/uuid.c \
65 @MONITOR_TRUE@ monitor/hwdb.h monitor/hwdb.c \
66 @MONITOR_TRUE@ monitor/keys.h monitor/keys.c \
67-@MONITOR_TRUE@ monitor/analyze.h monitor/analyze.c
68+@MONITOR_TRUE@ monitor/analyze.h monitor/analyze.c \
69+@MONITOR_TRUE@ monitor/intel.h monitor/intel.c \
70+@MONITOR_TRUE@ monitor/broadcom.h monitor/broadcom.c
71
72 @MONITOR_TRUE@monitor_btmon_LDADD = lib/libbluetooth-internal.la \
73 @MONITOR_TRUE@ src/libshared-mainloop.la @UDEV_LIBS@
74@@ -3999,6 +4004,10 @@
75 monitor/$(DEPDIR)/$(am__dirstamp)
76 monitor/analyze.$(OBJEXT): monitor/$(am__dirstamp) \
77 monitor/$(DEPDIR)/$(am__dirstamp)
78+monitor/intel.$(OBJEXT): monitor/$(am__dirstamp) \
79+ monitor/$(DEPDIR)/$(am__dirstamp)
80+monitor/broadcom.$(OBJEXT): monitor/$(am__dirstamp) \
81+ monitor/$(DEPDIR)/$(am__dirstamp)
82
83 monitor/btmon$(EXEEXT): $(monitor_btmon_OBJECTS) $(monitor_btmon_DEPENDENCIES) $(EXTRA_monitor_btmon_DEPENDENCIES) monitor/$(am__dirstamp)
84 @rm -f monitor/btmon$(EXEEXT)
85@@ -5275,12 +5284,14 @@
86 @AMDEP_TRUE@@am__include@ @am__quote@monitor/$(DEPDIR)/analyze.Po@am__quote@
87 @AMDEP_TRUE@@am__include@ @am__quote@monitor/$(DEPDIR)/avctp.Po@am__quote@
88 @AMDEP_TRUE@@am__include@ @am__quote@monitor/$(DEPDIR)/bnep.Po@am__quote@
89+@AMDEP_TRUE@@am__include@ @am__quote@monitor/$(DEPDIR)/broadcom.Po@am__quote@
90 @AMDEP_TRUE@@am__include@ @am__quote@monitor/$(DEPDIR)/control.Po@am__quote@
91 @AMDEP_TRUE@@am__include@ @am__quote@monitor/$(DEPDIR)/crc.Po@am__quote@
92 @AMDEP_TRUE@@am__include@ @am__quote@monitor/$(DEPDIR)/display.Po@am__quote@
93 @AMDEP_TRUE@@am__include@ @am__quote@monitor/$(DEPDIR)/ellisys.Po@am__quote@
94 @AMDEP_TRUE@@am__include@ @am__quote@monitor/$(DEPDIR)/hcidump.Po@am__quote@
95 @AMDEP_TRUE@@am__include@ @am__quote@monitor/$(DEPDIR)/hwdb.Po@am__quote@
96+@AMDEP_TRUE@@am__include@ @am__quote@monitor/$(DEPDIR)/intel.Po@am__quote@
97 @AMDEP_TRUE@@am__include@ @am__quote@monitor/$(DEPDIR)/keys.Po@am__quote@
98 @AMDEP_TRUE@@am__include@ @am__quote@monitor/$(DEPDIR)/l2cap.Po@am__quote@
99 @AMDEP_TRUE@@am__include@ @am__quote@monitor/$(DEPDIR)/ll.Po@am__quote@
100
101=== modified file 'Makefile.tools'
102--- Makefile.tools 2015-09-15 13:42:52 +0000
103+++ Makefile.tools 2015-11-23 18:34:05 +0000
104@@ -32,7 +32,9 @@
105 monitor/uuid.h monitor/uuid.c \
106 monitor/hwdb.h monitor/hwdb.c \
107 monitor/keys.h monitor/keys.c \
108- monitor/analyze.h monitor/analyze.c
109+ monitor/analyze.h monitor/analyze.c \
110+ monitor/intel.h monitor/intel.c \
111+ monitor/broadcom.h monitor/broadcom.c
112 monitor_btmon_LDADD = lib/libbluetooth-internal.la \
113 src/libshared-mainloop.la @UDEV_LIBS@
114 endif
115
116=== modified file 'android/Android.mk'
117--- android/Android.mk 2015-09-15 13:42:52 +0000
118+++ android/Android.mk 2015-11-23 18:34:05 +0000
119@@ -351,6 +351,8 @@
120 bluez/monitor/keys.c \
121 bluez/monitor/ellisys.c \
122 bluez/monitor/analyze.c \
123+ bluez/monitor/intel.c \
124+ bluez/monitor/broadcom.c \
125 bluez/src/shared/util.c \
126 bluez/src/shared/queue.c \
127 bluez/src/shared/crypto.c \
128
129=== modified file 'android/README'
130--- android/README 2015-09-15 13:42:52 +0000
131+++ android/README 2015-11-23 18:34:05 +0000
132@@ -9,7 +9,7 @@
133 More details about BlueZ for Android architecture and components can be found
134 in android/hal-ipc-api.txt file.
135
136-Supported Android version: 4.4 KitKat and 5.0 Lollipop
137+Supported Android version: 4.4 KitKat and 5.0, 5.1 Lollipop
138
139
140 Building and running on Android
141@@ -402,12 +402,16 @@
142 recommended Android fixes that are not part of latest AOSP release supported by
143 BlueZ.
144
145+For Android 5.1 Lollipop:
146+https://android-review.googlesource.com/177314
147+
148 For Android 5.0 Lollipop:
149 https://android-review.googlesource.com/99761
150 https://android-review.googlesource.com/100297
151 https://android-review.googlesource.com/102882
152 https://android-review.googlesource.com/132733
153 https://android-review.googlesource.com/132763
154+https://android-review.googlesource.com/177314
155
156 For Android 4.4 KitKat:
157 https://android-review.googlesource.com/82757
158@@ -417,6 +421,7 @@
159 https://android-review.googlesource.com/99850
160 https://android-review.googlesource.com/100297
161 https://android-review.googlesource.com/102882
162+https://android-review.googlesource.com/177314
163
164 Unimplemented Bluetooth features
165 ================================
166
167=== modified file 'android/bluetoothd-snoop.c'
168--- android/bluetoothd-snoop.c 2015-09-15 13:42:52 +0000
169+++ android/bluetoothd-snoop.c 2015-11-23 18:34:05 +0000
170@@ -73,6 +73,9 @@
171 case BTSNOOP_OPCODE_SCO_TX_PKT:
172 case BTSNOOP_OPCODE_SCO_RX_PKT:
173 break;
174+ case BTSNOOP_OPCODE_OPEN_INDEX:
175+ case BTSNOOP_OPCODE_CLOSE_INDEX:
176+ break;
177 }
178
179 return 0xff;
180
181=== modified file 'configure'
182--- configure 2015-10-06 11:46:27 +0000
183+++ configure 2015-11-23 18:34:05 +0000
184@@ -1,6 +1,6 @@
185 #! /bin/sh
186 # Guess values for system-dependent variables and create Makefiles.
187-# Generated by GNU Autoconf 2.69 for bluez 5.35.
188+# Generated by GNU Autoconf 2.69 for bluez 5.36.
189 #
190 #
191 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
192@@ -587,8 +587,8 @@
193 # Identity of this package.
194 PACKAGE_NAME='bluez'
195 PACKAGE_TARNAME='bluez'
196-PACKAGE_VERSION='5.35'
197-PACKAGE_STRING='bluez 5.35'
198+PACKAGE_VERSION='5.36'
199+PACKAGE_STRING='bluez 5.36'
200 PACKAGE_BUGREPORT=''
201 PACKAGE_URL=''
202
203@@ -1420,7 +1420,7 @@
204 # Omit some internal or obsolete options to make the list less imposing.
205 # This message is too long to be a string in the A/UX 3.1 sh.
206 cat <<_ACEOF
207-\`configure' configures bluez 5.35 to adapt to many kinds of systems.
208+\`configure' configures bluez 5.36 to adapt to many kinds of systems.
209
210 Usage: $0 [OPTION]... [VAR=VALUE]...
211
212@@ -1490,7 +1490,7 @@
213
214 if test -n "$ac_init_help"; then
215 case $ac_init_help in
216- short | recursive ) echo "Configuration of bluez 5.35:";;
217+ short | recursive ) echo "Configuration of bluez 5.36:";;
218 esac
219 cat <<\_ACEOF
220
221@@ -1649,7 +1649,7 @@
222 test -n "$ac_init_help" && exit $ac_status
223 if $ac_init_version; then
224 cat <<\_ACEOF
225-bluez configure 5.35
226+bluez configure 5.36
227 generated by GNU Autoconf 2.69
228
229 Copyright (C) 2012 Free Software Foundation, Inc.
230@@ -2014,7 +2014,7 @@
231 This file contains any messages produced by compilers while
232 running configure, to aid debugging if configure makes a mistake.
233
234-It was created by bluez $as_me 5.35, which was
235+It was created by bluez $as_me 5.36, which was
236 generated by GNU Autoconf 2.69. Invocation command line was
237
238 $ $0 $@
239@@ -2878,7 +2878,7 @@
240
241 # Define the identity of the package.
242 PACKAGE='bluez'
243- VERSION='5.35'
244+ VERSION='5.36'
245
246
247 cat >>confdefs.h <<_ACEOF
248@@ -14690,7 +14690,7 @@
249 # report actual input values of CONFIG_FILES etc. instead of their
250 # values after options handling.
251 ac_log="
252-This file was extended by bluez $as_me 5.35, which was
253+This file was extended by bluez $as_me 5.36, which was
254 generated by GNU Autoconf 2.69. Invocation command line was
255
256 CONFIG_FILES = $CONFIG_FILES
257@@ -14756,7 +14756,7 @@
258 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
259 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
260 ac_cs_version="\\
261-bluez config.status 5.35
262+bluez config.status 5.36
263 configured by $0, generated by GNU Autoconf 2.69,
264 with options \\"\$ac_cs_config\\"
265
266
267=== modified file 'configure.ac'
268--- configure.ac 2015-10-06 11:46:27 +0000
269+++ configure.ac 2015-11-23 18:34:05 +0000
270@@ -1,5 +1,5 @@
271 AC_PREREQ(2.60)
272-AC_INIT(bluez, 5.35)
273+AC_INIT(bluez, 5.36)
274
275 AM_INIT_AUTOMAKE([foreign subdir-objects color-tests silent-rules
276 tar-pax no-dist-gzip dist-xz])
277
278=== modified file 'debian/changelog'
279--- debian/changelog 2015-10-23 14:34:31 +0000
280+++ debian/changelog 2015-11-23 18:34:05 +0000
281@@ -1,3 +1,11 @@
282+bluez (5.36-0ubuntu2) UNRELEASED; urgency=medium
283+
284+ * New upstream release.
285+ * debian/patches/0001-obexd-pbap-add-headers-correctly-for-size-query.patch:
286+ - Drop patch as accepted upstream.
287+
288+ -- Simon Fels <simon.fels@canonical.com> Mon, 23 Nov 2015 07:11:59 +0100
289+
290 bluez (5.35+15.04.20151023-0ubuntu1) vivid; urgency=medium
291
292 [ Simon Fels ]
293
294=== modified file 'debian/control'
295--- debian/control 2015-10-12 09:54:28 +0000
296+++ debian/control 2015-11-23 18:34:05 +0000
297@@ -26,6 +26,8 @@
298 Homepage: http://www.bluez.org
299 Standards-Version: 3.9.5
300 XS-Testsuite: autopkgtest
301+# Prevent citrain from rewriting the version number which we don't want
302+X-Auto-Uploader: no-rewrite-version
303
304 Package: libbluetooth3
305 Section: libs
306
307=== removed file 'debian/patches/0001-obexd-pbap-add-headers-correctly-for-size-query.patch'
308--- debian/patches/0001-obexd-pbap-add-headers-correctly-for-size-query.patch 2015-10-19 12:06:57 +0000
309+++ debian/patches/0001-obexd-pbap-add-headers-correctly-for-size-query.patch 1970-01-01 00:00:00 +0000
310@@ -1,44 +0,0 @@
311-From 08ae4f17e97df49af0c702d43a957cb6529ef0a4 Mon Sep 17 00:00:00 2001
312-From: Simon Fels <simon.fels@canonical.com>
313-Date: Mon, 19 Oct 2015 13:58:15 +0200
314-Subject: [PATCH] obexd: pbap: add headers correctly for size query
315-
316-When client queries for the size of a phonebook we fall into a
317-indefinite loop as g_obex_apparam_encode always returns the same
318-number of items added to the buffer regardless how often it is
319-called. In former times where this code wasn't using GObexApparams
320-a array was reduced each time the headers where added and so we could
321-easily find out when we've added all headers. However today we need
322-to solve this a bit differently by also setting the firstpacket flag
323-when we receive the phonebook size result from the phonebook
324-implementation which then lets us correctly go through without
325-falling into a indefinite loop.
326----
327- obexd/plugins/pbap.c | 4 +++-
328- 1 file changed, 3 insertions(+), 1 deletion(-)
329-
330-diff --git a/obexd/plugins/pbap.c b/obexd/plugins/pbap.c
331-index f2f9166..1ecf379 100644
332---- a/obexd/plugins/pbap.c
333-+++ b/obexd/plugins/pbap.c
334-@@ -193,6 +193,8 @@ static void phonebook_size_result(const char *buffer, size_t bufsize,
335- pbap->obj->apparam = g_obex_apparam_set_uint16(NULL, PHONEBOOKSIZE_TAG,
336- phonebooksize);
337-
338-+ pbap->obj->firstpacket = TRUE;
339-+
340- if (missed > 0) {
341- DBG("missed %d", missed);
342-
343-@@ -833,7 +835,7 @@ static ssize_t vobject_pull_get_next_header(void *object, void *buf, size_t mtu,
344-
345- *hi = G_OBEX_HDR_APPARAM;
346-
347-- if (pbap->params->maxlistcount == 0 || obj->firstpacket) {
348-+ if (obj->firstpacket) {
349- obj->firstpacket = FALSE;
350-
351- return g_obex_apparam_encode(obj->apparam, buf, mtu);
352---
353-2.5.0
354-
355
356=== modified file 'debian/patches/series'
357--- debian/patches/series 2015-10-19 20:21:10 +0000
358+++ debian/patches/series 2015-11-23 18:34:05 +0000
359@@ -13,5 +13,4 @@
360 # dropped with one of the next releases
361 0001-core-device-expose-list-of-connected-profiles.patch
362 0002-client-add-support-for-new-property-to-list-connecte.patch
363-0001-obexd-pbap-add-headers-correctly-for-size-query.patch
364 0001-tools-mpris-proxy-allow-user-to-specify-different-mp.patch
365
366=== modified file 'doc/media-api.txt'
367--- doc/media-api.txt 2015-09-15 13:42:52 +0000
368+++ doc/media-api.txt 2015-11-23 18:34:05 +0000
369@@ -71,43 +71,43 @@
370 =======================
371
372 Service org.bluez
373-Interface org.bluez.MediaControl1 [Deprecated]
374+Interface org.bluez.MediaControl1
375 Object path [variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX
376
377-Methods void Play()
378+Methods void Play() [Deprecated]
379
380 Resume playback.
381
382- void Pause()
383+ void Pause() [Deprecated]
384
385 Pause playback.
386
387- void Stop()
388+ void Stop() [Deprecated]
389
390 Stop playback.
391
392- void Next()
393+ void Next() [Deprecated]
394
395 Next item.
396
397- void Previous()
398+ void Previous() [Deprecated]
399
400 Previous item.
401
402- void VolumeUp()
403+ void VolumeUp() [Deprecated]
404
405 Adjust remote volume one step up
406
407- void VolumeDown()
408+ void VolumeDown() [Deprecated]
409
410 Adjust remote volume one step down
411
412- void FastForward()
413+ void FastForward() [Deprecated]
414
415 Fast forward playback, this action is only stopped
416 when another method in this interface is called.
417
418- void Rewind()
419+ void Rewind() [Deprecated]
420
421 Rewind playback, this action is only stopped
422 when another method in this interface is called.
423@@ -116,6 +116,10 @@
424
425 boolean Connected [readonly]
426
427+ object Player [readonly, optional]
428+
429+ Addressed Player object path.
430+
431
432 MediaPlayer1 hierarchy
433 ======================
434
435=== modified file 'doc/mgmt-api.txt'
436--- doc/mgmt-api.txt 2015-09-15 13:42:52 +0000
437+++ doc/mgmt-api.txt 2015-11-23 18:34:05 +0000
438@@ -24,6 +24,7 @@
439 Linux kernel v3.17 Version 1.7
440 Linux kernel v3.19 Version 1.8
441 Linux kernel v4.1 Version 1.9
442+Linux kernel v4.2 Version 1.10
443
444 Version 1.1 introduces Set Device ID command.
445
446
447=== modified file 'emulator/btdev.c'
448--- emulator/btdev.c 2015-09-15 13:42:52 +0000
449+++ emulator/btdev.c 2015-11-23 18:34:05 +0000
450@@ -443,6 +443,10 @@
451 btdev->commands[28] |= 0x20; /* LE Transmitter Test */
452 btdev->commands[28] |= 0x40; /* LE Test End */
453
454+ /* Extra LE commands for >= 4.1 adapters */
455+ btdev->commands[33] |= 0x10; /* LE Remote Conn Param Req Reply */
456+ btdev->commands[33] |= 0x20; /* LE Remote Conn Param Req Neg Reply */
457+
458 /* Extra LE commands for >= 4.2 adapters */
459 btdev->commands[34] |= 0x02; /* LE Read Local P-256 Public Key */
460 btdev->commands[34] |= 0x04; /* LE Generate DHKey */
461@@ -562,6 +566,8 @@
462 btdev->max_page = 1;
463
464 btdev->le_features[0] |= 0x01; /* LE Encryption */
465+ btdev->le_features[0] |= 0x02; /* Connection Parameters Request */
466+ btdev->le_features[0] |= 0x08; /* Slave-initiated Features Exchange */
467 }
468
469 static void set_amp_features(struct btdev *btdev)
470@@ -1095,8 +1101,8 @@
471 }
472
473 static void le_conn_complete(struct btdev *btdev,
474- const uint8_t *bdaddr, uint8_t bdaddr_type,
475- uint8_t status)
476+ const struct bt_hci_cmd_le_create_conn *lecc,
477+ uint8_t status)
478 {
479 char buf[1 + sizeof(struct bt_hci_evt_le_conn_complete)];
480 struct bt_hci_evt_le_conn_complete *cc = (void *) &buf[1];
481@@ -1106,8 +1112,10 @@
482 buf[0] = BT_HCI_EVT_LE_CONN_COMPLETE;
483
484 if (!status) {
485- struct btdev *remote = find_btdev_by_bdaddr_type(bdaddr,
486- bdaddr_type);
487+ struct btdev *remote;
488+
489+ remote = find_btdev_by_bdaddr_type(lecc->peer_addr,
490+ lecc->peer_addr_type);
491
492 btdev->conn = remote;
493 btdev->le_adv_enable = 0;
494@@ -1123,15 +1131,16 @@
495
496 cc->role = 0x01;
497 cc->handle = cpu_to_le16(42);
498+ cc->interval = lecc->max_interval;
499+ cc->latency = lecc->latency;
500+ cc->supv_timeout = lecc->supv_timeout;
501
502 send_event(remote, BT_HCI_EVT_LE_META_EVENT, buf, sizeof(buf));
503-
504- cc->handle = cpu_to_le16(42);
505 }
506
507 cc->status = status;
508- cc->peer_addr_type = bdaddr_type;
509- memcpy(cc->peer_addr, bdaddr, 6);
510+ cc->peer_addr_type = lecc->peer_addr_type;
511+ memcpy(cc->peer_addr, lecc->peer_addr, 6);
512 cc->role = 0x00;
513
514 send_event(btdev, BT_HCI_EVT_LE_META_EVENT, buf, sizeof(buf));
515@@ -1173,16 +1182,17 @@
516 return btdev->le_adv_type != 0x03;
517 }
518
519-static void le_conn_request(struct btdev *btdev, const uint8_t *bdaddr,
520- uint8_t bdaddr_type)
521+static void le_conn_request(struct btdev *btdev,
522+ const struct bt_hci_cmd_le_create_conn *lecc)
523 {
524- struct btdev *remote = find_btdev_by_bdaddr_type(bdaddr, bdaddr_type);
525+ struct btdev *remote = find_btdev_by_bdaddr_type(lecc->peer_addr,
526+ lecc->peer_addr_type);
527
528 if (remote && adv_connectable(remote) && adv_match(btdev, remote) &&
529- remote->le_adv_own_addr == bdaddr_type)
530- le_conn_complete(btdev, bdaddr, bdaddr_type, 0);
531+ remote->le_adv_own_addr == lecc->peer_addr_type)
532+ le_conn_complete(btdev, lecc, 0);
533 else
534- le_conn_complete(btdev, bdaddr, bdaddr_type,
535+ le_conn_complete(btdev, lecc,
536 BT_HCI_ERR_CONN_FAILED_TO_ESTABLISH);
537 }
538
539@@ -1203,6 +1213,25 @@
540 }
541 }
542
543+static void rej_le_conn_update(struct btdev *btdev, uint16_t handle,
544+ uint8_t reason)
545+{
546+ struct btdev *remote = btdev->conn;
547+ struct __packed {
548+ uint8_t subevent;
549+ struct bt_hci_evt_le_conn_update_complete ev;
550+ } ev;
551+
552+ if (!remote)
553+ return;
554+
555+ ev.subevent = BT_HCI_EVT_LE_CONN_UPDATE_COMPLETE;
556+ ev.ev.handle = cpu_to_le16(handle);
557+ ev.ev.status = cpu_to_le16(reason);
558+
559+ send_event(remote, BT_HCI_EVT_LE_META_EVENT, &ev, sizeof(ev));
560+}
561+
562 static void le_conn_update(struct btdev *btdev, uint16_t handle,
563 uint16_t min_interval, uint16_t max_interval,
564 uint16_t latency, uint16_t supv_timeout,
565@@ -1231,6 +1260,30 @@
566 send_event(remote, BT_HCI_EVT_LE_META_EVENT, &ev, sizeof(ev));
567 }
568
569+static void le_conn_param_req(struct btdev *btdev, uint16_t handle,
570+ uint16_t min_interval, uint16_t max_interval,
571+ uint16_t latency, uint16_t supv_timeout,
572+ uint16_t min_length, uint16_t max_length)
573+{
574+ struct btdev *remote = btdev->conn;
575+ struct __packed {
576+ uint8_t subevent;
577+ struct bt_hci_evt_le_conn_param_request ev;
578+ } ev;
579+
580+ if (!remote)
581+ return;
582+
583+ ev.subevent = BT_HCI_EVT_LE_CONN_PARAM_REQUEST;
584+ ev.ev.handle = cpu_to_le16(handle);
585+ ev.ev.min_interval = cpu_to_le16(min_interval);
586+ ev.ev.max_interval = cpu_to_le16(max_interval);
587+ ev.ev.latency = cpu_to_le16(latency);
588+ ev.ev.supv_timeout = cpu_to_le16(supv_timeout);
589+
590+ send_event(remote, BT_HCI_EVT_LE_META_EVENT, &ev, sizeof(ev));
591+}
592+
593 static void disconnect_complete(struct btdev *btdev, uint16_t handle,
594 uint8_t reason)
595 {
596@@ -2000,6 +2053,8 @@
597 const struct bt_hci_cmd_le_ltk_req_reply *llrr;
598 const struct bt_hci_cmd_le_encrypt *lenc_cmd;
599 const struct bt_hci_cmd_le_generate_dhkey *dh;
600+ const struct bt_hci_cmd_le_conn_param_req_reply *lcprr_cmd;
601+ const struct bt_hci_cmd_le_conn_param_req_neg_reply *lcprnr_cmd;
602 const struct bt_hci_cmd_read_local_amp_assoc *rlaa_cmd;
603 const struct bt_hci_cmd_read_rssi *rrssi;
604 const struct bt_hci_cmd_read_tx_power *rtxp;
605@@ -2041,6 +2096,8 @@
606 struct bt_hci_rsp_read_local_amp_info rlai;
607 struct bt_hci_rsp_read_local_amp_assoc rlaa_rsp;
608 struct bt_hci_rsp_get_mws_transport_config *gmtc;
609+ struct bt_hci_rsp_le_conn_param_req_reply lcprr_rsp;
610+ struct bt_hci_rsp_le_conn_param_req_neg_reply lcprnr_rsp;
611 struct bt_hci_rsp_le_read_buffer_size lrbs;
612 struct bt_hci_rsp_le_read_local_features lrlf;
613 struct bt_hci_rsp_le_read_adv_tx_power lratp;
614@@ -2948,8 +3005,6 @@
615 status = BT_HCI_ERR_SUCCESS;
616 }
617 cmd_complete(btdev, opcode, &status, sizeof(status));
618- if (status == BT_HCI_ERR_SUCCESS && btdev->le_scan_enable)
619- le_set_scan_enable_complete(btdev);
620 break;
621
622 case BT_HCI_CMD_LE_CREATE_CONN:
623@@ -3145,6 +3200,22 @@
624 cmd_complete(btdev, opcode, &lte, sizeof(lte));
625 break;
626
627+ case BT_HCI_CMD_LE_CONN_PARAM_REQ_REPLY:
628+ if (btdev->type == BTDEV_TYPE_BREDR)
629+ goto unsupported;
630+ lcprr_cmd = data;
631+ lcprr_rsp.handle = lcprr_cmd->handle;
632+ lcprr_rsp.status = BT_HCI_ERR_SUCCESS;
633+ cmd_complete(btdev, opcode, &lcprr_rsp, sizeof(lcprr_rsp));
634+ break;
635+ case BT_HCI_CMD_LE_CONN_PARAM_REQ_NEG_REPLY:
636+ if (btdev->type == BTDEV_TYPE_BREDR)
637+ goto unsupported;
638+ lcprnr_cmd = data;
639+ lcprnr_rsp.handle = lcprnr_cmd->handle;
640+ lcprnr_rsp.status = BT_HCI_ERR_SUCCESS;
641+ cmd_complete(btdev, opcode, &lcprnr_rsp, sizeof(lcprnr_rsp));
642+ break;
643 default:
644 goto unsupported;
645 }
646@@ -3179,6 +3250,9 @@
647 const struct bt_hci_cmd_read_clock_offset *rco;
648 const struct bt_hci_cmd_le_create_conn *lecc;
649 const struct bt_hci_cmd_le_conn_update *lecu;
650+ const struct bt_hci_cmd_le_conn_param_req_reply *lcprr;
651+ const struct bt_hci_cmd_le_conn_param_req_neg_reply *lcprnr;
652+ const struct bt_hci_cmd_le_set_scan_enable *lsse;
653
654 switch (opcode) {
655 case BT_HCI_CMD_INQUIRY:
656@@ -3323,21 +3397,57 @@
657 return;
658 lecc = data;
659 btdev->le_scan_own_addr_type = lecc->own_addr_type;
660- le_conn_request(btdev, lecc->peer_addr, lecc->peer_addr_type);
661+ le_conn_request(btdev, lecc);
662 break;
663
664 case BT_HCI_CMD_LE_CONN_UPDATE:
665 if (btdev->type == BTDEV_TYPE_BREDR)
666 return;
667 lecu = data;
668- le_conn_update(btdev, le16_to_cpu(lecu->handle),
669- le16_to_cpu(lecu->min_interval),
670- le16_to_cpu(lecu->max_interval),
671- le16_to_cpu(lecu->latency),
672- le16_to_cpu(lecu->supv_timeout),
673- le16_to_cpu(lecu->min_length),
674- le16_to_cpu(lecu->max_length));
675- break;
676+ if (btdev->le_features[0] & 0x02)
677+ le_conn_param_req(btdev, le16_to_cpu(lecu->handle),
678+ le16_to_cpu(lecu->min_interval),
679+ le16_to_cpu(lecu->max_interval),
680+ le16_to_cpu(lecu->latency),
681+ le16_to_cpu(lecu->supv_timeout),
682+ le16_to_cpu(lecu->min_length),
683+ le16_to_cpu(lecu->max_length));
684+ else
685+ le_conn_update(btdev, le16_to_cpu(lecu->handle),
686+ le16_to_cpu(lecu->min_interval),
687+ le16_to_cpu(lecu->max_interval),
688+ le16_to_cpu(lecu->latency),
689+ le16_to_cpu(lecu->supv_timeout),
690+ le16_to_cpu(lecu->min_length),
691+ le16_to_cpu(lecu->max_length));
692+ break;
693+ case BT_HCI_CMD_LE_CONN_PARAM_REQ_REPLY:
694+ if (btdev->type == BTDEV_TYPE_BREDR)
695+ return;
696+ lcprr = data;
697+ le_conn_update(btdev, le16_to_cpu(lcprr->handle),
698+ le16_to_cpu(lcprr->min_interval),
699+ le16_to_cpu(lcprr->max_interval),
700+ le16_to_cpu(lcprr->latency),
701+ le16_to_cpu(lcprr->supv_timeout),
702+ le16_to_cpu(lcprr->min_length),
703+ le16_to_cpu(lcprr->max_length));
704+ break;
705+ case BT_HCI_CMD_LE_CONN_PARAM_REQ_NEG_REPLY:
706+ if (btdev->type == BTDEV_TYPE_BREDR)
707+ return;
708+ lcprnr = data;
709+ rej_le_conn_update(btdev, le16_to_cpu(lcprnr->handle),
710+ le16_to_cpu(lcprnr->reason));
711+ break;
712+ break;
713+ case BT_HCI_CMD_LE_SET_SCAN_ENABLE:
714+ if (btdev->type == BTDEV_TYPE_BREDR)
715+ return;
716+ lsse = data;
717+ if (btdev->le_scan_enable && lsse->enable)
718+ le_set_scan_enable_complete(btdev);
719+
720 }
721 }
722
723
724=== modified file 'lib/bluetooth.c'
725--- lib/bluetooth.c 2015-10-06 11:46:27 +0000
726+++ lib/bluetooth.c 2015-11-23 18:34:05 +0000
727@@ -1579,6 +1579,62 @@
728 return "CliniCloud Inc";
729 case 658:
730 return "SwiftSensors";
731+ case 659:
732+ return "Blue Bite";
733+ case 660:
734+ return "ELIAS GmbH";
735+ case 661:
736+ return "Sivantos GmbH";
737+ case 662:
738+ return "Petzl";
739+ case 663:
740+ return "storm power ltd";
741+ case 664:
742+ return "EISST Ltd";
743+ case 665:
744+ return "Inexess Technology Simma KG";
745+ case 666:
746+ return "Currant, Inc.";
747+ case 667:
748+ return "C2 Development, Inc.";
749+ case 668:
750+ return "Blue Sky Scientific, LLC";
751+ case 669:
752+ return "ALOTTAZS LABS, LLC";
753+ case 670:
754+ return "Kupson spol. s r.o.";
755+ case 671:
756+ return "Areus Engineering GmbH";
757+ case 672:
758+ return "Impossible Camera GmbH";
759+ case 673:
760+ return "InventureTrack Systems";
761+ case 674:
762+ return "LockedUp";
763+ case 675:
764+ return "Itude";
765+ case 676:
766+ return "Pacific Lock Company";
767+ case 677:
768+ return "Tendyron Corporation ( 天地融科技股份有限公司 )";
769+ case 678:
770+ return "Robert Bosch GmbH";
771+ case 679:
772+ return "Illuxtron international B.V.";
773+ case 680:
774+ return "miSport Ltd.";
775+ case 681:
776+ return "Chargelib";
777+ case 682:
778+ return "Doppler Lab";
779+ case 683:
780+ return "BBPOS Limited";
781+ case 684:
782+ return "RTB Elektronik GmbH & Co. KG";
783+ case 685:
784+ return "Rx Networks, Inc.";
785+ case 686:
786+ return "WeatherFlow, Inc.";
787 case 65535:
788 return "internal use";
789 default:
790
791=== modified file 'monitor/analyze.c'
792--- monitor/analyze.c 2015-09-15 13:42:52 +0000
793+++ monitor/analyze.c 2015-11-23 18:34:05 +0000
794@@ -309,6 +309,9 @@
795 case BTSNOOP_OPCODE_SCO_RX_PKT:
796 sco_pkt(&tv, index, buf, pktlen);
797 break;
798+ case BTSNOOP_OPCODE_OPEN_INDEX:
799+ case BTSNOOP_OPCODE_CLOSE_INDEX:
800+ break;
801 default:
802 fprintf(stderr, "Wrong opcode %u\n", opcode);
803 goto done;
804
805=== modified file 'monitor/avctp.c'
806--- monitor/avctp.c 2015-09-15 13:42:52 +0000
807+++ monitor/avctp.c 2015-11-23 18:34:05 +0000
808@@ -1813,6 +1813,45 @@
809 return true;
810 }
811
812+
813+static struct {
814+ const char *str;
815+ bool reserved;
816+} features_table[] = {
817+ /* Ignore passthrough bits */
818+ [58] = { "Advanced Control Player" },
819+ [59] = { "Browsing" },
820+ [60] = { "Searching" },
821+ [61] = { "AddToNowPlaying" },
822+ [62] = { "Unique UIDs" },
823+ [63] = { "OnlyBrowsableWhenAddressed" },
824+ [64] = { "OnlySearchableWhenAddressed" },
825+ [65] = { "NowPlaying" },
826+ [66] = { "UIDPersistency" },
827+ /* 67-127 reserved */
828+ [67 ... 127] = { .reserved = true },
829+};
830+
831+static void print_features(uint8_t features[16], uint8_t indent)
832+{
833+ int i;
834+
835+ for (i = 0; i < 127; i++) {
836+ if (!(features[i / 8] & (1 << (i % 8))))
837+ continue;
838+
839+ if (features_table[i].reserved) {
840+ print_text(COLOR_WHITE_BG, "Unknown bit %u", i);
841+ continue;
842+ }
843+
844+ if (!features_table[i].str)
845+ continue;
846+
847+ print_field("%*c%s", indent, ' ', features_table[i].str);
848+ }
849+}
850+
851 static bool avrcp_media_player_item(struct avctp_frame *avctp_frame,
852 uint8_t indent)
853 {
854@@ -1856,6 +1895,8 @@
855
856 printf("\n");
857
858+ print_features(features, indent + 2);
859+
860 if (!l2cap_frame_get_be16(frame, &charset))
861 return false;
862
863
864=== added file 'monitor/broadcom.c'
865--- monitor/broadcom.c 1970-01-01 00:00:00 +0000
866+++ monitor/broadcom.c 2015-11-23 18:34:05 +0000
867@@ -0,0 +1,251 @@
868+/*
869+ *
870+ * BlueZ - Bluetooth protocol stack for Linux
871+ *
872+ * Copyright (C) 2011-2014 Intel Corporation
873+ * Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
874+ *
875+ *
876+ * This library is free software; you can redistribute it and/or
877+ * modify it under the terms of the GNU Lesser General Public
878+ * License as published by the Free Software Foundation; either
879+ * version 2.1 of the License, or (at your option) any later version.
880+ *
881+ * This library is distributed in the hope that it will be useful,
882+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
883+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
884+ * Lesser General Public License for more details.
885+ *
886+ * You should have received a copy of the GNU Lesser General Public
887+ * License along with this library; if not, write to the Free Software
888+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
889+ *
890+ */
891+
892+#ifdef HAVE_CONFIG_H
893+#include <config.h>
894+#endif
895+
896+#include <stdio.h>
897+
898+#include "src/shared/util.h"
899+#include "display.h"
900+#include "packet.h"
901+#include "lmp.h"
902+#include "ll.h"
903+#include "vendor.h"
904+#include "broadcom.h"
905+
906+static void print_status(uint8_t status)
907+{
908+ packet_print_error("Status", status);
909+}
910+
911+static void null_cmd(const void *data, uint8_t size)
912+{
913+}
914+
915+static void status_rsp(const void *data, uint8_t size)
916+{
917+ uint8_t status = get_u8(data);
918+
919+ print_status(status);
920+}
921+
922+static void write_bd_addr_cmd(const void *data, uint8_t size)
923+{
924+ packet_print_addr("Address", data, false);
925+}
926+
927+static void enable_usb_hid_emulation_cmd(const void *data, uint8_t size)
928+{
929+ uint8_t enable = get_u8(data);
930+ const char *str;
931+
932+ switch (enable) {
933+ case 0x00:
934+ str = "Bluetooth mode";
935+ break;
936+ case 0x01:
937+ str = "HID Mode";
938+ break;
939+ default:
940+ str = "Reserved";
941+ break;
942+ }
943+
944+ print_field("Enable: %s (0x%2.2x)", str, enable);
945+}
946+
947+static void write_ram_cmd(const void *data, uint8_t size)
948+{
949+ uint32_t addr = get_le32(data);
950+
951+ print_field("Address: 0x%8.8x", addr);
952+
953+ packet_hexdump(data + 4, size - 4);
954+}
955+
956+static void launch_ram_cmd(const void *data, uint8_t size)
957+{
958+ uint32_t addr = get_le32(data);
959+
960+ print_field("Address: 0x%8.8x", addr);
961+}
962+
963+static void read_vid_pid_rsp(const void *data, uint8_t size)
964+{
965+ uint8_t status = get_u8(data);
966+ uint16_t vid = get_le16(data + 1);
967+ uint16_t pid = get_le16(data + 3);
968+
969+ print_status(status);
970+ print_field("Product: %4.4x:%4.4x", vid, pid);
971+}
972+
973+static void read_verbose_version_info_rsp(const void *data, uint8_t size)
974+{
975+ uint8_t status = get_u8(data);
976+ uint8_t chip_id = get_u8(data + 1);
977+ uint8_t target_id = get_u8(data + 2);
978+ uint16_t build_base = get_le16(data + 3);
979+ uint16_t build_num = get_le16(data + 5);
980+ const char *str;
981+
982+ print_status(status);
983+ print_field("Chip ID: %u (0x%2.2x)", chip_id, chip_id);
984+
985+ switch (target_id) {
986+ case 254:
987+ str = "Invalid";
988+ break;
989+ case 255:
990+ str = "Undefined";
991+ break;
992+ default:
993+ str = "Reserved";
994+ break;
995+ }
996+
997+ print_field("Build target: %s (%u)", str, target_id);
998+ print_field("Build baseline: %u (0x%4.4x)", build_base, build_base);
999+ print_field("Build number: %u (0x%4.4x)", build_num, build_num);
1000+}
1001+
1002+static const struct vendor_ocf vendor_ocf_table[] = {
1003+ { 0x001, "Write BD ADDR",
1004+ write_bd_addr_cmd, 6, true,
1005+ status_rsp, 1, true },
1006+ { 0x018, "Update UART Baud Rate" },
1007+ { 0x027, "Set Sleepmode Param" },
1008+ { 0x02e, "Download Minidriver",
1009+ null_cmd, 0, true,
1010+ status_rsp, 1, true },
1011+ { 0x03b, "Enable USB HID Emulation",
1012+ enable_usb_hid_emulation_cmd, 1, true,
1013+ status_rsp, 1, true },
1014+ { 0x045, "Write UART Clock Setting" },
1015+ { 0x04c, "Write RAM",
1016+ write_ram_cmd, 4, false,
1017+ status_rsp, 1, true },
1018+ { 0x04e, "Launch RAM",
1019+ launch_ram_cmd, 4, true,
1020+ status_rsp, 1, true },
1021+ { 0x05a, "Read VID PID",
1022+ null_cmd, 0, true,
1023+ read_vid_pid_rsp, 5, true },
1024+ { 0x079, "Read Verbose Config Version Info",
1025+ null_cmd, 0, true,
1026+ read_verbose_version_info_rsp, 7, true },
1027+ { }
1028+};
1029+
1030+const struct vendor_ocf *broadcom_vendor_ocf(uint16_t ocf)
1031+{
1032+ int i;
1033+
1034+ for (i = 0; vendor_ocf_table[i].str; i++) {
1035+ if (vendor_ocf_table[i].ocf == ocf)
1036+ return &vendor_ocf_table[i];
1037+ }
1038+
1039+ return NULL;
1040+}
1041+
1042+void broadcom_lm_diag(const void *data, uint8_t size)
1043+{
1044+ uint8_t type;
1045+ uint32_t clock;
1046+ const uint8_t *addr;
1047+ const char *str;
1048+
1049+ if (size != 63) {
1050+ packet_hexdump(data, size);
1051+ return;
1052+ }
1053+
1054+ type = *((uint8_t *) data);
1055+ clock = get_be32(data + 1);
1056+
1057+ switch (type) {
1058+ case 0x00:
1059+ str = "LMP sent";
1060+ break;
1061+ case 0x01:
1062+ str = "LMP receive";
1063+ break;
1064+ case 0x80:
1065+ str = "LL sent";
1066+ break;
1067+ case 0x81:
1068+ str = "LL receive";
1069+ break;
1070+ default:
1071+ str = "Unknown";
1072+ break;
1073+ }
1074+
1075+ print_field("Type: %s (%u)", str, type);
1076+ print_field("Clock: 0x%8.8x", clock);
1077+
1078+ switch (type) {
1079+ case 0x00:
1080+ addr = data + 5;
1081+ print_field("Address: --:--:%2.2X:%2.2X:%2.2X:%2.2X",
1082+ addr[0], addr[1], addr[2], addr[3]);
1083+ packet_hexdump(data + 9, 1);
1084+ lmp_packet(data + 10, size - 10, true);
1085+ break;
1086+ case 0x01:
1087+ addr = data + 5;
1088+ print_field("Address: --:--:%2.2X:%2.2X:%2.2X:%2.2X",
1089+ addr[0], addr[1], addr[2], addr[3]);
1090+ packet_hexdump(data + 9, 4);
1091+ lmp_packet(data + 13, size - 13, true);
1092+ break;
1093+ case 0x80:
1094+ case 0x81:
1095+ packet_hexdump(data + 5, 7);
1096+ llcp_packet(data + 12, size - 12, true);
1097+ break;
1098+ default:
1099+ packet_hexdump(data + 9, size - 9);
1100+ break;
1101+ }
1102+}
1103+
1104+static const struct vendor_evt vendor_evt_table[] = {
1105+ { }
1106+};
1107+
1108+const struct vendor_evt *broadcom_vendor_evt(uint8_t evt)
1109+{
1110+ int i;
1111+
1112+ for (i = 0; vendor_evt_table[i].str; i++) {
1113+ if (vendor_evt_table[i].evt == evt)
1114+ return &vendor_evt_table[i];
1115+ }
1116+
1117+ return NULL;
1118+}
1119
1120=== added file 'monitor/broadcom.h'
1121--- monitor/broadcom.h 1970-01-01 00:00:00 +0000
1122+++ monitor/broadcom.h 2015-11-23 18:34:05 +0000
1123@@ -0,0 +1,32 @@
1124+/*
1125+ *
1126+ * BlueZ - Bluetooth protocol stack for Linux
1127+ *
1128+ * Copyright (C) 2011-2014 Intel Corporation
1129+ * Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
1130+ *
1131+ *
1132+ * This library is free software; you can redistribute it and/or
1133+ * modify it under the terms of the GNU Lesser General Public
1134+ * License as published by the Free Software Foundation; either
1135+ * version 2.1 of the License, or (at your option) any later version.
1136+ *
1137+ * This library is distributed in the hope that it will be useful,
1138+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1139+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1140+ * Lesser General Public License for more details.
1141+ *
1142+ * You should have received a copy of the GNU Lesser General Public
1143+ * License along with this library; if not, write to the Free Software
1144+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1145+ *
1146+ */
1147+
1148+#include <stdint.h>
1149+
1150+struct vendor_ocf;
1151+struct vendor_evt;
1152+
1153+const struct vendor_ocf *broadcom_vendor_ocf(uint16_t ocf);
1154+const struct vendor_evt *broadcom_vendor_evt(uint8_t evt);
1155+void broadcom_lm_diag(const void *data, uint8_t size);
1156
1157=== modified file 'monitor/bt.h'
1158--- monitor/bt.h 2015-09-15 13:42:52 +0000
1159+++ monitor/bt.h 2015-11-23 18:34:05 +0000
1160@@ -99,8 +99,43 @@
1161 uint8_t error;
1162 } __attribute__ ((packed));
1163
1164+#define BT_LL_SLAVE_FEATURE_REQ 0x0e
1165+struct bt_ll_slave_feature_req {
1166+ uint8_t features[8];
1167+} __attribute__ ((packed));
1168+
1169+#define BT_LL_CONN_PARAM_REQ 0x0f
1170+
1171+#define BT_LL_CONN_PARAM_RSP 0x10
1172+
1173+#define BT_LL_REJECT_IND_EXT 0x11
1174+struct bt_ll_reject_ind_ext {
1175+ uint8_t opcode;
1176+ uint8_t error;
1177+} __attribute__ ((packed));
1178+
1179+#define BT_LL_PING_REQ 0x12
1180+
1181+#define BT_LL_PING_RSP 0x13
1182+
1183+#define BT_LL_LENGTH_REQ 0x14
1184+
1185+#define BT_LL_LENGTH_RSP 0x15
1186+
1187 #define LMP_ESC4(x) ((127 << 8) | (x))
1188
1189+#define BT_LMP_NAME_REQ 1
1190+struct bt_lmp_name_req {
1191+ uint8_t offset;
1192+} __attribute__ ((packed));
1193+
1194+#define BT_LMP_NAME_RSP 2
1195+struct bt_lmp_name_rsp {
1196+ uint8_t offset;
1197+ uint8_t length;
1198+ uint8_t fragment[14];
1199+} __attribute__ ((packed));
1200+
1201 #define BT_LMP_ACCEPTED 3
1202 struct bt_lmp_accepted {
1203 uint8_t opcode;
1204@@ -114,6 +149,11 @@
1205
1206 #define BT_LMP_CLKOFFSET_REQ 5
1207
1208+#define BT_LMP_CLKOFFSET_RSP 6
1209+struct bt_lmp_clkoffset_rsp {
1210+ uint16_t offset;
1211+} __attribute__ ((packed));
1212+
1213 #define BT_LMP_DETACH 7
1214 struct bt_lmp_detach {
1215 uint8_t error;
1216@@ -146,6 +186,11 @@
1217
1218 #define BT_LMP_STOP_ENCRYPTION_REQ 18
1219
1220+#define BT_LMP_SWITCH_REQ 19
1221+struct bt_lmp_switch_req {
1222+ uint32_t instant;
1223+} __attribute__ ((packed));
1224+
1225 #define BT_LMP_UNSNIFF_REQ 24
1226
1227 #define BT_LMP_MAX_POWER 33
1228@@ -154,6 +199,11 @@
1229
1230 #define BT_LMP_AUTO_RATE 35
1231
1232+#define BT_LMP_PREFERRED_RATE 36
1233+struct bt_lmp_preferred_rate {
1234+ uint8_t rate;
1235+} __attribute__ ((packed));
1236+
1237 #define BT_LMP_VERSION_REQ 37
1238 struct bt_lmp_version_req {
1239 uint8_t version;
1240@@ -202,6 +252,12 @@
1241
1242 #define BT_LMP_HOST_CONNECTION_REQ 51
1243
1244+#define BT_LMP_SLOT_OFFSET 52
1245+struct bt_lmp_slot_offset {
1246+ uint16_t offset;
1247+ uint8_t bdaddr[6];
1248+} __attribute__ ((packed));
1249+
1250 #define BT_LMP_PAGE_SCAN_MODE_REQ 54
1251 struct bt_lmp_page_scan_mode_req {
1252 uint8_t scheme;
1253
1254=== modified file 'monitor/control.c'
1255--- monitor/control.c 2015-09-15 13:42:52 +0000
1256+++ monitor/control.c 2015-11-23 18:34:05 +0000
1257@@ -902,7 +902,7 @@
1258 static void data_callback(int fd, uint32_t events, void *user_data)
1259 {
1260 struct control_data *data = user_data;
1261- unsigned char control[32];
1262+ unsigned char control[64];
1263 struct mgmt_hdr hdr;
1264 struct msghdr msg;
1265 struct iovec iov[2];
1266@@ -927,6 +927,8 @@
1267 struct cmsghdr *cmsg;
1268 struct timeval *tv = NULL;
1269 struct timeval ctv;
1270+ struct ucred *cred = NULL;
1271+ struct ucred ccred;
1272 uint16_t opcode, index, pktlen;
1273 ssize_t len;
1274
1275@@ -946,6 +948,11 @@
1276 memcpy(&ctv, CMSG_DATA(cmsg), sizeof(ctv));
1277 tv = &ctv;
1278 }
1279+
1280+ if (cmsg->cmsg_type == SCM_CREDENTIALS) {
1281+ memcpy(&ccred, CMSG_DATA(cmsg), sizeof(ccred));
1282+ cred = &ccred;
1283+ }
1284 }
1285
1286 opcode = le16_to_cpu(hdr.opcode);
1287@@ -954,14 +961,16 @@
1288
1289 switch (data->channel) {
1290 case HCI_CHANNEL_CONTROL:
1291- packet_control(tv, index, opcode, data->buf, pktlen);
1292+ packet_control(tv, cred, index, opcode,
1293+ data->buf, pktlen);
1294 break;
1295 case HCI_CHANNEL_MONITOR:
1296 btsnoop_write_hci(btsnoop_file, tv, index, opcode,
1297 data->buf, pktlen);
1298 ellisys_inject_hci(tv, index, opcode,
1299 data->buf, pktlen);
1300- packet_monitor(tv, index, opcode, data->buf, pktlen);
1301+ packet_monitor(tv, cred, index, opcode,
1302+ data->buf, pktlen);
1303 break;
1304 }
1305 }
1306@@ -1001,6 +1010,12 @@
1307 return -1;
1308 }
1309
1310+ if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &opt, sizeof(opt)) < 0) {
1311+ perror("Failed to enable credentials");
1312+ close(fd);
1313+ return -1;
1314+ }
1315+
1316 return fd;
1317 }
1318
1319@@ -1051,7 +1066,7 @@
1320 uint16_t opcode = le16_to_cpu(hdr->opcode);
1321 uint16_t index = le16_to_cpu(hdr->index);
1322
1323- packet_monitor(NULL, index, opcode,
1324+ packet_monitor(NULL, NULL, index, opcode,
1325 data->buf + MGMT_HDR_SIZE, pktlen);
1326
1327 data->offset -= pktlen + MGMT_HDR_SIZE;
1328@@ -1190,7 +1205,7 @@
1329 if (opcode == 0xffff)
1330 continue;
1331
1332- packet_monitor(&tv, index, opcode, buf, pktlen);
1333+ packet_monitor(&tv, NULL, index, opcode, buf, pktlen);
1334 ellisys_inject_hci(&tv, index, opcode, buf, pktlen);
1335 }
1336 break;
1337
1338=== modified file 'monitor/display.h'
1339--- monitor/display.h 2015-09-15 13:42:52 +0000
1340+++ monitor/display.h 2015-11-23 18:34:05 +0000
1341@@ -38,6 +38,7 @@
1342 #define COLOR_WHITE_BG "\x1B[0;47;30m"
1343 #define COLOR_HIGHLIGHT "\x1B[1;39m"
1344
1345+#define COLOR_WARN "\x1B[1;30m"
1346 #define COLOR_ERROR "\x1B[1;31m"
1347
1348 #define FALLBACK_TERMINAL_WIDTH 80
1349
1350=== modified file 'monitor/hcidump.c'
1351--- monitor/hcidump.c 2015-09-15 13:42:52 +0000
1352+++ monitor/hcidump.c 2015-11-23 18:34:05 +0000
1353@@ -160,17 +160,19 @@
1354
1355 switch (buf[0]) {
1356 case HCI_COMMAND_PKT:
1357- packet_hci_command(tv, data->index, buf + 1, len - 1);
1358+ packet_hci_command(tv, NULL, data->index,
1359+ buf + 1, len - 1);
1360 break;
1361 case HCI_EVENT_PKT:
1362- packet_hci_event(tv, data->index, buf + 1, len - 1);
1363+ packet_hci_event(tv, NULL, data->index,
1364+ buf + 1, len - 1);
1365 break;
1366 case HCI_ACLDATA_PKT:
1367- packet_hci_acldata(tv, data->index, !!dir,
1368+ packet_hci_acldata(tv, NULL, data->index, !!dir,
1369 buf + 1, len - 1);
1370 break;
1371 case HCI_SCODATA_PKT:
1372- packet_hci_scodata(tv, data->index, !!dir,
1373+ packet_hci_scodata(tv, NULL, data->index, !!dir,
1374 buf + 1, len - 1);
1375 break;
1376 }
1377
1378=== added file 'monitor/intel.c'
1379--- monitor/intel.c 1970-01-01 00:00:00 +0000
1380+++ monitor/intel.c 2015-11-23 18:34:05 +0000
1381@@ -0,0 +1,926 @@
1382+/*
1383+ *
1384+ * BlueZ - Bluetooth protocol stack for Linux
1385+ *
1386+ * Copyright (C) 2011-2014 Intel Corporation
1387+ * Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
1388+ *
1389+ *
1390+ * This library is free software; you can redistribute it and/or
1391+ * modify it under the terms of the GNU Lesser General Public
1392+ * License as published by the Free Software Foundation; either
1393+ * version 2.1 of the License, or (at your option) any later version.
1394+ *
1395+ * This library is distributed in the hope that it will be useful,
1396+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1397+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1398+ * Lesser General Public License for more details.
1399+ *
1400+ * You should have received a copy of the GNU Lesser General Public
1401+ * License along with this library; if not, write to the Free Software
1402+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
1403+ *
1404+ */
1405+
1406+#ifdef HAVE_CONFIG_H
1407+#include <config.h>
1408+#endif
1409+
1410+#include <stdio.h>
1411+#include <inttypes.h>
1412+
1413+#include "lib/bluetooth.h"
1414+#include "lib/hci.h"
1415+
1416+#include "src/shared/util.h"
1417+#include "display.h"
1418+#include "packet.h"
1419+#include "lmp.h"
1420+#include "ll.h"
1421+#include "vendor.h"
1422+#include "intel.h"
1423+
1424+#define COLOR_UNKNOWN_EVENT_MASK COLOR_WHITE_BG
1425+#define COLOR_UNKNOWN_SCAN_STATUS COLOR_WHITE_BG
1426+
1427+static void print_status(uint8_t status)
1428+{
1429+ packet_print_error("Status", status);
1430+}
1431+
1432+static void print_module(uint8_t module)
1433+{
1434+ const char *str;
1435+
1436+ switch (module) {
1437+ case 0x01:
1438+ str = "BC";
1439+ break;
1440+ case 0x02:
1441+ str = "HCI";
1442+ break;
1443+ case 0x03:
1444+ str = "LLC";
1445+ break;
1446+ case 0x04:
1447+ str = "OS";
1448+ break;
1449+ case 0x05:
1450+ str = "LM";
1451+ break;
1452+ case 0x06:
1453+ str = "SC";
1454+ break;
1455+ case 0x07:
1456+ str = "SP";
1457+ break;
1458+ case 0x08:
1459+ str = "OSAL";
1460+ break;
1461+ case 0x09:
1462+ str = "LC";
1463+ break;
1464+ case 0x0a:
1465+ str = "APP";
1466+ break;
1467+ case 0x0b:
1468+ str = "TLD";
1469+ break;
1470+ case 0xf0:
1471+ str = "Debug";
1472+ break;
1473+ default:
1474+ str = "Reserved";
1475+ break;
1476+ }
1477+
1478+ print_field("Module: %s (0x%2.2x)", str, module);
1479+}
1480+
1481+static void null_cmd(const void *data, uint8_t size)
1482+{
1483+}
1484+
1485+static void status_rsp(const void *data, uint8_t size)
1486+{
1487+ uint8_t status = get_u8(data);
1488+
1489+ print_status(status);
1490+}
1491+
1492+static void reset_cmd(const void *data, uint8_t size)
1493+{
1494+ uint8_t reset_type = get_u8(data);
1495+ uint8_t patch_enable = get_u8(data + 1);
1496+ uint8_t ddc_reload = get_u8(data + 2);
1497+ uint8_t boot_option = get_u8(data + 3);
1498+ uint32_t boot_addr = get_le32(data + 4);
1499+ const char *str;
1500+
1501+ switch (reset_type) {
1502+ case 0x00:
1503+ str = "Soft software reset";
1504+ break;
1505+ case 0x01:
1506+ str = "Hard software reset";
1507+ break;
1508+ default:
1509+ str = "Reserved";
1510+ break;
1511+ }
1512+
1513+ print_field("Reset type: %s (0x%2.2x)", str, reset_type);
1514+
1515+ switch (patch_enable) {
1516+ case 0x00:
1517+ str = "Do not enable";
1518+ break;
1519+ case 0x01:
1520+ str = "Enable";
1521+ break;
1522+ default:
1523+ str = "Reserved";
1524+ break;
1525+ }
1526+
1527+ print_field("Patch vectors: %s (0x%2.2x)", str, patch_enable);
1528+
1529+ switch (ddc_reload) {
1530+ case 0x00:
1531+ str = "Do not reload";
1532+ break;
1533+ case 0x01:
1534+ str = "Reload from OTP";
1535+ break;
1536+ default:
1537+ str = "Reserved";
1538+ break;
1539+ }
1540+
1541+ print_field("DDC parameters: %s (0x%2.2x)", str, ddc_reload);
1542+
1543+ switch (boot_option) {
1544+ case 0x00:
1545+ str = "Current image";
1546+ break;
1547+ case 0x01:
1548+ str = "Specified address";
1549+ break;
1550+ default:
1551+ str = "Reserved";
1552+ break;
1553+ }
1554+
1555+ print_field("Boot option: %s (0x%2.2x)", str, boot_option);
1556+ print_field("Boot address: 0x%8.8x", boot_addr);
1557+}
1558+
1559+static void read_version_rsp(const void *data, uint8_t size)
1560+{
1561+ uint8_t status = get_u8(data);
1562+ uint8_t hw_platform = get_u8(data + 1);
1563+ uint8_t hw_variant = get_u8(data + 2);
1564+ uint8_t hw_revision = get_u8(data + 3);
1565+ uint8_t fw_variant = get_u8(data + 4);
1566+ uint8_t fw_revision = get_u8(data + 5);
1567+ uint8_t fw_build_nn = get_u8(data + 6);
1568+ uint8_t fw_build_cw = get_u8(data + 7);
1569+ uint8_t fw_build_yy = get_u8(data + 8);
1570+ uint8_t fw_patch = get_u8(data + 9);
1571+
1572+ print_status(status);
1573+ print_field("Hardware platform: 0x%2.2x", hw_platform);
1574+ print_field("Hardware variant: 0x%2.2x", hw_variant);
1575+ print_field("Hardware revision: %u.%u", hw_revision >> 4,
1576+ hw_revision & 0x0f);
1577+ print_field("Firmware variant: 0x%2.2x", fw_variant);
1578+ print_field("Firmware revision: %u.%u", fw_revision >> 4,
1579+ fw_revision & 0x0f);
1580+
1581+ print_field("Firmware build: %u-%u.%u", fw_build_nn,
1582+ fw_build_cw, 2000 + fw_build_yy);
1583+ print_field("Firmware patch: %u", fw_patch);
1584+}
1585+
1586+static void secure_send_cmd(const void *data, uint8_t size)
1587+{
1588+ uint8_t type = get_u8(data);
1589+ const char *str;
1590+
1591+ switch (type) {
1592+ case 0x00:
1593+ str = "Init";
1594+ break;
1595+ case 0x01:
1596+ str = "Data";
1597+ break;
1598+ case 0x02:
1599+ str = "Sign";
1600+ break;
1601+ case 0x03:
1602+ str = "PKey";
1603+ break;
1604+ default:
1605+ str = "Reserved";
1606+ break;
1607+ }
1608+
1609+ print_field("Type: %s fragment (0x%2.2x)", str, type);
1610+
1611+ packet_hexdump(data + 1, size - 1);
1612+}
1613+
1614+static void manufacturer_mode_cmd(const void *data, uint8_t size)
1615+{
1616+ uint8_t mode = get_u8(data);
1617+ uint8_t reset = get_u8(data + 1);
1618+ const char *str;
1619+
1620+ switch (mode) {
1621+ case 0x00:
1622+ str = "Disabled";
1623+ break;
1624+ case 0x01:
1625+ str = "Enabled";
1626+ break;
1627+ default:
1628+ str = "Reserved";
1629+ break;
1630+ }
1631+
1632+ print_field("Mode switch: %s (0x%2.2x)", str, mode);
1633+
1634+ switch (reset) {
1635+ case 0x00:
1636+ str = "No reset";
1637+ break;
1638+ case 0x01:
1639+ str = "Reset and deactivate patches";
1640+ break;
1641+ case 0x02:
1642+ str = "Reset and activate patches";
1643+ break;
1644+ default:
1645+ str = "Reserved";
1646+ break;
1647+ }
1648+
1649+ print_field("Reset behavior: %s (0x%2.2x)", str, reset);
1650+}
1651+
1652+static void write_bd_data_cmd(const void *data, uint8_t size)
1653+{
1654+ uint8_t features[8];
1655+
1656+ packet_print_addr("Address", data, false);
1657+ packet_hexdump(data + 6, 6);
1658+
1659+ memcpy(features, data + 12, 8);
1660+ packet_print_features_lmp(features, 0);
1661+
1662+ memcpy(features, data + 20, 1);
1663+ memset(features + 1, 0, 7);
1664+ packet_print_features_ll(features);
1665+
1666+ packet_hexdump(data + 21, size - 21);
1667+}
1668+
1669+static void read_bd_data_rsp(const void *data, uint8_t size)
1670+{
1671+ uint8_t status = get_u8(data);
1672+
1673+ print_status(status);
1674+ packet_print_addr("Address", data + 1, false);
1675+ packet_hexdump(data + 7, size - 7);
1676+}
1677+
1678+static void write_bd_address_cmd(const void *data, uint8_t size)
1679+{
1680+ packet_print_addr("Address", data, false);
1681+}
1682+
1683+static void act_deact_traces_cmd(const void *data, uint8_t size)
1684+{
1685+ uint8_t tx = get_u8(data);
1686+ uint8_t tx_arq = get_u8(data + 1);
1687+ uint8_t rx = get_u8(data + 2);
1688+
1689+ print_field("Transmit traces: 0x%2.2x", tx);
1690+ print_field("Transmit ARQ: 0x%2.2x", tx_arq);
1691+ print_field("Receive traces: 0x%2.2x", rx);
1692+}
1693+
1694+static void stimulate_exception_cmd(const void *data, uint8_t size)
1695+{
1696+ uint8_t type = get_u8(data);
1697+ const char *str;
1698+
1699+ switch (type) {
1700+ case 0x00:
1701+ str = "Fatal Exception";
1702+ break;
1703+ case 0x01:
1704+ str = "Debug Exception";
1705+ break;
1706+ default:
1707+ str = "Reserved";
1708+ break;
1709+ }
1710+
1711+ print_field("Type: %s (0x%2.2x)", str, type);
1712+}
1713+
1714+static const struct {
1715+ uint8_t bit;
1716+ const char *str;
1717+} events_table[] = {
1718+ { 0, "Bootup" },
1719+ { 1, "SCO Rejected via LMP" },
1720+ { 2, "PTT Switch Notification" },
1721+ { 7, "Scan Status" },
1722+ { 9, "Debug Exception" },
1723+ { 10, "Fatal Exception" },
1724+ { 11, "System Exception" },
1725+ { 13, "LE Link Established" },
1726+ { 14, "FW Trace String" },
1727+ { }
1728+};
1729+
1730+static void set_event_mask_cmd(const void *data, uint8_t size)
1731+{
1732+ const uint8_t *events_array = data;
1733+ uint64_t mask, events = 0;
1734+ int i;
1735+
1736+ for (i = 0; i < 8; i++)
1737+ events |= ((uint64_t) events_array[i]) << (i * 8);
1738+
1739+ print_field("Mask: 0x%16.16" PRIx64, events);
1740+
1741+ mask = events;
1742+
1743+ for (i = 0; events_table[i].str; i++) {
1744+ if (events & (((uint64_t) 1) << events_table[i].bit)) {
1745+ print_field(" %s", events_table[i].str);
1746+ mask &= ~(((uint64_t) 1) << events_table[i].bit);
1747+ }
1748+ }
1749+
1750+ if (mask)
1751+ print_text(COLOR_UNKNOWN_EVENT_MASK, " Unknown mask "
1752+ "(0x%16.16" PRIx64 ")", mask);
1753+}
1754+
1755+static void ddc_config_write_cmd(const void *data, uint8_t size)
1756+{
1757+ while (size > 0) {
1758+ uint8_t param_len = get_u8(data);
1759+ uint16_t param_id = get_le16(data + 1);
1760+
1761+ print_field("Identifier: 0x%4.4x", param_id);
1762+ packet_hexdump(data + 2, param_len - 2);
1763+
1764+ data += param_len + 1;
1765+ size -= param_len + 1;
1766+ }
1767+}
1768+
1769+static void ddc_config_write_rsp(const void *data, uint8_t size)
1770+{
1771+ uint8_t status = get_u8(data);
1772+ uint16_t param_id = get_le16(data + 1);
1773+
1774+ print_status(status);
1775+ print_field("Identifier: 0x%4.4x", param_id);
1776+}
1777+
1778+static void memory_write_cmd(const void *data, uint8_t size)
1779+{
1780+ uint32_t addr = get_le32(data);
1781+ uint8_t mode = get_u8(data + 4);
1782+ uint8_t length = get_u8(data + 5);
1783+ const char *str;
1784+
1785+ print_field("Address: 0x%8.8x", addr);
1786+
1787+ switch (mode) {
1788+ case 0x00:
1789+ str = "Byte access";
1790+ break;
1791+ case 0x01:
1792+ str = "Half word access";
1793+ break;
1794+ case 0x02:
1795+ str = "Word access";
1796+ break;
1797+ default:
1798+ str = "Reserved";
1799+ break;
1800+ }
1801+
1802+ print_field("Mode: %s (0x%2.2x)", str, mode);
1803+ print_field("Length: %u", length);
1804+
1805+ packet_hexdump(data + 6, size - 6);
1806+}
1807+
1808+static const struct vendor_ocf vendor_ocf_table[] = {
1809+ { 0x001, "Reset",
1810+ reset_cmd, 8, true,
1811+ status_rsp, 1, true },
1812+ { 0x002, "No Operation" },
1813+ { 0x005, "Read Version",
1814+ null_cmd, 0, true,
1815+ read_version_rsp, 10, true },
1816+ { 0x006, "Set UART Baudrate" },
1817+ { 0x007, "Enable LPM" },
1818+ { 0x008, "PCM Write Configuration" },
1819+ { 0x009, "Secure Send",
1820+ secure_send_cmd, 1, false,
1821+ status_rsp, 1, true },
1822+ { 0x00d, "Read Secure Boot Params",
1823+ null_cmd, 0, true },
1824+ { 0x00e, "Write Secure Boot Params" },
1825+ { 0x00f, "Unlock" },
1826+ { 0x010, "Change UART Baudrate" },
1827+ { 0x011, "Manufacturer Mode",
1828+ manufacturer_mode_cmd, 2, true,
1829+ status_rsp, 1, true },
1830+ { 0x012, "Read Link RSSI" },
1831+ { 0x022, "Get Exception Info" },
1832+ { 0x024, "Clear Exception Info" },
1833+ { 0x02f, "Write BD Data",
1834+ write_bd_data_cmd, 6, false },
1835+ { 0x030, "Read BD Data",
1836+ null_cmd, 0, true,
1837+ read_bd_data_rsp, 7, false },
1838+ { 0x031, "Write BD Address",
1839+ write_bd_address_cmd, 6, true,
1840+ status_rsp, 1, true },
1841+ { 0x032, "Flow Specification" },
1842+ { 0x034, "Read Secure ID" },
1843+ { 0x038, "Set Synchronous USB Interface Type" },
1844+ { 0x039, "Config Synchronous Interface" },
1845+ { 0x03f, "SW RF Kill",
1846+ null_cmd, 0, true,
1847+ status_rsp, 1, true },
1848+ { 0x043, "Activate Deactivate Traces",
1849+ act_deact_traces_cmd, 3, true },
1850+ { 0x04d, "Stimulate Exception",
1851+ stimulate_exception_cmd, 1, true,
1852+ status_rsp, 1, true },
1853+ { 0x050, "Read HW Version" },
1854+ { 0x052, "Set Event Mask",
1855+ set_event_mask_cmd, 8, true,
1856+ status_rsp, 1, true },
1857+ { 0x053, "Config_Link_Controller" },
1858+ { 0x089, "DDC Write" },
1859+ { 0x08a, "DDC Read" },
1860+ { 0x08b, "DDC Config Write",
1861+ ddc_config_write_cmd, 3, false,
1862+ ddc_config_write_rsp, 3, true },
1863+ { 0x08c, "DDC Config Read" },
1864+ { 0x08d, "Memory Read" },
1865+ { 0x08e, "Memory Write",
1866+ memory_write_cmd, 6, false,
1867+ status_rsp, 1, true },
1868+ { }
1869+};
1870+
1871+const struct vendor_ocf *intel_vendor_ocf(uint16_t ocf)
1872+{
1873+ int i;
1874+
1875+ for (i = 0; vendor_ocf_table[i].str; i++) {
1876+ if (vendor_ocf_table[i].ocf == ocf)
1877+ return &vendor_ocf_table[i];
1878+ }
1879+
1880+ return NULL;
1881+}
1882+
1883+static void fatal_exception_evt(const void *data, uint8_t size)
1884+{
1885+ uint16_t line = get_le16(data);
1886+ uint8_t module = get_u8(data + 2);
1887+ uint8_t reason = get_u8(data + 3);
1888+
1889+ print_field("Line: %u", line);
1890+ print_module(module);
1891+ print_field("Reason: 0x%2.2x", reason);
1892+}
1893+
1894+static void bootup_evt(const void *data, uint8_t size)
1895+{
1896+ uint8_t zero = get_u8(data);
1897+ uint8_t num_packets = get_u8(data + 1);
1898+ uint8_t source = get_u8(data + 2);
1899+ uint8_t reset_type = get_u8(data + 3);
1900+ uint8_t reset_reason = get_u8(data + 4);
1901+ uint8_t ddc_status = get_u8(data + 5);
1902+ const char *str;
1903+
1904+ print_field("Zero: 0x%2.2x", zero);
1905+ print_field("Number of packets: %d", num_packets);
1906+
1907+ switch (source) {
1908+ case 0x00:
1909+ str = "Bootloader";
1910+ break;
1911+ case 0x01:
1912+ str = "Operational firmware";
1913+ break;
1914+ case 0x02:
1915+ str = "Self test firmware";
1916+ break;
1917+ default:
1918+ str = "Reserved";
1919+ break;
1920+ }
1921+
1922+ print_field("Source: %s (0x%2.2x)", str, source);
1923+
1924+ switch (reset_type) {
1925+ case 0x00:
1926+ str = "Hardware reset";
1927+ break;
1928+ case 0x01:
1929+ str = "Soft watchdog reset";
1930+ break;
1931+ case 0x02:
1932+ str = "Soft software reset";
1933+ break;
1934+ case 0x03:
1935+ str = "Hard watchdog reset";
1936+ break;
1937+ case 0x04:
1938+ str = "Hard software reset";
1939+ break;
1940+ default:
1941+ str = "Reserved";
1942+ break;
1943+ }
1944+
1945+ print_field("Reset type: %s (0x%2.2x)", str, reset_type);
1946+
1947+ switch (reset_reason) {
1948+ case 0x00:
1949+ str = "Power on";
1950+ break;
1951+ case 0x01:
1952+ str = "Reset command";
1953+ break;
1954+ case 0x02:
1955+ str = "Intel reset command";
1956+ break;
1957+ case 0x03:
1958+ str = "Watchdog";
1959+ break;
1960+ case 0x04:
1961+ str = "Fatal exception";
1962+ break;
1963+ case 0x05:
1964+ str = "System exception";
1965+ break;
1966+ case 0xff:
1967+ str = "Unknown";
1968+ break;
1969+ default:
1970+ str = "Reserved";
1971+ break;
1972+ }
1973+
1974+ print_field("Reset reason: %s (0x%2.2x)", str, reset_reason);
1975+
1976+ switch (ddc_status) {
1977+ case 0x00:
1978+ str = "Firmware default";
1979+ break;
1980+ case 0x01:
1981+ str = "Firmware default plus OTP";
1982+ break;
1983+ case 0x02:
1984+ str = "Persistent RAM";
1985+ break;
1986+ case 0x03:
1987+ str = "Not used";
1988+ break;
1989+ default:
1990+ str = "Reserved";
1991+ break;
1992+ }
1993+
1994+ print_field("DDC status: %s (0x%2.2x)", str, ddc_status);
1995+}
1996+
1997+static void default_bd_data_evt(const void *data, uint8_t size)
1998+{
1999+ uint8_t mem_status = get_u8(data);
2000+ const char *str;
2001+
2002+ switch (mem_status) {
2003+ case 0x02:
2004+ str = "Invalid manufacturing data";
2005+ break;
2006+ default:
2007+ str = "Reserved";
2008+ break;
2009+ }
2010+
2011+ print_field("Memory status: %s (0x%2.2x)", str, mem_status);
2012+}
2013+
2014+static void secure_send_commands_result_evt(const void *data, uint8_t size)
2015+{
2016+ uint8_t result = get_u8(data);
2017+ uint16_t opcode = get_le16(data + 1);
2018+ uint16_t ogf = cmd_opcode_ogf(opcode);
2019+ uint16_t ocf = cmd_opcode_ocf(opcode);
2020+ uint8_t status = get_u8(data + 3);
2021+ const char *str;
2022+
2023+ switch (result) {
2024+ case 0x00:
2025+ str = "Success";
2026+ break;
2027+ case 0x01:
2028+ str = "General failure";
2029+ break;
2030+ case 0x02:
2031+ str = "Hardware failure";
2032+ break;
2033+ case 0x03:
2034+ str = "Signature verification failed";
2035+ break;
2036+ case 0x04:
2037+ str = "Parsing error of command buffer";
2038+ break;
2039+ case 0x05:
2040+ str = "Command execution failure";
2041+ break;
2042+ case 0x06:
2043+ str = "Command parameters error";
2044+ break;
2045+ case 0x07:
2046+ str = "Command missing";
2047+ break;
2048+ default:
2049+ str = "Reserved";
2050+ break;
2051+ }
2052+
2053+ print_field("Result: %s (0x%2.2x)", str, result);
2054+ print_field("Opcode: 0x%4.4x (0x%2.2x|0x%4.4x)", opcode, ogf, ocf);
2055+ print_status(status);
2056+}
2057+
2058+static void debug_exception_evt(const void *data, uint8_t size)
2059+{
2060+ uint16_t line = get_le16(data);
2061+ uint8_t module = get_u8(data + 2);
2062+ uint8_t reason = get_u8(data + 3);
2063+
2064+ print_field("Line: %u", line);
2065+ print_module(module);
2066+ print_field("Reason: 0x%2.2x", reason);
2067+}
2068+
2069+static void le_link_established_evt(const void *data, uint8_t size)
2070+{
2071+ uint16_t handle = get_le16(data);
2072+ uint32_t access_addr = get_le32(data + 10);
2073+
2074+ print_field("Handle: %u", handle);
2075+
2076+ packet_hexdump(data + 2, 8);
2077+
2078+ print_field("Access address: 0x%8.8x", access_addr);
2079+
2080+ packet_hexdump(data + 14, size - 14);
2081+}
2082+
2083+static void scan_status_evt(const void *data, uint8_t size)
2084+{
2085+ uint8_t enable = get_u8(data);
2086+
2087+ print_field("Inquiry scan: %s",
2088+ (enable & 0x01) ? "Enabled" : "Disabled");
2089+ print_field("Page scan: %s",
2090+ (enable & 0x02) ? "Enabled" : "Disabled");
2091+
2092+ if (enable & 0xfc)
2093+ print_text(COLOR_UNKNOWN_SCAN_STATUS,
2094+ " Unknown status (0x%2.2x)", enable & 0xfc);
2095+
2096+}
2097+
2098+static void act_deact_traces_complete_evt(const void *data, uint8_t size)
2099+{
2100+ uint8_t status = get_u8(data);
2101+
2102+ print_status(status);
2103+}
2104+
2105+static void lmp_pdu_trace_evt(const void *data, uint8_t size)
2106+{
2107+ uint8_t type, len, id;
2108+ uint16_t handle, count;
2109+ uint32_t clock;
2110+ const char *str;
2111+
2112+ type = get_u8(data);
2113+ handle = get_le16(data + 1);
2114+
2115+ switch (type) {
2116+ case 0x00:
2117+ str = "RX LMP";
2118+ break;
2119+ case 0x01:
2120+ str = "TX LMP";
2121+ break;
2122+ case 0x02:
2123+ str = "ACK LMP";
2124+ break;
2125+ case 0x03:
2126+ str = "RX LL";
2127+ break;
2128+ case 0x04:
2129+ str = "TX LL";
2130+ break;
2131+ case 0x05:
2132+ str = "ACK LL";
2133+ break;
2134+ default:
2135+ str = "Unknown";
2136+ break;
2137+ }
2138+
2139+ print_field("Type: %s (0x%2.2x)", str, type);
2140+ print_field("Handle: %u", handle);
2141+
2142+ switch (type) {
2143+ case 0x00:
2144+ len = size - 8;
2145+ clock = get_le32(data + 4 + len);
2146+
2147+ packet_hexdump(data + 3, 1);
2148+ lmp_packet(data + 4, len, false);
2149+ print_field("Clock: 0x%8.8x", clock);
2150+ break;
2151+ case 0x01:
2152+ len = size - 9;
2153+ clock = get_le32(data + 4 + len);
2154+ id = get_u8(data + 4 + len + 4);
2155+
2156+ packet_hexdump(data + 3, 1);
2157+ lmp_packet(data + 4, len, false);
2158+ print_field("Clock: 0x%8.8x", clock);
2159+ print_field("ID: 0x%2.2x", id);
2160+ break;
2161+ case 0x02:
2162+ clock = get_le32(data + 3);
2163+ id = get_u8(data + 3 + 4);
2164+
2165+ print_field("Clock: 0x%8.8x", clock);
2166+ print_field("ID: 0x%2.2x", id);
2167+ break;
2168+ case 0x03:
2169+ len = size - 8;
2170+ count = get_le16(data + 3);
2171+
2172+ print_field("Count: 0x%4.4x", count);
2173+ packet_hexdump(data + 3 + 2 + 1, 2);
2174+ llcp_packet(data + 8, len, false);
2175+ break;
2176+ case 0x04:
2177+ len = size - 8;
2178+ count = get_le16(data + 3);
2179+ id = get_u8(data + 3 + 2);
2180+
2181+ print_field("Count: 0x%4.4x", count);
2182+ print_field("ID: 0x%2.2x", id);
2183+ packet_hexdump(data + 3 + 2 + 1, 2);
2184+ llcp_packet(data + 8, len, false);
2185+ break;
2186+ case 0x05:
2187+ count = get_le16(data + 3);
2188+ id = get_u8(data + 3 + 2);
2189+
2190+ print_field("Count: 0x%4.4x", count);
2191+ print_field("ID: 0x%2.2x", id);
2192+ break;
2193+ default:
2194+ packet_hexdump(data + 3, size - 3);
2195+ break;
2196+ }
2197+}
2198+
2199+static void write_bd_data_complete_evt(const void *data, uint8_t size)
2200+{
2201+ uint8_t status = get_u8(data);
2202+
2203+ print_status(status);
2204+}
2205+
2206+static void sco_rejected_via_lmp_evt(const void *data, uint8_t size)
2207+{
2208+ uint8_t reason = get_u8(data + 6);
2209+
2210+ packet_print_addr("Address", data, false);
2211+ packet_print_error("Reason", reason);
2212+}
2213+
2214+static void ptt_switch_notification_evt(const void *data, uint8_t size)
2215+{
2216+ uint16_t handle = get_le16(data);
2217+ uint8_t table = get_u8(data + 2);
2218+ const char *str;
2219+
2220+ print_field("Handle: %u", handle);
2221+
2222+ switch (table) {
2223+ case 0x00:
2224+ str = "Basic rate";
2225+ break;
2226+ case 0x01:
2227+ str = "Enhanced data rate";
2228+ break;
2229+ default:
2230+ str = "Reserved";
2231+ break;
2232+ }
2233+
2234+ print_field("Packet type table: %s (0x%2.2x)", str, table);
2235+}
2236+
2237+static void system_exception_evt(const void *data, uint8_t size)
2238+{
2239+ uint8_t type = get_u8(data);
2240+ const char *str;
2241+
2242+ switch (type) {
2243+ case 0x00:
2244+ str = "No Exception";
2245+ break;
2246+ case 0x01:
2247+ str = "Undefined Instruction";
2248+ break;
2249+ case 0x02:
2250+ str = "Prefetch abort";
2251+ break;
2252+ case 0x03:
2253+ str = "Data abort";
2254+ break;
2255+ default:
2256+ str = "Reserved";
2257+ break;
2258+ }
2259+
2260+ print_field("Type: %s (0x%2.2x)", str, type);
2261+
2262+ packet_hexdump(data + 1, size - 1);
2263+}
2264+
2265+static const struct vendor_evt vendor_evt_table[] = {
2266+ { 0x01, "Fatal Exception",
2267+ fatal_exception_evt, 4, true },
2268+ { 0x02, "Bootup",
2269+ bootup_evt, 6, true },
2270+ { 0x05, "Default BD Data",
2271+ default_bd_data_evt, 1, true },
2272+ { 0x06, "Secure Send Commands Result",
2273+ secure_send_commands_result_evt, 4, true },
2274+ { 0x08, "Debug Exception",
2275+ debug_exception_evt, 4, true },
2276+ { 0x0f, "LE Link Established",
2277+ le_link_established_evt, 26, true },
2278+ { 0x11, "Scan Status",
2279+ scan_status_evt, 1, true },
2280+ { 0x16, "Activate Deactivate Traces Complete",
2281+ act_deact_traces_complete_evt, 1, true },
2282+ { 0x17, "LMP PDU Trace",
2283+ lmp_pdu_trace_evt, 3, false },
2284+ { 0x19, "Write BD Data Complete",
2285+ write_bd_data_complete_evt, 1, true },
2286+ { 0x25, "SCO Rejected via LMP",
2287+ sco_rejected_via_lmp_evt, 7, true },
2288+ { 0x26, "PTT Switch Notification",
2289+ ptt_switch_notification_evt, 3, true },
2290+ { 0x29, "System Exception",
2291+ system_exception_evt, 133, true },
2292+ { 0x2c, "FW Trace String" },
2293+ { 0x2e, "FW Trace Binary" },
2294+ { }
2295+};
2296+
2297+const struct vendor_evt *intel_vendor_evt(uint8_t evt)
2298+{
2299+ int i;
2300+
2301+ for (i = 0; vendor_evt_table[i].str; i++) {
2302+ if (vendor_evt_table[i].evt == evt)
2303+ return &vendor_evt_table[i];
2304+ }
2305+
2306+ return NULL;
2307+}
2308
2309=== added file 'monitor/intel.h'
2310--- monitor/intel.h 1970-01-01 00:00:00 +0000
2311+++ monitor/intel.h 2015-11-23 18:34:05 +0000
2312@@ -0,0 +1,31 @@
2313+/*
2314+ *
2315+ * BlueZ - Bluetooth protocol stack for Linux
2316+ *
2317+ * Copyright (C) 2011-2014 Intel Corporation
2318+ * Copyright (C) 2002-2010 Marcel Holtmann <marcel@holtmann.org>
2319+ *
2320+ *
2321+ * This library is free software; you can redistribute it and/or
2322+ * modify it under the terms of the GNU Lesser General Public
2323+ * License as published by the Free Software Foundation; either
2324+ * version 2.1 of the License, or (at your option) any later version.
2325+ *
2326+ * This library is distributed in the hope that it will be useful,
2327+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
2328+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
2329+ * Lesser General Public License for more details.
2330+ *
2331+ * You should have received a copy of the GNU Lesser General Public
2332+ * License along with this library; if not, write to the Free Software
2333+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2334+ *
2335+ */
2336+
2337+#include <stdint.h>
2338+
2339+struct vendor_ocf;
2340+struct vendor_evt;
2341+
2342+const struct vendor_ocf *intel_vendor_ocf(uint16_t ocf);
2343+const struct vendor_evt *intel_vendor_evt(uint8_t evt);
2344
2345=== modified file 'monitor/ll.c'
2346--- monitor/ll.c 2015-09-15 13:42:52 +0000
2347+++ monitor/ll.c 2015-11-23 18:34:05 +0000
2348@@ -245,7 +245,7 @@
2349 }
2350 }
2351
2352-static void data_packet(const void *data, uint8_t size)
2353+static void data_packet(const void *data, uint8_t size, bool padded)
2354 {
2355 const uint8_t *ptr = data;
2356 uint8_t llid, length;
2357@@ -290,7 +290,7 @@
2358
2359 switch (llid) {
2360 case 0x03:
2361- llcp_packet(data + 2, size - 2);
2362+ llcp_packet(data + 2, size - 2, padded);
2363 break;
2364
2365 default:
2366@@ -299,7 +299,7 @@
2367 }
2368 }
2369
2370-void ll_packet(uint16_t frequency, const void *data, uint8_t size)
2371+void ll_packet(uint16_t frequency, const void *data, uint8_t size, bool padded)
2372 {
2373 const struct bt_ll_hdr *hdr = data;
2374 uint8_t channel = (frequency - 2402) / 2;
2375@@ -368,7 +368,7 @@
2376 if (access_addr == 0x8e89bed6)
2377 advertising_packet(pdu_data, pdu_len);
2378 else
2379- data_packet(pdu_data, pdu_len);
2380+ data_packet(pdu_data, pdu_len, padded);
2381 }
2382
2383 static void null_pdu(const void *data, uint8_t size)
2384@@ -460,6 +460,21 @@
2385 packet_print_error("Error code", pdu->error);
2386 }
2387
2388+static void slave_feature_req(const void *data, uint8_t size)
2389+{
2390+ const struct bt_ll_slave_feature_req *pdu = data;
2391+
2392+ packet_print_features_ll(pdu->features);
2393+}
2394+
2395+static void reject_ind_ext(const void *data, uint8_t size)
2396+{
2397+ const struct bt_ll_reject_ind_ext *pdu = data;
2398+
2399+ print_field("Reject opcode: %u (0x%2.2x)", pdu->opcode, pdu->opcode);
2400+ packet_print_error("Error code", pdu->error);
2401+}
2402+
2403 struct llcp_data {
2404 uint8_t opcode;
2405 const char *str;
2406@@ -469,22 +484,28 @@
2407 };
2408
2409 static const struct llcp_data llcp_table[] = {
2410- { 0x00, "LL_CONNECTION_UPDATE_REQ", conn_update_req, 11, true },
2411- { 0x01, "LL_CHANNEL_MAP_REQ", channel_map_req, 7, true },
2412- { 0x02, "LL_TERMINATE_IND", terminate_ind, 1, true },
2413- { 0x03, "LL_ENC_REQ", enc_req, 22, true },
2414- { 0x04, "LL_ENC_RSP", enc_rsp, 12, true },
2415- { 0x05, "LL_START_ENC_REQ", null_pdu, 0, true },
2416- { 0x06, "LL_START_ENC_RSP", null_pdu, 0, true },
2417- { 0x07, "LL_UNKNOWN_RSP", unknown_rsp, 1, true },
2418- { 0x08, "LL_FEATURE_REQ", feature_req, 8, true },
2419- { 0x09, "LL_FEATURE_RSP", feature_rsp, 8, true },
2420- { 0x0a, "LL_PAUSE_ENC_REQ", null_pdu, 0, true },
2421- { 0x0b, "LL_PAUSE_ENC_RSP", null_pdu, 0, true },
2422- { 0x0c, "LL_VERSION_IND", version_ind, 5, true },
2423- { 0x0d, "LL_REJECT_IND", reject_ind, 1, true },
2424- { 0x12, "LL_PING_REQ", null_pdu, 0, true },
2425- { 0x13, "LL_PING_RSP", null_pdu, 0, true },
2426+ { 0x00, "LL_CONNECTION_UPDATE_REQ", conn_update_req, 11, true },
2427+ { 0x01, "LL_CHANNEL_MAP_REQ", channel_map_req, 7, true },
2428+ { 0x02, "LL_TERMINATE_IND", terminate_ind, 1, true },
2429+ { 0x03, "LL_ENC_REQ", enc_req, 22, true },
2430+ { 0x04, "LL_ENC_RSP", enc_rsp, 12, true },
2431+ { 0x05, "LL_START_ENC_REQ", null_pdu, 0, true },
2432+ { 0x06, "LL_START_ENC_RSP", null_pdu, 0, true },
2433+ { 0x07, "LL_UNKNOWN_RSP", unknown_rsp, 1, true },
2434+ { 0x08, "LL_FEATURE_REQ", feature_req, 8, true },
2435+ { 0x09, "LL_FEATURE_RSP", feature_rsp, 8, true },
2436+ { 0x0a, "LL_PAUSE_ENC_REQ", null_pdu, 0, true },
2437+ { 0x0b, "LL_PAUSE_ENC_RSP", null_pdu, 0, true },
2438+ { 0x0c, "LL_VERSION_IND", version_ind, 5, true },
2439+ { 0x0d, "LL_REJECT_IND", reject_ind, 1, true },
2440+ { 0x0e, "LL_SLAVE_FEATURE_REQ", slave_feature_req, 8, true },
2441+ { 0x0f, "LL_CONNECTION_PARAM_REQ", NULL, 23, true },
2442+ { 0x10, "LL_CONNECTION_PARAM_RSP", NULL, 23, true },
2443+ { 0x11, "LL_REJECT_IND_EXT", reject_ind_ext, 2, true },
2444+ { 0x12, "LL_PING_REQ", null_pdu, 0, true },
2445+ { 0x13, "LL_PING_RSP", null_pdu, 0, true },
2446+ { 0x14, "LL_LENGTH_REQ", NULL, 8, true },
2447+ { 0x15, "LL_LENGTH_RSP", NULL, 8, true },
2448 { }
2449 };
2450
2451@@ -500,7 +521,7 @@
2452 return "Unknown";
2453 }
2454
2455-void llcp_packet(const void *data, uint8_t size)
2456+void llcp_packet(const void *data, uint8_t size, bool padded)
2457 {
2458 uint8_t opcode = ((const uint8_t *) data)[0];
2459 const struct llcp_data *llcp_data = NULL;
2460@@ -533,7 +554,7 @@
2461 return;
2462 }
2463
2464- if (llcp_data->fixed) {
2465+ if (llcp_data->fixed && !padded) {
2466 if (size - 1 != llcp_data->size) {
2467 print_text(COLOR_ERROR, "invalid packet size");
2468 packet_hexdump(data + 1, size - 1);
2469
2470=== modified file 'monitor/ll.h'
2471--- monitor/ll.h 2015-09-15 13:42:52 +0000
2472+++ monitor/ll.h 2015-11-23 18:34:05 +0000
2473@@ -24,5 +24,5 @@
2474
2475 #include <stdint.h>
2476
2477-void ll_packet(uint16_t frequency, const void *data, uint8_t size);
2478-void llcp_packet(const void *data, uint8_t size);
2479+void ll_packet(uint16_t frequency, const void *data, uint8_t size, bool padded);
2480+void llcp_packet(const void *data, uint8_t size, bool padded);
2481
2482=== modified file 'monitor/lmp.c'
2483--- monitor/lmp.c 2015-09-15 13:42:52 +0000
2484+++ monitor/lmp.c 2015-11-23 18:34:05 +0000
2485@@ -27,6 +27,7 @@
2486 #endif
2487
2488 #include <stdio.h>
2489+#include <string.h>
2490
2491 #include "src/shared/util.h"
2492 #include "display.h"
2493@@ -54,6 +55,26 @@
2494 print_field("Operation: %s (%u)", str, opcode);
2495 }
2496
2497+static void name_req(const void *data, uint8_t size)
2498+{
2499+ const struct bt_lmp_name_req *pdu = data;
2500+
2501+ print_field("Offset: %u", pdu->offset);
2502+}
2503+
2504+static void name_rsp(const void *data, uint8_t size)
2505+{
2506+ const struct bt_lmp_name_rsp *pdu = data;
2507+ char str[15];
2508+
2509+ memcpy(str, pdu->fragment, 14);
2510+ str[14] = '\0';
2511+
2512+ print_field("Offset: %u", pdu->offset);
2513+ print_field("Length: %u", pdu->length);
2514+ print_field("Fragment: %s", str);
2515+}
2516+
2517 static void accepted(const void *data, uint8_t size)
2518 {
2519 const struct bt_lmp_accepted *pdu = data;
2520@@ -73,6 +94,13 @@
2521 {
2522 }
2523
2524+static void clkoffset_rsp(const void *data, uint8_t size)
2525+{
2526+ const struct bt_lmp_clkoffset_rsp *pdu = data;
2527+
2528+ print_field("Clock offset: 0x%4.4x", le16_to_cpu(pdu->offset));
2529+}
2530+
2531 static void detach(const void *data, uint8_t size)
2532 {
2533 const struct bt_lmp_detach *pdu = data;
2534@@ -135,6 +163,13 @@
2535 {
2536 }
2537
2538+static void switch_req(const void *data, uint8_t size)
2539+{
2540+ const struct bt_lmp_switch_req *pdu = data;
2541+
2542+ print_field("Instant: 0x%8.8x", le32_to_cpu(pdu->instant));
2543+}
2544+
2545 static void unsniff_req(const void *data, uint8_t size)
2546 {
2547 }
2548@@ -151,6 +186,67 @@
2549 {
2550 }
2551
2552+static void preferred_rate(const void *data, uint8_t size)
2553+{
2554+ const struct bt_lmp_preferred_rate *pdu = data;
2555+ const char *str;
2556+
2557+ str = (pdu->rate & 0x01) ? "do not use FEC" : "use FEC";
2558+
2559+ print_field("Basic data rate: %s (0x%02x)", str, pdu->rate & 0x01);
2560+
2561+ switch ((pdu->rate & 0x06) >> 1) {
2562+ case 0:
2563+ str = "No packet-size preference available";
2564+ break;
2565+ case 1:
2566+ str = "use 1-slot packets";
2567+ break;
2568+ case 2:
2569+ str = "use 3-slot packets";
2570+ break;
2571+ case 3:
2572+ str = "use 5-slot packets";
2573+ break;
2574+ }
2575+
2576+ print_field("Basic data rate: %s (0x%02x)", str, pdu->rate & 0x06);
2577+
2578+ switch ((pdu->rate & 0x11) >> 3) {
2579+ case 0:
2580+ str = "use DM1 packets";
2581+ break;
2582+ case 1:
2583+ str = "use 2 Mb/s packets";
2584+ break;
2585+ case 2:
2586+ str = "use 3 MB/s packets";
2587+ break;
2588+ case 3:
2589+ str = "reserved";
2590+ break;
2591+ }
2592+
2593+ print_field("Enhanced data rate: %s (0x%2.2x)", str, pdu->rate & 0x11);
2594+
2595+ switch ((pdu->rate & 0x60) >> 5) {
2596+ case 0:
2597+ str = "No packet-size preference available";
2598+ break;
2599+ case 1:
2600+ str = "use 1-slot packets";
2601+ break;
2602+ case 2:
2603+ str = "use 3-slot packets";
2604+ break;
2605+ case 3:
2606+ str = "use 5-slot packets";
2607+ break;
2608+ }
2609+
2610+ print_field("Enhanced data rate: %s (0x%2.2x)", str, pdu->rate & 0x60);
2611+}
2612+
2613 static void version_req(const void *data, uint8_t size)
2614 {
2615 const struct bt_lmp_version_req *pdu = data;
2616@@ -221,6 +317,14 @@
2617 {
2618 }
2619
2620+static void slot_offset(const void *data, uint8_t size)
2621+{
2622+ const struct bt_lmp_slot_offset *pdu = data;
2623+
2624+ print_field("Offset: %u usec", le16_to_cpu(pdu->offset));
2625+ packet_print_addr("Address", pdu->bdaddr, false);
2626+}
2627+
2628 static void page_scan_mode_req(const void *data, uint8_t size)
2629 {
2630 const struct bt_lmp_page_scan_mode_req *pdu = data;
2631@@ -446,7 +550,7 @@
2632 for (i = 0; i < 10; i++)
2633 sprintf(str + (i * 2), "%2.2x", pdu->classification[i]);
2634
2635- print_field("Features: 0x%s", str);
2636+ print_field("Classification: 0x%s", str);
2637 }
2638
2639 static void pause_encryption_req(const void *data, uint8_t size)
2640@@ -625,12 +729,12 @@
2641 };
2642
2643 static const struct lmp_data lmp_table[] = {
2644- { 1, "LMP_name_req" },
2645- { 2, "LMP_name_res" },
2646+ { 1, "LMP_name_req", name_req, 1, true },
2647+ { 2, "LMP_name_res", name_rsp, 16, true },
2648 { 3, "LMP_accepted", accepted, 1, true },
2649 { 4, "LMP_not_accepted", not_accepted, 2, true },
2650 { 5, "LMP_clkoffset_req", clkoffset_req, 0, true },
2651- { 6, "LMP_clkoffset_res" },
2652+ { 6, "LMP_clkoffset_res", clkoffset_rsp, 2, true },
2653 { 7, "LMP_detach", detach, 1, true },
2654 { 8, "LMP_in_rand" },
2655 { 9, "LMP_comb_key" },
2656@@ -643,7 +747,7 @@
2657 { 16, "LMP_encryption_key_size_req", encryption_key_size_req, 1, true },
2658 { 17, "LMP_start_encryption_req", start_encryption_req, 16, true },
2659 { 18, "LMP_stop_encryption_req", stop_encryption_req, 0, true },
2660- { 19, "LMP_switch_req" },
2661+ { 19, "LMP_switch_req", switch_req, 4, true },
2662 { 20, "LMP_hold" },
2663 { 21, "LMP_hold_req" },
2664 { 22, "LMP_sniff" },
2665@@ -660,7 +764,7 @@
2666 { 33, "LMP_max_power", max_power, 0, true },
2667 { 34, "LMP_min_power", min_power, 0, true },
2668 { 35, "LMP_auto_rate", auto_rate, 0, true },
2669- { 36, "LMP_preferred_rate" },
2670+ { 36, "LMP_preferred_rate", preferred_rate, 1, true },
2671 { 37, "LMP_version_req", version_req, 5, true },
2672 { 38, "LMP_version_res", version_res, 5, true },
2673 { 39, "LMP_features_req", features_req, 8, true },
2674@@ -676,7 +780,7 @@
2675 { 49, "LMP_setup_complete", setup_complete, 0, true },
2676 { 50, "LMP_use_semi_permanent_key", use_semi_permanent_key, 0, true },
2677 { 51, "LMP_host_connection_req", host_connection_req, 0, true },
2678- { 52, "LMP_slot_offset" },
2679+ { 52, "LMP_slot_offset", slot_offset, 8, true },
2680 { 53, "LMP_page_mode_req" },
2681 { 54, "LMP_page_scan_mode_req", page_scan_mode_req, 2, true },
2682 { 55, "LMP_supervision_timeout" },
2683@@ -732,19 +836,27 @@
2684 return NULL;
2685 }
2686
2687-void lmp_packet(const void *data, uint8_t size)
2688+void lmp_packet(const void *data, uint8_t size, bool padded)
2689 {
2690 const struct lmp_data *lmp_data = NULL;
2691 const char *opcode_color, *opcode_str;
2692 uint16_t opcode;
2693 uint8_t tid, off;
2694+ const char *tid_str;
2695 int i;
2696
2697 tid = ((const uint8_t *) data)[0] & 0x01;
2698 opcode = (((const uint8_t *) data)[0] & 0xfe) >> 1;
2699
2700+ tid_str = tid == 0x00 ? "Master" : "Slave";
2701+
2702 switch (opcode) {
2703 case 127:
2704+ if (size < 2) {
2705+ print_text(COLOR_ERROR, "extended opcode too short");
2706+ packet_hexdump(data, size);
2707+ return;
2708+ }
2709 opcode = LMP_ESC4(((const uint8_t *) data)[1]);
2710 off = 2;
2711 break;
2712@@ -777,17 +889,19 @@
2713
2714 if (opcode & 0xff00)
2715 print_indent(6, opcode_color, "", opcode_str, COLOR_OFF,
2716- " (%u/%u) TID %u", opcode >> 8, opcode & 0xff, tid);
2717+ " (%u/%u) %s transaction (%u)",
2718+ opcode >> 8, opcode & 0xff, tid_str, tid);
2719 else
2720 print_indent(6, opcode_color, "", opcode_str, COLOR_OFF,
2721- " (%u) TID %d", opcode, tid);
2722+ " (%u) %s transaction (%d)",
2723+ opcode, tid_str, tid);
2724
2725 if (!lmp_data || !lmp_data->func) {
2726 packet_hexdump(data + off, size - off);
2727 return;
2728 }
2729
2730- if (lmp_data->fixed) {
2731+ if (lmp_data->fixed && !padded) {
2732 if (size - off != lmp_data->size) {
2733 print_text(COLOR_ERROR, "invalid packet size");
2734 packet_hexdump(data + off, size - off);
2735
2736=== modified file 'monitor/lmp.h'
2737--- monitor/lmp.h 2015-09-15 13:42:52 +0000
2738+++ monitor/lmp.h 2015-11-23 18:34:05 +0000
2739@@ -24,6 +24,6 @@
2740
2741 #include <stdint.h>
2742
2743-void lmp_packet(const void *data, uint8_t size);
2744+void lmp_packet(const void *data, uint8_t size, bool padded);
2745
2746 void lmp_todo(void);
2747
2748=== modified file 'monitor/packet.c'
2749--- monitor/packet.c 2015-09-15 13:42:52 +0000
2750+++ monitor/packet.c 2015-11-23 18:34:05 +0000
2751@@ -36,6 +36,7 @@
2752 #include <inttypes.h>
2753 #include <time.h>
2754 #include <sys/time.h>
2755+#include <sys/socket.h>
2756
2757 #include "lib/bluetooth.h"
2758 #include "lib/hci.h"
2759@@ -52,6 +53,8 @@
2760 #include "l2cap.h"
2761 #include "control.h"
2762 #include "vendor.h"
2763+#include "intel.h"
2764+#include "broadcom.h"
2765 #include "packet.h"
2766
2767 #define COLOR_INDEX_LABEL COLOR_WHITE
2768@@ -59,6 +62,10 @@
2769
2770 #define COLOR_NEW_INDEX COLOR_GREEN
2771 #define COLOR_DEL_INDEX COLOR_RED
2772+#define COLOR_OPEN_INDEX COLOR_GREEN
2773+#define COLOR_CLOSE_INDEX COLOR_RED
2774+#define COLOR_INDEX_INFO COLOR_GREEN
2775+#define COLOR_VENDOR_DIAG COLOR_YELLOW
2776
2777 #define COLOR_HCI_COMMAND COLOR_BLUE
2778 #define COLOR_HCI_COMMAND_UNKNOWN COLOR_WHITE_BG
2779@@ -85,6 +92,8 @@
2780 static uint16_t index_number = 0;
2781 static uint16_t index_current = 0;
2782
2783+#define UNKNOWN_MANUFACTURER 0xffff
2784+
2785 #define MAX_CONN 16
2786
2787 struct conn_data {
2788@@ -160,7 +169,8 @@
2789
2790 #define print_space(x) printf("%*c", (x), ' ');
2791
2792-static void print_packet(struct timeval *tv, uint16_t index, char ident,
2793+static void print_packet(struct timeval *tv, struct ucred *cred,
2794+ uint16_t index, char ident,
2795 const char *color, const char *label,
2796 const char *text, const char *extra)
2797 {
2798@@ -168,7 +178,8 @@
2799 char line[256], ts_str[64];
2800 int n, ts_len = 0, ts_pos = 0, len = 0, pos = 0;
2801
2802- if (filter_mask & PACKET_FILTER_SHOW_INDEX) {
2803+ if ((filter_mask & PACKET_FILTER_SHOW_INDEX) &&
2804+ index != HCI_DEV_NONE) {
2805 if (use_color()) {
2806 n = sprintf(ts_str + ts_pos, "%s", COLOR_INDEX_LABEL);
2807 if (n > 0)
2808@@ -2456,11 +2467,11 @@
2809
2810 if (str)
2811 print_field(" Firmware: %3.3u.%3.3u.%3.3u (%s)",
2812- (ver & 0x7000) >> 13,
2813+ (ver & 0xe000) >> 13,
2814 (ver & 0x1f00) >> 8, ver & 0x00ff, str);
2815 else
2816 print_field(" Firmware: %3.3u.%3.3u.%3.3u",
2817- (ver & 0x7000) >> 13,
2818+ (ver & 0xe000) >> 13,
2819 (ver & 0x1f00) >> 8, ver & 0x00ff);
2820
2821 if (rev != 0xffff)
2822@@ -3646,7 +3657,8 @@
2823 }
2824 }
2825
2826-void packet_control(struct timeval *tv, uint16_t index, uint16_t opcode,
2827+void packet_control(struct timeval *tv, struct ucred *cred,
2828+ uint16_t index, uint16_t opcode,
2829 const void *data, uint16_t size)
2830 {
2831 if (index_filter && index_number != index)
2832@@ -3664,17 +3676,21 @@
2833 #define MAX_INDEX 16
2834
2835 struct index_data {
2836- uint8_t type;
2837- uint8_t bdaddr[6];
2838+ uint8_t type;
2839+ uint8_t bdaddr[6];
2840+ uint16_t manufacturer;
2841 };
2842
2843 static struct index_data index_list[MAX_INDEX];
2844
2845-void packet_monitor(struct timeval *tv, uint16_t index, uint16_t opcode,
2846+void packet_monitor(struct timeval *tv, struct ucred *cred,
2847+ uint16_t index, uint16_t opcode,
2848 const void *data, uint16_t size)
2849 {
2850 const struct btsnoop_opcode_new_index *ni;
2851+ const struct btsnoop_opcode_index_info *ii;
2852 char str[18], extra_str[24];
2853+ uint16_t manufacturer;
2854
2855 if (index_filter && index_number != index)
2856 return;
2857@@ -3691,6 +3707,7 @@
2858 if (index < MAX_INDEX) {
2859 index_list[index].type = ni->type;
2860 memcpy(index_list[index].bdaddr, ni->bdaddr, 6);
2861+ index_list[index].manufacturer = UNKNOWN_MANUFACTURER;
2862 }
2863
2864 addr2str(ni->bdaddr, str);
2865@@ -3705,26 +3722,62 @@
2866 packet_del_index(tv, index, str);
2867 break;
2868 case BTSNOOP_OPCODE_COMMAND_PKT:
2869- packet_hci_command(tv, index, data, size);
2870+ packet_hci_command(tv, cred, index, data, size);
2871 break;
2872 case BTSNOOP_OPCODE_EVENT_PKT:
2873- packet_hci_event(tv, index, data, size);
2874+ packet_hci_event(tv, cred, index, data, size);
2875 break;
2876 case BTSNOOP_OPCODE_ACL_TX_PKT:
2877- packet_hci_acldata(tv, index, false, data, size);
2878+ packet_hci_acldata(tv, cred, index, false, data, size);
2879 break;
2880 case BTSNOOP_OPCODE_ACL_RX_PKT:
2881- packet_hci_acldata(tv, index, true, data, size);
2882+ packet_hci_acldata(tv, cred, index, true, data, size);
2883 break;
2884 case BTSNOOP_OPCODE_SCO_TX_PKT:
2885- packet_hci_scodata(tv, index, false, data, size);
2886+ packet_hci_scodata(tv, cred, index, false, data, size);
2887 break;
2888 case BTSNOOP_OPCODE_SCO_RX_PKT:
2889- packet_hci_scodata(tv, index, true, data, size);
2890+ packet_hci_scodata(tv, cred, index, true, data, size);
2891+ break;
2892+ case BTSNOOP_OPCODE_OPEN_INDEX:
2893+ if (index < MAX_INDEX)
2894+ addr2str(index_list[index].bdaddr, str);
2895+ else
2896+ sprintf(str, "00:00:00:00:00:00");
2897+
2898+ packet_open_index(tv, index, str);
2899+ break;
2900+ case BTSNOOP_OPCODE_CLOSE_INDEX:
2901+ if (index < MAX_INDEX)
2902+ addr2str(index_list[index].bdaddr, str);
2903+ else
2904+ sprintf(str, "00:00:00:00:00:00");
2905+
2906+ packet_close_index(tv, index, str);
2907+ break;
2908+ case BTSNOOP_OPCODE_INDEX_INFO:
2909+ ii = data;
2910+ manufacturer = le16_to_cpu(ii->manufacturer);
2911+
2912+ if (index < MAX_INDEX) {
2913+ memcpy(index_list[index].bdaddr, ii->bdaddr, 6);
2914+ index_list[index].manufacturer = manufacturer;
2915+ }
2916+
2917+ addr2str(ii->bdaddr, str);
2918+ packet_index_info(tv, index, str, manufacturer);
2919+ break;
2920+ case BTSNOOP_OPCODE_VENDOR_DIAG:
2921+ if (index < MAX_INDEX)
2922+ manufacturer = index_list[index].manufacturer;
2923+ else
2924+ manufacturer = UNKNOWN_MANUFACTURER;
2925+
2926+ packet_vendor_diag(tv, index, manufacturer, data, size);
2927 break;
2928 default:
2929 sprintf(extra_str, "(code %d len %d)", opcode, size);
2930- print_packet(tv, index, '*', COLOR_ERROR,
2931+ print_packet(tv, cred, index, '*', COLOR_ERROR,
2932 "Unknown packet", NULL, extra_str);
2933 packet_hexdump(data, size);
2934 break;
2935@@ -3741,10 +3794,10 @@
2936
2937 sprintf(str, "%u MHz", frequency);
2938
2939- print_packet(tv, 0, '*', COLOR_PHY_PACKET,
2940+ print_packet(tv, NULL, 0, '*', COLOR_PHY_PACKET,
2941 "Physical packet:", NULL, str);
2942
2943- ll_packet(frequency, data, size);
2944+ ll_packet(frequency, data, size, false);
2945 }
2946
2947 static void null_cmd(const void *data, uint8_t size)
2948@@ -5453,22 +5506,29 @@
2949 static void read_local_version_rsp(const void *data, uint8_t size)
2950 {
2951 const struct bt_hci_rsp_read_local_version *rsp = data;
2952+ uint16_t manufacturer;
2953
2954 print_status(rsp->status);
2955 print_hci_version(rsp->hci_ver, rsp->hci_rev);
2956
2957- switch (index_list[index_current].type) {
2958- case HCI_BREDR:
2959- print_lmp_version(rsp->lmp_ver, rsp->lmp_subver);
2960- break;
2961- case HCI_AMP:
2962- print_pal_version(rsp->lmp_ver, rsp->lmp_subver);
2963- break;
2964+ manufacturer = le16_to_cpu(rsp->manufacturer);
2965+
2966+ if (index_current < MAX_INDEX) {
2967+ switch (index_list[index_current].type) {
2968+ case HCI_BREDR:
2969+ print_lmp_version(rsp->lmp_ver, rsp->lmp_subver);
2970+ break;
2971+ case HCI_AMP:
2972+ print_pal_version(rsp->lmp_ver, rsp->lmp_subver);
2973+ break;
2974+ }
2975+
2976+ index_list[index_current].manufacturer = manufacturer;
2977 }
2978
2979 print_manufacturer(rsp->manufacturer);
2980
2981- switch (le16_to_cpu(rsp->manufacturer)) {
2982+ switch (manufacturer) {
2983 case 15:
2984 print_manufacturer_broadcom(rsp->lmp_subver, rsp->hci_rev);
2985 break;
2986@@ -5548,6 +5608,9 @@
2987
2988 print_status(rsp->status);
2989 print_bdaddr(rsp->bdaddr);
2990+
2991+ if (index_current < MAX_INDEX)
2992+ memcpy(index_list[index_current].bdaddr, rsp->bdaddr, 6);
2993 }
2994
2995 static void read_data_block_size_rsp(const void *data, uint8_t size)
2996@@ -7198,6 +7261,63 @@
2997 return NULL;
2998 }
2999
3000+static const char *current_vendor_str(void)
3001+{
3002+ uint16_t manufacturer;
3003+
3004+ if (index_current < MAX_INDEX)
3005+ manufacturer = index_list[index_current].manufacturer;
3006+ else
3007+ manufacturer = UNKNOWN_MANUFACTURER;
3008+
3009+ switch (manufacturer) {
3010+ case 2:
3011+ return "Intel";
3012+ case 15:
3013+ return "Broadcom";
3014+ }
3015+
3016+ return NULL;
3017+}
3018+
3019+static const struct vendor_ocf *current_vendor_ocf(uint16_t ocf)
3020+{
3021+ uint16_t manufacturer;
3022+
3023+ if (index_current < MAX_INDEX)
3024+ manufacturer = index_list[index_current].manufacturer;
3025+ else
3026+ manufacturer = UNKNOWN_MANUFACTURER;
3027+
3028+ switch (manufacturer) {
3029+ case 2:
3030+ return intel_vendor_ocf(ocf);
3031+ case 15:
3032+ return broadcom_vendor_ocf(ocf);
3033+ }
3034+
3035+ return NULL;
3036+}
3037+
3038+static const struct vendor_evt *current_vendor_evt(uint8_t evt)
3039+{
3040+ uint16_t manufacturer;
3041+
3042+ if (index_current < MAX_INDEX)
3043+ manufacturer = index_list[index_current].manufacturer;
3044+ else
3045+ manufacturer = UNKNOWN_MANUFACTURER;
3046+
3047+ switch (manufacturer) {
3048+ case 2:
3049+ return intel_vendor_evt(evt);
3050+ case 15:
3051+ return broadcom_vendor_evt(evt);
3052+ }
3053+
3054+ return NULL;
3055+}
3056+
3057 static void inquiry_complete_evt(const void *data, uint8_t size)
3058 {
3059 const struct bt_hci_evt_inquiry_complete *evt = data;
3060@@ -7346,8 +7466,10 @@
3061 uint16_t opcode = le16_to_cpu(evt->opcode);
3062 uint16_t ogf = cmd_opcode_ogf(opcode);
3063 uint16_t ocf = cmd_opcode_ocf(opcode);
3064+ struct opcode_data vendor_data;
3065 const struct opcode_data *opcode_data = NULL;
3066 const char *opcode_color, *opcode_str;
3067+ char vendor_str[150];
3068 int i;
3069
3070 for (i = 0; opcode_table[i].str; i++) {
3071@@ -7365,8 +7487,32 @@
3072 opcode_str = opcode_data->str;
3073 } else {
3074 if (ogf == 0x3f) {
3075- opcode_color = COLOR_HCI_COMMAND;
3076- opcode_str = "Vendor";
3077+ const struct vendor_ocf *vnd = current_vendor_ocf(ocf);
3078+
3079+ if (vnd) {
3080+ const char *str = current_vendor_str();
3081+
3082+ if (str) {
3083+ snprintf(vendor_str, sizeof(vendor_str),
3084+ "%s %s", str, vnd->str);
3085+ vendor_data.str = vendor_str;
3086+ } else
3087+ vendor_data.str = vnd->str;
3088+ vendor_data.rsp_func = vnd->rsp_func;
3089+ vendor_data.rsp_size = vnd->rsp_size;
3090+ vendor_data.rsp_fixed = vnd->rsp_fixed;
3091+
3092+ opcode_data = &vendor_data;
3093+
3094+ if (opcode_data->rsp_func)
3095+ opcode_color = COLOR_HCI_COMMAND;
3096+ else
3097+ opcode_color = COLOR_HCI_COMMAND_UNKNOWN;
3098+ opcode_str = opcode_data->str;
3099+ } else {
3100+ opcode_color = COLOR_HCI_COMMAND;
3101+ opcode_str = "Vendor";
3102+ }
3103 } else {
3104 opcode_color = COLOR_HCI_COMMAND_UNKNOWN;
3105 opcode_str = "Unknown";
3106@@ -7418,6 +7564,7 @@
3107 uint16_t ocf = cmd_opcode_ocf(opcode);
3108 const struct opcode_data *opcode_data = NULL;
3109 const char *opcode_color, *opcode_str;
3110+ char vendor_str[150];
3111 int i;
3112
3113 for (i = 0; opcode_table[i].str; i++) {
3114@@ -7432,8 +7579,23 @@
3115 opcode_str = opcode_data->str;
3116 } else {
3117 if (ogf == 0x3f) {
3118- opcode_color = COLOR_HCI_COMMAND;
3119- opcode_str = "Vendor";
3120+ const struct vendor_ocf *vnd = current_vendor_ocf(ocf);
3121+
3122+ if (vnd) {
3123+ const char *str = current_vendor_str();
3124+
3125+ if (str) {
3126+ snprintf(vendor_str, sizeof(vendor_str),
3127+ "%s %s", str, vnd->str);
3128+ opcode_str = vendor_str;
3129+ } else
3130+ opcode_str = vnd->str;
3131+
3132+ opcode_color = COLOR_HCI_COMMAND;
3133+ } else {
3134+ opcode_color = COLOR_HCI_COMMAND;
3135+ opcode_str = "Vendor";
3136+ }
3137 } else {
3138 opcode_color = COLOR_HCI_COMMAND_UNKNOWN;
3139 opcode_str = "Unknown";
3140@@ -8185,7 +8347,48 @@
3141 bool fixed;
3142 };
3143
3144-static const struct subevent_data subevent_table[] = {
3145+static void print_subevent(const struct subevent_data *subevent_data,
3146+ const void *data, uint8_t size)
3147+{
3148+ const char *subevent_color, *subevent_str;
3149+
3150+ if (subevent_data) {
3151+ if (subevent_data->func)
3152+ subevent_color = COLOR_HCI_EVENT;
3153+ else
3154+ subevent_color = COLOR_HCI_EVENT_UNKNOWN;
3155+ subevent_str = subevent_data->str;
3156+ } else {
3157+ subevent_color = COLOR_HCI_EVENT_UNKNOWN;
3158+ subevent_str = "Unknown";
3159+ }
3160+
3161+ print_indent(6, subevent_color, "", subevent_str, COLOR_OFF,
3162+ " (0x%2.2x)", subevent_data->subevent);
3163+
3164+ if (!subevent_data || !subevent_data->func) {
3165+ packet_hexdump(data, size);
3166+ return;
3167+ }
3168+
3169+ if (subevent_data->fixed) {
3170+ if (size != subevent_data->size) {
3171+ print_text(COLOR_ERROR, "invalid packet size");
3172+ packet_hexdump(data, size);
3173+ return;
3174+ }
3175+ } else {
3176+ if (size < subevent_data->size) {
3177+ print_text(COLOR_ERROR, "too short packet");
3178+ packet_hexdump(data, size);
3179+ return;
3180+ }
3181+ }
3182+
3183+ subevent_data->func(data, size);
3184+}
3185+
3186+static const struct subevent_data le_meta_event_table[] = {
3187 { 0x01, "LE Connection Complete",
3188 le_conn_complete_evt, 18, true },
3189 { 0x02, "LE Advertising Report",
3190@@ -8215,55 +8418,49 @@
3191 {
3192 uint8_t subevent = *((const uint8_t *) data);
3193 const struct subevent_data *subevent_data = NULL;
3194- const char *subevent_color, *subevent_str;
3195 int i;
3196
3197- for (i = 0; subevent_table[i].str; i++) {
3198- if (subevent_table[i].subevent == subevent) {
3199- subevent_data = &subevent_table[i];
3200+ for (i = 0; le_meta_event_table[i].str; i++) {
3201+ if (le_meta_event_table[i].subevent == subevent) {
3202+ subevent_data = &le_meta_event_table[i];
3203 break;
3204 }
3205 }
3206
3207- if (subevent_data) {
3208- if (subevent_data->func)
3209- subevent_color = COLOR_HCI_EVENT;
3210- else
3211- subevent_color = COLOR_HCI_EVENT_UNKNOWN;
3212- subevent_str = subevent_data->str;
3213- } else {
3214- subevent_color = COLOR_HCI_EVENT_UNKNOWN;
3215- subevent_str = "Unknown";
3216- }
3217-
3218- print_indent(6, subevent_color, "", subevent_str, COLOR_OFF,
3219- " (0x%2.2x)", subevent);
3220-
3221- if (!subevent_data || !subevent_data->func) {
3222- packet_hexdump(data + 1, size - 1);
3223- return;
3224- }
3225-
3226- if (subevent_data->fixed) {
3227- if (size - 1 != subevent_data->size) {
3228- print_text(COLOR_ERROR, "invalid packet size");
3229- packet_hexdump(data + 1, size - 1);
3230- return;
3231- }
3232- } else {
3233- if (size - 1 < subevent_data->size) {
3234- print_text(COLOR_ERROR, "too short packet");
3235- packet_hexdump(data + 1, size - 1);
3236- return;
3237- }
3238- }
3239-
3240- subevent_data->func(data + 1, size - 1);
3241+ print_subevent(subevent_data, data + 1, size - 1);
3242 }
3243
3244 static void vendor_evt(const void *data, uint8_t size)
3245 {
3246- vendor_event(0xffff, data, size);
3247+ uint8_t subevent = *((const uint8_t *) data);
3248+ struct subevent_data vendor_data;
3249+ char vendor_str[150];
3250+ const struct vendor_evt *vnd = current_vendor_evt(subevent);
3251+
3252+ if (vnd) {
3253+ const char *str = current_vendor_str();
3254+
3255+ if (str) {
3256+ snprintf(vendor_str, sizeof(vendor_str),
3257+ "%s %s", str, vnd->str);
3258+ vendor_data.str = vendor_str;
3259+ } else
3260+ vendor_data.str = vnd->str;
3261+ vendor_data.func = vnd->evt_func;
3262+ vendor_data.size = vnd->evt_size;
3263+ vendor_data.fixed = vnd->evt_fixed;
3264+
3265+ print_subevent(&vendor_data, data + 1, size - 1);
3266+ } else {
3267+ uint16_t manufacturer;
3268+
3269+ if (index_current < MAX_INDEX)
3270+ manufacturer = index_list[index_current].manufacturer;
3271+ else
3272+ manufacturer = UNKNOWN_MANUFACTURER;
3273+
3274+ vendor_event(manufacturer, data, size);
3275+ }
3276 }
3277
3278 struct event_data {
3279@@ -8437,31 +8634,76 @@
3280 sprintf(details, "(%s,%s,%s)", hci_typetostr(type),
3281 hci_bustostr(bus), name);
3282
3283- print_packet(tv, index, '=', COLOR_NEW_INDEX, "New Index",
3284+ print_packet(tv, NULL, index, '=', COLOR_NEW_INDEX, "New Index",
3285 label, details);
3286 }
3287
3288 void packet_del_index(struct timeval *tv, uint16_t index, const char *label)
3289 {
3290- print_packet(tv, index, '=', COLOR_DEL_INDEX, "Delete Index",
3291- label, NULL);
3292-}
3293-
3294-void packet_hci_command(struct timeval *tv, uint16_t index,
3295+ print_packet(tv, NULL, index, '=', COLOR_DEL_INDEX, "Delete Index",
3296+ label, NULL);
3297+}
3298+
3299+void packet_open_index(struct timeval *tv, uint16_t index, const char *label)
3300+{
3301+ print_packet(tv, NULL, index, '=', COLOR_OPEN_INDEX, "Open Index",
3302+ label, NULL);
3303+}
3304+
3305+void packet_close_index(struct timeval *tv, uint16_t index, const char *label)
3306+{
3307+ print_packet(tv, NULL, index, '=', COLOR_CLOSE_INDEX, "Close Index",
3308+ label, NULL);
3309+}
3310+
3311+void packet_index_info(struct timeval *tv, uint16_t index, const char *label,
3312+ uint16_t manufacturer)
3313+{
3314+ char details[128];
3315+
3316+ sprintf(details, "(%s)", bt_compidtostr(manufacturer));
3317+
3318+ print_packet(tv, NULL, index, '=', COLOR_INDEX_INFO, "Index Info",
3319+ label, details);
3320+}
3321+
3322+void packet_vendor_diag(struct timeval *tv, uint16_t index,
3323+ uint16_t manufacturer,
3324+ const void *data, uint16_t size)
3325+{
3326+ char extra_str[16];
3327+
3328+ sprintf(extra_str, "(len %d)", size);
3329+
3330+ print_packet(tv, NULL, index, '=', COLOR_VENDOR_DIAG,
3331+ "Vendor Diagnostic", NULL, extra_str);
3332+
3333+ switch (manufacturer) {
3334+ case 15:
3335+ broadcom_lm_diag(data, size);
3336+ break;
3337+ default:
3338+ packet_hexdump(data, size);
3339+ break;
3340+ }
3341+}
3342+
3343+void packet_hci_command(struct timeval *tv, struct ucred *cred, uint16_t index,
3344 const void *data, uint16_t size)
3345 {
3346 const hci_command_hdr *hdr = data;
3347 uint16_t opcode = le16_to_cpu(hdr->opcode);
3348 uint16_t ogf = cmd_opcode_ogf(opcode);
3349 uint16_t ocf = cmd_opcode_ocf(opcode);
3350+ struct opcode_data vendor_data;
3351 const struct opcode_data *opcode_data = NULL;
3352 const char *opcode_color, *opcode_str;
3353- char extra_str[25];
3354+ char extra_str[25], vendor_str[150];
3355 int i;
3356
3357 if (size < HCI_COMMAND_HDR_SIZE) {
3358 sprintf(extra_str, "(len %d)", size);
3359- print_packet(tv, index, '*', COLOR_ERROR,
3360+ print_packet(tv, cred, index, '*', COLOR_ERROR,
3361 "Malformed HCI Command packet", NULL, extra_str);
3362 packet_hexdump(data, size);
3363 return;
3364@@ -8485,8 +8727,32 @@
3365 opcode_str = opcode_data->str;
3366 } else {
3367 if (ogf == 0x3f) {
3368- opcode_color = COLOR_HCI_COMMAND;
3369- opcode_str = "Vendor";
3370+ const struct vendor_ocf *vnd = current_vendor_ocf(ocf);
3371+
3372+ if (vnd) {
3373+ const char *str = current_vendor_str();
3374+
3375+ if (str) {
3376+ snprintf(vendor_str, sizeof(vendor_str),
3377+ "%s %s", str, vnd->str);
3378+ vendor_data.str = vendor_str;
3379+ } else
3380+ vendor_data.str = vnd->str;
3381+ vendor_data.cmd_func = vnd->cmd_func;
3382+ vendor_data.cmd_size = vnd->cmd_size;
3383+ vendor_data.cmd_fixed = vnd->cmd_fixed;
3384+
3385+ opcode_data = &vendor_data;
3386+
3387+ if (opcode_data->cmd_func)
3388+ opcode_color = COLOR_HCI_COMMAND;
3389+ else
3390+ opcode_color = COLOR_HCI_COMMAND_UNKNOWN;
3391+ opcode_str = opcode_data->str;
3392+ } else {
3393+ opcode_color = COLOR_HCI_COMMAND;
3394+ opcode_str = "Vendor";
3395+ }
3396 } else {
3397 opcode_color = COLOR_HCI_COMMAND_UNKNOWN;
3398 opcode_str = "Unknown";
3399@@ -8495,7 +8761,7 @@
3400
3401 sprintf(extra_str, "(0x%2.2x|0x%4.4x) plen %d", ogf, ocf, hdr->plen);
3402
3403- print_packet(tv, index, '<', opcode_color, "HCI Command",
3404+ print_packet(tv, cred, index, '<', opcode_color, "HCI Command",
3405 opcode_str, extra_str);
3406
3407 if (!opcode_data || !opcode_data->cmd_func) {
3408@@ -8527,7 +8793,7 @@
3409 opcode_data->cmd_func(data, hdr->plen);
3410 }
3411
3412-void packet_hci_event(struct timeval *tv, uint16_t index,
3413+void packet_hci_event(struct timeval *tv, struct ucred *cred, uint16_t index,
3414 const void *data, uint16_t size)
3415 {
3416 const hci_event_hdr *hdr = data;
3417@@ -8538,7 +8804,7 @@
3418
3419 if (size < HCI_EVENT_HDR_SIZE) {
3420 sprintf(extra_str, "(len %d)", size);
3421- print_packet(tv, index, '*', COLOR_ERROR,
3422+ print_packet(tv, cred, index, '*', COLOR_ERROR,
3423 "Malformed HCI Event packet", NULL, extra_str);
3424 packet_hexdump(data, size);
3425 return;
3426@@ -8567,7 +8833,7 @@
3427
3428 sprintf(extra_str, "(0x%2.2x) plen %d", hdr->evt, hdr->plen);
3429
3430- print_packet(tv, index, '>', event_color, "HCI Event",
3431+ print_packet(tv, cred, index, '>', event_color, "HCI Event",
3432 event_str, extra_str);
3433
3434 if (!event_data || !event_data->func) {
3435@@ -8599,8 +8865,8 @@
3436 event_data->func(data, hdr->plen);
3437 }
3438
3439-void packet_hci_acldata(struct timeval *tv, uint16_t index, bool in,
3440- const void *data, uint16_t size)
3441+void packet_hci_acldata(struct timeval *tv, struct ucred *cred, uint16_t index,
3442+ bool in, const void *data, uint16_t size)
3443 {
3444 const struct bt_hci_acl_hdr *hdr = data;
3445 uint16_t handle = le16_to_cpu(hdr->handle);
3446@@ -8610,10 +8876,10 @@
3447
3448 if (size < sizeof(*hdr)) {
3449 if (in)
3450- print_packet(tv, index, '*', COLOR_ERROR,
3451+ print_packet(tv, cred, index, '*', COLOR_ERROR,
3452 "Malformed ACL Data RX packet", NULL, NULL);
3453 else
3454- print_packet(tv, index, '*', COLOR_ERROR,
3455+ print_packet(tv, cred, index, '*', COLOR_ERROR,
3456 "Malformed ACL Data TX packet", NULL, NULL);
3457 packet_hexdump(data, size);
3458 return;
3459@@ -8625,7 +8891,7 @@
3460 sprintf(handle_str, "Handle %d", acl_handle(handle));
3461 sprintf(extra_str, "flags 0x%2.2x dlen %d", flags, dlen);
3462
3463- print_packet(tv, index, in ? '>' : '<', COLOR_HCI_ACLDATA,
3464+ print_packet(tv, cred, index, in ? '>' : '<', COLOR_HCI_ACLDATA,
3465 in ? "ACL Data RX" : "ACL Data TX",
3466 handle_str, extra_str);
3467
3468@@ -8642,8 +8908,8 @@
3469 l2cap_packet(index, in, acl_handle(handle), flags, data, size);
3470 }
3471
3472-void packet_hci_scodata(struct timeval *tv, uint16_t index, bool in,
3473- const void *data, uint16_t size)
3474+void packet_hci_scodata(struct timeval *tv, struct ucred *cred, uint16_t index,
3475+ bool in, const void *data, uint16_t size)
3476 {
3477 const hci_sco_hdr *hdr = data;
3478 uint16_t handle = le16_to_cpu(hdr->handle);
3479@@ -8652,10 +8918,10 @@
3480
3481 if (size < HCI_SCO_HDR_SIZE) {
3482 if (in)
3483- print_packet(tv, index, '*', COLOR_ERROR,
3484+ print_packet(tv, cred, index, '*', COLOR_ERROR,
3485 "Malformed SCO Data RX packet", NULL, NULL);
3486 else
3487- print_packet(tv, index, '*', COLOR_ERROR,
3488+ print_packet(tv, cred, index, '*', COLOR_ERROR,
3489 "Malformed SCO Data TX packet", NULL, NULL);
3490 packet_hexdump(data, size);
3491 return;
3492@@ -8667,7 +8933,7 @@
3493 sprintf(handle_str, "Handle %d", acl_handle(handle));
3494 sprintf(extra_str, "flags 0x%2.2x dlen %d", flags, hdr->dlen);
3495
3496- print_packet(tv, index, in ? '>' : '<', COLOR_HCI_SCODATA,
3497+ print_packet(tv, cred, index, in ? '>' : '<', COLOR_HCI_SCODATA,
3498 in ? "SCO Data RX" : "SCO Data TX",
3499 handle_str, extra_str);
3500
3501@@ -8707,10 +8973,10 @@
3502 printf("\t%s\n", event_table[i].str);
3503 }
3504
3505- for (i = 0; subevent_table[i].str; i++) {
3506- if (subevent_table[i].func)
3507+ for (i = 0; le_meta_event_table[i].str; i++) {
3508+ if (le_meta_event_table[i].func)
3509 continue;
3510
3511- printf("\t%s\n", subevent_table[i].str);
3512+ printf("\t%s\n", le_meta_event_table[i].str);
3513 }
3514 }
3515
3516=== modified file 'monitor/packet.h'
3517--- monitor/packet.h 2015-09-15 13:42:52 +0000
3518+++ monitor/packet.h 2015-11-23 18:34:05 +0000
3519@@ -25,6 +25,7 @@
3520 #include <stdint.h>
3521 #include <stdbool.h>
3522 #include <sys/time.h>
3523+#include <sys/socket.h>
3524
3525 #define PACKET_FILTER_SHOW_INDEX (1 << 0)
3526 #define PACKET_FILTER_SHOW_DATE (1 << 1)
3527@@ -53,9 +54,11 @@
3528 void packet_print_io_capability(uint8_t capability);
3529 void packet_print_io_authentication(uint8_t authentication);
3530
3531-void packet_control(struct timeval *tv, uint16_t index, uint16_t opcode,
3532+void packet_control(struct timeval *tv, struct ucred *cred,
3533+ uint16_t index, uint16_t opcode,
3534 const void *data, uint16_t size);
3535-void packet_monitor(struct timeval *tv, uint16_t index, uint16_t opcode,
3536+void packet_monitor(struct timeval *tv, struct ucred *cred,
3537+ uint16_t index, uint16_t opcode,
3538 const void *data, uint16_t size);
3539 void packet_simulator(struct timeval *tv, uint16_t frequency,
3540 const void *data, uint16_t size);
3541@@ -63,14 +66,21 @@
3542 void packet_new_index(struct timeval *tv, uint16_t index, const char *label,
3543 uint8_t type, uint8_t bus, const char *name);
3544 void packet_del_index(struct timeval *tv, uint16_t index, const char *label);
3545+void packet_open_index(struct timeval *tv, uint16_t index, const char *label);
3546+void packet_close_index(struct timeval *tv, uint16_t index, const char *label);
3547+void packet_index_info(struct timeval *tv, uint16_t index, const char *label,
3548+ uint16_t manufacturer);
3549+void packet_vendor_diag(struct timeval *tv, uint16_t index,
3550+ uint16_t manufacturer,
3551+ const void *data, uint16_t size);
3552
3553-void packet_hci_command(struct timeval *tv, uint16_t index,
3554- const void *data, uint16_t size);
3555-void packet_hci_event(struct timeval *tv, uint16_t index,
3556- const void *data, uint16_t size);
3557-void packet_hci_acldata(struct timeval *tv, uint16_t index, bool in,
3558- const void *data, uint16_t size);
3559-void packet_hci_scodata(struct timeval *tv, uint16_t index, bool in,
3560- const void *data, uint16_t size);
3561+void packet_hci_command(struct timeval *tv, struct ucred *cred, uint16_t index,
3562+ const void *data, uint16_t size);
3563+void packet_hci_event(struct timeval *tv, struct ucred *cred, uint16_t index,
3564+ const void *data, uint16_t size);
3565+void packet_hci_acldata(struct timeval *tv, struct ucred *cred, uint16_t index,
3566+ bool in, const void *data, uint16_t size);
3567+void packet_hci_scodata(struct timeval *tv, struct ucred *cred, uint16_t index,
3568+ bool in, const void *data, uint16_t size);
3569
3570 void packet_todo(void);
3571
3572=== modified file 'monitor/vendor.h'
3573--- monitor/vendor.h 2015-09-15 13:42:52 +0000
3574+++ monitor/vendor.h 2015-11-23 18:34:05 +0000
3575@@ -24,4 +24,23 @@
3576
3577 #include <stdint.h>
3578
3579+struct vendor_ocf {
3580+ uint16_t ocf;
3581+ const char *str;
3582+ void (*cmd_func) (const void *data, uint8_t size);
3583+ uint8_t cmd_size;
3584+ bool cmd_fixed;
3585+ void (*rsp_func) (const void *data, uint8_t size);
3586+ uint8_t rsp_size;
3587+ bool rsp_fixed;
3588+};
3589+
3590+struct vendor_evt {
3591+ uint8_t evt;
3592+ const char *str;
3593+ void (*evt_func) (const void *data, uint8_t size);
3594+ uint8_t evt_size;
3595+ bool evt_fixed;
3596+};
3597+
3598 void vendor_event(uint16_t manufacturer, const void *data, uint8_t size);
3599
3600=== modified file 'obexd/plugins/pbap.c'
3601--- obexd/plugins/pbap.c 2015-09-15 13:42:52 +0000
3602+++ obexd/plugins/pbap.c 2015-11-23 18:34:05 +0000
3603@@ -193,6 +193,8 @@
3604 pbap->obj->apparam = g_obex_apparam_set_uint16(NULL, PHONEBOOKSIZE_TAG,
3605 phonebooksize);
3606
3607+ pbap->obj->firstpacket = TRUE;
3608+
3609 if (missed > 0) {
3610 DBG("missed %d", missed);
3611
3612@@ -826,14 +828,13 @@
3613 uint8_t *hi)
3614 {
3615 struct pbap_object *obj = object;
3616- struct pbap_session *pbap = obj->session;
3617
3618 if (!obj->buffer && !obj->apparam)
3619 return -EAGAIN;
3620
3621 *hi = G_OBEX_HDR_APPARAM;
3622
3623- if (pbap->params->maxlistcount == 0 || obj->firstpacket) {
3624+ if (obj->firstpacket) {
3625 obj->firstpacket = FALSE;
3626
3627 return g_obex_apparam_encode(obj->apparam, buf, mtu);
3628
3629=== modified file 'profiles/audio/a2dp.c'
3630--- profiles/audio/a2dp.c 2015-09-15 13:42:52 +0000
3631+++ profiles/audio/a2dp.c 2015-11-23 18:34:05 +0000
3632@@ -1457,7 +1457,7 @@
3633
3634 if (!avdtp_stream_set_transport(setup->stream,
3635 g_io_channel_unix_get_fd(io),
3636- omtu, imtu))
3637+ imtu, omtu))
3638 goto drop;
3639
3640 g_io_channel_set_close_on_unref(io, FALSE);
3641
3642=== modified file 'profiles/audio/avrcp.c'
3643--- profiles/audio/avrcp.c 2015-10-06 11:46:27 +0000
3644+++ profiles/audio/avrcp.c 2015-11-23 18:34:05 +0000
3645@@ -3030,7 +3030,7 @@
3646
3647 length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
3648
3649- avctp_send_vendordep_req(session->conn, AVC_CTYPE_STATUS,
3650+ avctp_send_vendordep_req(session->conn, AVC_CTYPE_CONTROL,
3651 AVC_SUBUNIT_PANEL, buf, length,
3652 NULL, session);
3653 }
3654@@ -3076,7 +3076,7 @@
3655
3656 length = AVRCP_HEADER_LENGTH + ntohs(pdu->params_len);
3657
3658- avctp_send_vendordep_req(session->conn, AVC_CTYPE_STATUS,
3659+ avctp_send_vendordep_req(session->conn, AVC_CTYPE_CONTROL,
3660 AVC_SUBUNIT_PANEL, buf, length,
3661 NULL, session);
3662 }
3663@@ -3191,6 +3191,15 @@
3664 .total_items = ct_get_total_numberofitems,
3665 };
3666
3667+static void set_ct_player(struct avrcp *session, struct avrcp_player *player)
3668+{
3669+ struct btd_service *service;
3670+
3671+ session->controller->player = player;
3672+ service = btd_device_get_service(session->dev, AVRCP_TARGET_UUID);
3673+ control_set_player(service, media_player_get_path(player->user_data));
3674+}
3675+
3676 static struct avrcp_player *create_ct_player(struct avrcp *session,
3677 uint16_t id)
3678 {
3679@@ -3212,7 +3221,7 @@
3680 player->destroy = (GDestroyNotify) media_player_destroy;
3681
3682 if (session->controller->player == NULL)
3683- session->controller->player = player;
3684+ set_ct_player(session, player);
3685
3686 session->controller->players = g_slist_prepend(
3687 session->controller->players,
3688@@ -3320,10 +3329,15 @@
3689
3690 for (l = player->sessions; l; l = l->next) {
3691 struct avrcp *session = l->data;
3692-
3693- session->controller->players = g_slist_remove(
3694- session->controller->players,
3695- player);
3696+ struct avrcp_data *controller = session->controller;
3697+
3698+ controller->players = g_slist_remove(controller->players,
3699+ player);
3700+
3701+ /* Check if current player is being removed */
3702+ if (controller->player == player)
3703+ set_ct_player(session, g_slist_nth_data(
3704+ controller->players, 0));
3705 }
3706
3707 player_destroy(player);
3708@@ -3374,9 +3388,6 @@
3709 i += len;
3710 }
3711
3712- if (g_slist_find(removed, session->controller->player))
3713- session->controller->player = NULL;
3714-
3715 g_slist_free_full(removed, player_remove);
3716
3717 return FALSE;
3718@@ -3501,7 +3512,7 @@
3719 }
3720
3721 player->uid_counter = get_be16(&pdu->params[3]);
3722- session->controller->player = player;
3723+ set_ct_player(session, player);
3724
3725 if (player->features != NULL)
3726 return;
3727
3728=== modified file 'profiles/audio/control.c'
3729--- profiles/audio/control.c 2015-09-15 13:42:52 +0000
3730+++ profiles/audio/control.c 2015-11-23 18:34:05 +0000
3731@@ -59,6 +59,7 @@
3732
3733 #include "avctp.h"
3734 #include "control.h"
3735+#include "player.h"
3736
3737 static GSList *devices = NULL;
3738
3739@@ -68,6 +69,7 @@
3740 struct btd_service *target;
3741 struct btd_service *remote;
3742 unsigned int avctp_id;
3743+ const char *player;
3744 };
3745
3746 static void state_changed(struct btd_device *dev, avctp_state_t old_state,
3747@@ -81,9 +83,12 @@
3748 switch (new_state) {
3749 case AVCTP_STATE_DISCONNECTED:
3750 control->session = NULL;
3751+ control->player = NULL;
3752
3753 g_dbus_emit_property_changed(conn, path,
3754 AUDIO_CONTROL_INTERFACE, "Connected");
3755+ g_dbus_emit_property_changed(conn, path,
3756+ AUDIO_CONTROL_INTERFACE, "Player");
3757
3758 break;
3759 case AVCTP_STATE_CONNECTING:
3760@@ -215,21 +220,46 @@
3761 return TRUE;
3762 }
3763
3764+static gboolean control_player_exists(const GDBusPropertyTable *property,
3765+ void *data)
3766+{
3767+ struct control *control = data;
3768+
3769+ return control->player != NULL;
3770+}
3771+
3772+static gboolean control_get_player(const GDBusPropertyTable *property,
3773+ DBusMessageIter *iter, void *data)
3774+{
3775+ struct control *control = data;
3776+
3777+ if (!control->player)
3778+ return FALSE;
3779+
3780+ dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH,
3781+ &control->player);
3782+
3783+ return TRUE;
3784+}
3785+
3786 static const GDBusMethodTable control_methods[] = {
3787- { GDBUS_METHOD("Play", NULL, NULL, control_play) },
3788- { GDBUS_METHOD("Pause", NULL, NULL, control_pause) },
3789- { GDBUS_METHOD("Stop", NULL, NULL, control_stop) },
3790- { GDBUS_METHOD("Next", NULL, NULL, control_next) },
3791- { GDBUS_METHOD("Previous", NULL, NULL, control_previous) },
3792- { GDBUS_METHOD("VolumeUp", NULL, NULL, control_volume_up) },
3793- { GDBUS_METHOD("VolumeDown", NULL, NULL, control_volume_down) },
3794- { GDBUS_METHOD("FastForward", NULL, NULL, control_fast_forward) },
3795- { GDBUS_METHOD("Rewind", NULL, NULL, control_rewind) },
3796+ { GDBUS_DEPRECATED_METHOD("Play", NULL, NULL, control_play) },
3797+ { GDBUS_DEPRECATED_METHOD("Pause", NULL, NULL, control_pause) },
3798+ { GDBUS_DEPRECATED_METHOD("Stop", NULL, NULL, control_stop) },
3799+ { GDBUS_DEPRECATED_METHOD("Next", NULL, NULL, control_next) },
3800+ { GDBUS_DEPRECATED_METHOD("Previous", NULL, NULL, control_previous) },
3801+ { GDBUS_DEPRECATED_METHOD("VolumeUp", NULL, NULL, control_volume_up) },
3802+ { GDBUS_DEPRECATED_METHOD("VolumeDown", NULL, NULL,
3803+ control_volume_down) },
3804+ { GDBUS_DEPRECATED_METHOD("FastForward", NULL, NULL,
3805+ control_fast_forward) },
3806+ { GDBUS_DEPRECATED_METHOD("Rewind", NULL, NULL, control_rewind) },
3807 { }
3808 };
3809
3810 static const GDBusPropertyTable control_properties[] = {
3811 { "Connected", "b", control_property_get_connected },
3812+ { "Player", "o", control_get_player, NULL, control_player_exists },
3813 { }
3814 };
3815
3816@@ -338,3 +368,22 @@
3817
3818 return 0;
3819 }
3820+
3821+int control_set_player(struct btd_service *service, const char *path)
3822+{
3823+ struct control *control = btd_service_get_user_data(service);
3824+
3825+ if (!control->session)
3826+ return -ENOTCONN;
3827+
3828+ if (g_strcmp0(control->player, path) == 0)
3829+ return -EALREADY;
3830+
3831+ control->player = path;
3832+
3833+ g_dbus_emit_property_changed(btd_get_dbus_connection(),
3834+ device_get_path(control->dev),
3835+ AUDIO_CONTROL_INTERFACE, "Player");
3836+
3837+ return 0;
3838+}
3839
3840=== modified file 'profiles/audio/control.h'
3841--- profiles/audio/control.h 2015-09-15 13:42:52 +0000
3842+++ profiles/audio/control.h 2015-11-23 18:34:05 +0000
3843@@ -32,3 +32,5 @@
3844
3845 int control_connect(struct btd_service *service);
3846 int control_disconnect(struct btd_service *service);
3847+
3848+int control_set_player(struct btd_service *service, const char *path);
3849
3850=== modified file 'profiles/audio/player.c'
3851--- profiles/audio/player.c 2015-09-15 13:42:52 +0000
3852+++ profiles/audio/player.c 2015-11-23 18:34:05 +0000
3853@@ -1193,6 +1193,11 @@
3854 return mp;
3855 }
3856
3857+const char *media_player_get_path(struct media_player *mp)
3858+{
3859+ return mp->path;
3860+}
3861+
3862 void media_player_set_duration(struct media_player *mp, uint32_t duration)
3863 {
3864 char *value, *curval;
3865
3866=== modified file 'profiles/audio/player.h'
3867--- profiles/audio/player.h 2015-09-15 13:42:52 +0000
3868+++ profiles/audio/player.h 2015-11-23 18:34:05 +0000
3869@@ -70,6 +70,7 @@
3870
3871 struct media_player *media_player_controller_create(const char *path,
3872 uint16_t id);
3873+const char *media_player_get_path(struct media_player *mp);
3874 void media_player_destroy(struct media_player *mp);
3875 void media_player_set_duration(struct media_player *mp, uint32_t duration);
3876 void media_player_set_position(struct media_player *mp, uint32_t position);
3877
3878=== modified file 'profiles/deviceinfo/deviceinfo.c'
3879--- profiles/deviceinfo/deviceinfo.c 2015-09-15 13:42:52 +0000
3880+++ profiles/deviceinfo/deviceinfo.c 2015-11-23 18:34:05 +0000
3881@@ -3,6 +3,7 @@
3882 * BlueZ - Bluetooth protocol stack for Linux
3883 *
3884 * Copyright (C) 2012 Texas Instruments, Inc.
3885+ * Copyright (C) 2015 Google Inc.
3886 *
3887 * This program is free software; you can redistribute it and/or modify
3888 * it under the terms of the GNU General Public License as published by
3889@@ -38,161 +39,113 @@
3890 #include "src/device.h"
3891 #include "src/profile.h"
3892 #include "src/service.h"
3893+#include "attrib/gattrib.h"
3894 #include "src/shared/util.h"
3895-#include "attrib/gattrib.h"
3896-#include "src/attio.h"
3897+#include "src/shared/queue.h"
3898+#include "src/shared/gatt-db.h"
3899+#include "src/shared/gatt-client.h"
3900 #include "attrib/att.h"
3901-#include "attrib/gatt.h"
3902 #include "src/log.h"
3903
3904 #define PNP_ID_SIZE 7
3905
3906-struct deviceinfo {
3907- struct btd_device *dev; /* Device reference */
3908- GAttrib *attrib; /* GATT connection */
3909- guint attioid; /* Att watcher id */
3910- struct att_range *svc_range; /* DeviceInfo range */
3911- GSList *chars; /* Characteristics */
3912-};
3913-
3914-struct characteristic {
3915- struct gatt_char attr; /* Characteristic */
3916- struct deviceinfo *d; /* deviceinfo where the char belongs */
3917-};
3918-
3919-static void deviceinfo_driver_remove(struct btd_service *service)
3920-{
3921- struct deviceinfo *d = btd_service_get_user_data(service);
3922-
3923- if (d->attioid > 0)
3924- btd_device_remove_attio_callback(d->dev, d->attioid);
3925-
3926- if (d->attrib != NULL)
3927- g_attrib_unref(d->attrib);
3928-
3929- g_slist_free_full(d->chars, g_free);
3930-
3931- btd_device_unref(d->dev);
3932- g_free(d->svc_range);
3933- g_free(d);
3934-}
3935-
3936-static void read_pnpid_cb(guint8 status, const guint8 *pdu, guint16 len,
3937- gpointer user_data)
3938-{
3939- struct characteristic *ch = user_data;
3940- uint8_t value[PNP_ID_SIZE];
3941- ssize_t vlen;
3942-
3943- if (status != 0) {
3944- error("Error reading PNP_ID value: %s", att_ecode2str(status));
3945- return;
3946- }
3947-
3948- vlen = dec_read_resp(pdu, len, value, sizeof(value));
3949- if (vlen < 0) {
3950- error("Error reading PNP_ID: Protocol error");
3951- return;
3952- }
3953-
3954- if (vlen < 7) {
3955+static void read_pnpid_cb(bool success, uint8_t att_ecode, const uint8_t *value,
3956+ uint16_t length, void *user_data)
3957+{
3958+ struct btd_device *device = user_data;
3959+
3960+ if (!success) {
3961+ error("Error reading PNP_ID value: %s",
3962+ att_ecode2str(att_ecode));
3963+ return;
3964+ }
3965+
3966+ if (length < PNP_ID_SIZE) {
3967 error("Error reading PNP_ID: Invalid pdu length received");
3968 return;
3969 }
3970
3971- btd_device_set_pnpid(ch->d->dev, value[0], get_le16(&value[1]),
3972+ btd_device_set_pnpid(device, value[0], get_le16(&value[1]),
3973 get_le16(&value[3]), get_le16(&value[5]));
3974 }
3975
3976-static void process_deviceinfo_char(struct characteristic *ch)
3977+static void handle_pnpid(struct btd_device *device, uint16_t value_handle)
3978 {
3979- if (g_strcmp0(ch->attr.uuid, PNPID_UUID) == 0)
3980- gatt_read_char(ch->d->attrib, ch->attr.value_handle,
3981- read_pnpid_cb, ch);
3982+ struct bt_gatt_client *client = btd_device_get_gatt_client(device);
3983+
3984+ if (!bt_gatt_client_read_value(client, value_handle,
3985+ read_pnpid_cb, device, NULL))
3986+ DBG("Failed to send request to read pnpid");
3987 }
3988
3989-static void configure_deviceinfo_cb(uint8_t status, GSList *characteristics,
3990+static void handle_characteristic(struct gatt_db_attribute *attr,
3991 void *user_data)
3992 {
3993- struct deviceinfo *d = user_data;
3994- GSList *l;
3995-
3996- if (status != 0) {
3997- error("Discover deviceinfo characteristics: %s",
3998- att_ecode2str(status));
3999+ struct btd_device *device = user_data;
4000+ uint16_t value_handle;
4001+ bt_uuid_t uuid, pnpid_uuid;
4002+
4003+ bt_string_to_uuid(&pnpid_uuid, PNPID_UUID);
4004+
4005+ if (!gatt_db_attribute_get_char_data(attr, NULL, &value_handle, NULL,
4006+ &uuid)) {
4007+ error("Failed to obtain characteristic data");
4008 return;
4009 }
4010
4011- for (l = characteristics; l; l = l->next) {
4012- struct gatt_char *c = l->data;
4013- struct characteristic *ch;
4014-
4015- ch = g_new0(struct characteristic, 1);
4016- ch->attr.handle = c->handle;
4017- ch->attr.properties = c->properties;
4018- ch->attr.value_handle = c->value_handle;
4019- memcpy(ch->attr.uuid, c->uuid, MAX_LEN_UUID_STR + 1);
4020- ch->d = d;
4021-
4022- d->chars = g_slist_append(d->chars, ch);
4023-
4024- process_deviceinfo_char(ch);
4025+ if (bt_uuid_cmp(&pnpid_uuid, &uuid) == 0)
4026+ handle_pnpid(device, value_handle);
4027+ else {
4028+ char uuid_str[MAX_LEN_UUID_STR];
4029+
4030+ bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
4031+ DBG("Unsupported characteristic: %s", uuid_str);
4032 }
4033 }
4034-static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
4035-{
4036- struct deviceinfo *d = user_data;
4037-
4038- d->attrib = g_attrib_ref(attrib);
4039-
4040- gatt_discover_char(d->attrib, d->svc_range->start, d->svc_range->end,
4041- NULL, configure_deviceinfo_cb, d);
4042-}
4043-
4044-static void attio_disconnected_cb(gpointer user_data)
4045-{
4046- struct deviceinfo *d = user_data;
4047-
4048- g_attrib_unref(d->attrib);
4049- d->attrib = NULL;
4050-}
4051-
4052-static int deviceinfo_register(struct btd_service *service,
4053- struct gatt_primary *prim)
4054-{
4055- struct btd_device *device = btd_service_get_device(service);
4056- struct deviceinfo *d;
4057-
4058- d = g_new0(struct deviceinfo, 1);
4059- d->dev = btd_device_ref(device);
4060- d->svc_range = g_new0(struct att_range, 1);
4061- d->svc_range->start = prim->range.start;
4062- d->svc_range->end = prim->range.end;
4063-
4064- btd_service_set_user_data(service, d);
4065-
4066- d->attioid = btd_device_add_attio_callback(device, attio_connected_cb,
4067- attio_disconnected_cb, d);
4068- return 0;
4069+
4070+static void foreach_deviceinfo_service(struct gatt_db_attribute *attr,
4071+ void *user_data)
4072+{
4073+ struct btd_device *device = user_data;
4074+
4075+ gatt_db_service_foreach_char(attr, handle_characteristic, device);
4076 }
4077
4078 static int deviceinfo_driver_probe(struct btd_service *service)
4079 {
4080+ return 0;
4081+}
4082+
4083+static void deviceinfo_driver_remove(struct btd_service *service)
4084+{
4085+}
4086+
4087+
4088+static int deviceinfo_driver_accept(struct btd_service *service)
4089+{
4090 struct btd_device *device = btd_service_get_device(service);
4091- struct gatt_primary *prim;
4092-
4093- prim = btd_device_get_primary(device, DEVICE_INFORMATION_UUID);
4094- if (prim == NULL)
4095- return -EINVAL;
4096-
4097- return deviceinfo_register(service, prim);
4098+ struct gatt_db *db = btd_device_get_gatt_db(device);
4099+ char addr[18];
4100+ bt_uuid_t deviceinfo_uuid;
4101+
4102+ ba2str(device_get_address(device), addr);
4103+ DBG("deviceinfo profile accept (%s)", addr);
4104+
4105+ /* Handle the device info service */
4106+ bt_string_to_uuid(&deviceinfo_uuid, DEVICE_INFORMATION_UUID);
4107+ gatt_db_foreach_service(db, &deviceinfo_uuid,
4108+ foreach_deviceinfo_service, device);
4109+
4110+ return 0;
4111 }
4112
4113 static struct btd_profile deviceinfo_profile = {
4114 .name = "deviceinfo",
4115 .remote_uuid = DEVICE_INFORMATION_UUID,
4116+ .external = true,
4117 .device_probe = deviceinfo_driver_probe,
4118- .device_remove = deviceinfo_driver_remove
4119+ .device_remove = deviceinfo_driver_remove,
4120+ .accept = deviceinfo_driver_accept,
4121 };
4122
4123 static int deviceinfo_init(void)
4124
4125=== modified file 'profiles/gap/gas.c'
4126--- profiles/gap/gas.c 2015-09-15 13:42:52 +0000
4127+++ profiles/gap/gas.c 2015-11-23 18:34:05 +0000
4128@@ -53,7 +53,6 @@
4129 struct gas {
4130 struct btd_device *device;
4131 struct gatt_db *db;
4132- unsigned int db_id;
4133 struct bt_gatt_client *client;
4134 struct gatt_db_attribute *attr;
4135 };
4136@@ -62,7 +61,6 @@
4137
4138 static void gas_free(struct gas *gas)
4139 {
4140- gatt_db_unregister(gas->db, gas->db_id);
4141 gatt_db_unref(gas->db);
4142 bt_gatt_client_unref(gas->client);
4143 btd_device_unref(gas->device);
4144@@ -269,43 +267,6 @@
4145 handle_gap_service(gas);
4146 }
4147
4148-static void service_added(struct gatt_db_attribute *attr, void *user_data)
4149-{
4150- struct gas *gas = user_data;
4151- bt_uuid_t uuid, gap_uuid;
4152-
4153- if (!bt_gatt_client_is_ready(gas->client))
4154- return;
4155-
4156- gatt_db_attribute_get_service_uuid(attr, &uuid);
4157- bt_uuid16_create(&gap_uuid, GAP_UUID16);
4158-
4159- if (bt_uuid_cmp(&uuid, &gap_uuid))
4160- return;
4161-
4162- if (gas->attr) {
4163- error("More than one GAP service added to device");
4164- return;
4165- }
4166-
4167- DBG("GAP service added");
4168-
4169- gas->attr = attr;
4170- handle_gap_service(gas);
4171-}
4172-
4173-static void service_removed(struct gatt_db_attribute *attr, void *user_data)
4174-{
4175- struct gas *gas = user_data;
4176-
4177- if (gas->attr != attr)
4178- return;
4179-
4180- DBG("GAP service removed");
4181-
4182- gas->attr = NULL;
4183-}
4184-
4185 static int gap_driver_accept(struct btd_service *service)
4186 {
4187 struct btd_device *device = btd_service_get_device(service);
4188@@ -329,14 +290,11 @@
4189
4190 /* Clean-up any old client/db and acquire the new ones */
4191 gas->attr = NULL;
4192- gatt_db_unregister(gas->db, gas->db_id);
4193 gatt_db_unref(gas->db);
4194 bt_gatt_client_unref(gas->client);
4195
4196 gas->db = gatt_db_ref(db);
4197 gas->client = bt_gatt_client_ref(client);
4198- gas->db_id = gatt_db_register(db, service_added, service_removed, gas,
4199- NULL);
4200
4201 /* Handle the GAP services */
4202 bt_uuid16_create(&gap_uuid, GAP_UUID16);
4203
4204=== modified file 'profiles/scanparam/scan.c'
4205--- profiles/scanparam/scan.c 2015-09-15 13:42:52 +0000
4206+++ profiles/scanparam/scan.c 2015-11-23 18:34:05 +0000
4207@@ -40,10 +40,11 @@
4208 #include "src/profile.h"
4209 #include "src/service.h"
4210 #include "src/shared/util.h"
4211+#include "src/shared/att.h"
4212+#include "src/shared/queue.h"
4213+#include "src/shared/gatt-db.h"
4214+#include "src/shared/gatt-client.h"
4215 #include "attrib/att.h"
4216-#include "attrib/gattrib.h"
4217-#include "attrib/gatt.h"
4218-#include "src/attio.h"
4219
4220 #define SCAN_INTERVAL_WIN_UUID 0x2A4F
4221 #define SCAN_REFRESH_UUID 0x2A31
4222@@ -54,210 +55,217 @@
4223
4224 struct scan {
4225 struct btd_device *device;
4226- GAttrib *attrib;
4227- struct att_range range;
4228- guint attioid;
4229- uint16_t interval;
4230- uint16_t window;
4231+ struct gatt_db *db;
4232+ struct bt_gatt_client *client;
4233+ struct gatt_db_attribute *attr;
4234 uint16_t iwhandle;
4235- uint16_t refresh_handle;
4236 guint refresh_cb_id;
4237 };
4238
4239-static void write_scan_params(GAttrib *attrib, uint16_t handle)
4240+static GSList *devices;
4241+
4242+static void scan_free(struct scan *scan)
4243+{
4244+ bt_gatt_client_unregister_notify(scan->client, scan->refresh_cb_id);
4245+ gatt_db_unref(scan->db);
4246+ bt_gatt_client_unref(scan->client);
4247+ btd_device_unref(scan->device);
4248+ g_free(scan);
4249+}
4250+
4251+static int cmp_device(gconstpointer a, gconstpointer b)
4252+{
4253+ const struct scan *scan = a;
4254+ const struct btd_device *device = b;
4255+
4256+ return scan->device == device ? 0 : -1;
4257+}
4258+
4259+static void write_scan_params(struct scan *scan)
4260 {
4261 uint8_t value[4];
4262
4263 put_le16(SCAN_INTERVAL, &value[0]);
4264 put_le16(SCAN_WINDOW, &value[2]);
4265
4266- gatt_write_cmd(attrib, handle, value, sizeof(value), NULL, NULL);
4267-}
4268-
4269-static void refresh_value_cb(const uint8_t *pdu, uint16_t len,
4270- gpointer user_data)
4271-{
4272- struct scan *scan = user_data;
4273-
4274- DBG("Server requires refresh: %d", pdu[3]);
4275-
4276- if (pdu[3] == SERVER_REQUIRES_REFRESH)
4277- write_scan_params(scan->attrib, scan->iwhandle);
4278-}
4279-
4280-static void ccc_written_cb(guint8 status, const guint8 *pdu,
4281- guint16 plen, gpointer user_data)
4282-{
4283- struct scan *scan = user_data;
4284-
4285- if (status != 0) {
4286- error("Write Scan Refresh CCC failed: %s",
4287- att_ecode2str(status));
4288+ bt_gatt_client_write_without_response(scan->client, scan->iwhandle,
4289+ false, value, sizeof(value));
4290+}
4291+
4292+static void refresh_value_cb(uint16_t value_handle, const uint8_t *value,
4293+ uint16_t length, void *user_data)
4294+{
4295+ struct scan *scan = user_data;
4296+
4297+ DBG("Server requires refresh: %d", value[3]);
4298+
4299+ if (value[3] == SERVER_REQUIRES_REFRESH)
4300+ write_scan_params(scan);
4301+}
4302+
4303+static void refresh_ccc_written_cb(uint16_t att_ecode, void *user_data)
4304+{
4305+ if (att_ecode != 0) {
4306+ error("Scan Refresh: notifications not enabled %s",
4307+ att_ecode2str(att_ecode));
4308 return;
4309 }
4310
4311 DBG("Scan Refresh: notification enabled");
4312-
4313- scan->refresh_cb_id = g_attrib_register(scan->attrib,
4314- ATT_OP_HANDLE_NOTIFY, scan->refresh_handle,
4315- refresh_value_cb, scan, NULL);
4316-}
4317-
4318-static void discover_descriptor_cb(uint8_t status, GSList *descs,
4319- void *user_data)
4320-{
4321- struct scan *scan = user_data;
4322- struct gatt_desc *desc;
4323- uint8_t value[2];
4324-
4325- if (status != 0) {
4326- error("Discover descriptors failed: %s", att_ecode2str(status));
4327- return;
4328- }
4329-
4330- /* There will be only one descriptor on list and it will be CCC */
4331- desc = descs->data;
4332-
4333- put_le16(GATT_CLIENT_CHARAC_CFG_NOTIF_BIT, value);
4334- gatt_write_char(scan->attrib, desc->handle, value, sizeof(value),
4335- ccc_written_cb, user_data);
4336-}
4337-
4338-static void refresh_discovered_cb(uint8_t status, GSList *chars,
4339- void *user_data)
4340-{
4341- struct scan *scan = user_data;
4342- struct gatt_char *chr;
4343- uint16_t start, end;
4344- bt_uuid_t uuid;
4345-
4346- if (status) {
4347- error("Scan Refresh %s", att_ecode2str(status));
4348- return;
4349- }
4350-
4351- if (!chars) {
4352- DBG("Scan Refresh not supported");
4353- return;
4354- }
4355-
4356- chr = chars->data;
4357-
4358- DBG("Scan Refresh handle: 0x%04x", chr->value_handle);
4359-
4360- start = chr->value_handle + 1;
4361- end = scan->range.end;
4362-
4363- if (start > end)
4364- return;
4365-
4366- scan->refresh_handle = chr->value_handle;
4367-
4368- bt_uuid16_create(&uuid, GATT_CLIENT_CHARAC_CFG_UUID);
4369-
4370- gatt_discover_desc(scan->attrib, start, end, &uuid,
4371- discover_descriptor_cb, user_data);
4372-}
4373-
4374-static void iwin_discovered_cb(uint8_t status, GSList *chars, void *user_data)
4375-{
4376- struct scan *scan = user_data;
4377- struct gatt_char *chr;
4378-
4379- if (status) {
4380- error("Discover Scan Interval Window: %s",
4381- att_ecode2str(status));
4382- return;
4383- }
4384-
4385- chr = chars->data;
4386- scan->iwhandle = chr->value_handle;
4387+}
4388+
4389+static void handle_refresh(struct scan *scan, uint16_t value_handle)
4390+{
4391+ DBG("Scan Refresh handle: 0x%04x", value_handle);
4392+
4393+ scan->refresh_cb_id = bt_gatt_client_register_notify(scan->client,
4394+ value_handle, refresh_ccc_written_cb,
4395+ refresh_value_cb, scan, NULL);
4396+}
4397+
4398+static void handle_iwin(struct scan *scan, uint16_t value_handle)
4399+{
4400+ scan->iwhandle = value_handle;
4401
4402 DBG("Scan Interval Window handle: 0x%04x", scan->iwhandle);
4403
4404- write_scan_params(scan->attrib, scan->iwhandle);
4405-}
4406-
4407-static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
4408-{
4409- struct scan *scan = user_data;
4410- bt_uuid_t iwin_uuid, refresh_uuid;
4411-
4412- scan->attrib = g_attrib_ref(attrib);
4413-
4414- if (scan->iwhandle) {
4415- write_scan_params(scan->attrib, scan->iwhandle);
4416- return;
4417- }
4418-
4419- bt_uuid16_create(&iwin_uuid, SCAN_INTERVAL_WIN_UUID);
4420- bt_uuid16_create(&refresh_uuid, SCAN_REFRESH_UUID);
4421-
4422- gatt_discover_char(scan->attrib, scan->range.start, scan->range.end,
4423- &iwin_uuid, iwin_discovered_cb, scan);
4424-
4425- gatt_discover_char(scan->attrib, scan->range.start, scan->range.end,
4426- &refresh_uuid, refresh_discovered_cb, scan);
4427-}
4428-
4429-static void attio_disconnected_cb(gpointer user_data)
4430-{
4431- struct scan *scan = user_data;
4432-
4433- g_attrib_unref(scan->attrib);
4434- scan->attrib = NULL;
4435-}
4436-
4437-static int scan_register(struct btd_service *service, struct gatt_primary *prim)
4438-{
4439- struct btd_device *device = btd_service_get_device(service);
4440- struct scan *scan;
4441+ write_scan_params(scan);
4442+}
4443+
4444+static void handle_characteristic(struct gatt_db_attribute *attr,
4445+ void *user_data)
4446+{
4447+ struct scan *scan = user_data;
4448+ uint16_t value_handle;
4449+ bt_uuid_t uuid, scan_interval_wind_uuid, scan_refresh_uuid;
4450+
4451+ if (!gatt_db_attribute_get_char_data(attr, NULL, &value_handle, NULL,
4452+ &uuid)) {
4453+ error("Failed to obtain characteristic data");
4454+ return;
4455+ }
4456+
4457+ bt_uuid16_create(&scan_interval_wind_uuid, SCAN_INTERVAL_WIN_UUID);
4458+ bt_uuid16_create(&scan_refresh_uuid, SCAN_REFRESH_UUID);
4459+
4460+ if (bt_uuid_cmp(&scan_interval_wind_uuid, &uuid) == 0)
4461+ handle_iwin(scan, value_handle);
4462+ else if (bt_uuid_cmp(&scan_refresh_uuid, &uuid) == 0)
4463+ handle_refresh(scan, value_handle);
4464+ else {
4465+ char uuid_str[MAX_LEN_UUID_STR];
4466+
4467+ bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
4468+ DBG("Unsupported characteristic: %s", uuid_str);
4469+ }
4470+}
4471+
4472+static void foreach_scan_param_service(struct gatt_db_attribute *attr,
4473+ void *user_data)
4474+{
4475+ struct scan *scan = user_data;
4476+
4477+ if (scan->attr) {
4478+ error("More than one scan params service exists for this "
4479+ "device");
4480+ return;
4481+ }
4482+
4483+ scan->attr = attr;
4484+ gatt_db_service_foreach_char(scan->attr, handle_characteristic, scan);
4485+}
4486+
4487+static int scan_param_accept(struct btd_service *service)
4488+{
4489+ struct btd_device *device = btd_service_get_device(service);
4490+ struct gatt_db *db = btd_device_get_gatt_db(device);
4491+ struct bt_gatt_client *client = btd_device_get_gatt_client(device);
4492+ bt_uuid_t scan_parameters_uuid;
4493+ struct scan *scan;
4494+ GSList *l;
4495+ char addr[18];
4496+
4497+ ba2str(device_get_address(device), addr);
4498+ DBG("Scan Parameters Client Driver profile accept (%s)", addr);
4499+
4500+ l = g_slist_find_custom(devices, device, cmp_device);
4501+ if (!l) {
4502+ error("Scan Parameters service not handled by profile");
4503+ return -1;
4504+ }
4505+
4506+ scan = l->data;
4507+
4508+ /* Clean-up any old client/db and acquire the new ones */
4509+ scan->attr = NULL;
4510+ gatt_db_unref(scan->db);
4511+ bt_gatt_client_unref(scan->client);
4512+
4513+
4514+ scan->db = gatt_db_ref(db);
4515+ scan->client = bt_gatt_client_ref(client);
4516+
4517+ bt_string_to_uuid(&scan_parameters_uuid, SCAN_PARAMETERS_UUID);
4518+ gatt_db_foreach_service(db, &scan_parameters_uuid,
4519+ foreach_scan_param_service, scan);
4520+
4521+ return 0;
4522+}
4523+
4524+static void scan_param_remove(struct btd_service *service)
4525+{
4526+ struct btd_device *device = btd_service_get_device(service);
4527+ struct scan *scan;
4528+ GSList *l;
4529+ char addr[18];
4530+
4531+ ba2str(device_get_address(device), addr);
4532+ DBG("GAP profile remove (%s)", addr);
4533+
4534+ l = g_slist_find_custom(devices, device, cmp_device);
4535+ if (!l) {
4536+ error("GAP service not handled by profile");
4537+ return;
4538+ }
4539+
4540+ scan = l->data;
4541+
4542+ devices = g_slist_remove(devices, scan);
4543+ scan_free(scan);
4544+}
4545+
4546+static int scan_param_probe(struct btd_service *service)
4547+{
4548+ struct btd_device *device = btd_service_get_device(service);
4549+ struct scan *scan;
4550+ GSList *l;
4551+ char addr[18];
4552+
4553+ ba2str(device_get_address(device), addr);
4554+ DBG("Scan Parameters Client Driver profile probe (%s)", addr);
4555+
4556+ /* Ignore, if we were probed for this device already */
4557+ l = g_slist_find_custom(devices, device, cmp_device);
4558+ if (l) {
4559+ error("Profile probed twice for the same device!");
4560+ return -1;
4561+ }
4562
4563 scan = g_new0(struct scan, 1);
4564+ if (!scan)
4565+ return -1;
4566+
4567 scan->device = btd_device_ref(device);
4568- scan->range = prim->range;
4569- scan->attioid = btd_device_add_attio_callback(device,
4570- attio_connected_cb,
4571- attio_disconnected_cb,
4572- scan);
4573-
4574- btd_service_set_user_data(service, scan);
4575-
4576+ devices = g_slist_append(devices, scan);
4577 return 0;
4578 }
4579
4580-static void scan_param_remove(struct btd_service *service)
4581-{
4582- struct scan *scan = btd_service_get_user_data(service);
4583-
4584- if (scan->attrib != NULL && scan->refresh_cb_id > 0)
4585- g_attrib_unregister(scan->attrib, scan->refresh_cb_id);
4586-
4587- btd_device_remove_attio_callback(scan->device, scan->attioid);
4588- btd_device_unref(scan->device);
4589- g_attrib_unref(scan->attrib);
4590- g_free(scan);
4591-}
4592-
4593-static int scan_param_probe(struct btd_service *service)
4594-{
4595- struct btd_device *device = btd_service_get_device(service);
4596- struct gatt_primary *prim;
4597-
4598- DBG("Probing Scan Parameters");
4599-
4600- prim = btd_device_get_primary(device, SCAN_PARAMETERS_UUID);
4601- if (!prim)
4602- return -EINVAL;
4603-
4604- return scan_register(service, prim);
4605-}
4606-
4607 static struct btd_profile scan_profile = {
4608 .name = "Scan Parameters Client Driver",
4609 .remote_uuid = SCAN_PARAMETERS_UUID,
4610 .device_probe = scan_param_probe,
4611 .device_remove = scan_param_remove,
4612+ .accept = scan_param_accept,
4613 };
4614
4615 static int scan_param_init(void)
4616
4617=== modified file 'src/advertising.c'
4618--- src/advertising.c 2015-09-15 13:42:52 +0000
4619+++ src/advertising.c 2015-11-23 18:34:05 +0000
4620@@ -77,10 +77,10 @@
4621 const struct advertisement *ad = a;
4622 const struct dbus_obj_match *match = b;
4623
4624- if (match->owner && !g_strcmp0(ad->owner, match->owner))
4625+ if (match->owner && g_strcmp0(ad->owner, match->owner))
4626 return false;
4627
4628- if (match->path && !g_strcmp0(ad->path, match->path))
4629+ if (match->path && g_strcmp0(ad->path, match->path))
4630 return false;
4631
4632 return true;
4633
4634=== modified file 'src/bluetooth.service.in'
4635--- src/bluetooth.service.in 2015-09-15 13:42:52 +0000
4636+++ src/bluetooth.service.in 2015-11-23 18:34:05 +0000
4637@@ -1,6 +1,7 @@
4638 [Unit]
4639 Description=Bluetooth service
4640 Documentation=man:bluetoothd(8)
4641+ConditionPathIsDirectory=/sys/class/bluetooth
4642
4643 [Service]
4644 Type=dbus
4645
4646=== modified file 'src/device.c'
4647--- src/device.c 2015-10-06 11:46:27 +0000
4648+++ src/device.c 2015-11-23 18:34:05 +0000
4649@@ -626,6 +626,9 @@
4650 g_slist_free_full(device->attios_offline, g_free);
4651 g_slist_free_full(device->svc_callbacks, svc_dev_remove);
4652
4653+ /* Reset callbacks since the device is going to be freed */
4654+ gatt_db_register(device->db, NULL, NULL, NULL, NULL);
4655+
4656 attio_cleanup(device);
4657
4658 gatt_db_unref(device->db);
4659@@ -1355,6 +1358,12 @@
4660 if (device->browse)
4661 browse_request_cancel(device->browse);
4662
4663+ if (device->att_io) {
4664+ g_io_channel_shutdown(device->att_io, FALSE, NULL);
4665+ g_io_channel_unref(device->att_io);
4666+ device->att_io = NULL;
4667+ }
4668+
4669 if (device->connect) {
4670 DBusMessage *reply = btd_error_failed(device->connect,
4671 "Cancelled");
4672@@ -2006,7 +2015,7 @@
4673
4674 sprintf(handle, "%04hx", handle_num);
4675 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
4676- sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hx:%s", value_handle,
4677+ sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:%s", value_handle,
4678 properties, uuid_str);
4679 g_key_file_set_string(key_file, "Attributes", handle, value);
4680
4681@@ -3230,7 +3239,7 @@
4682 return true;
4683 }
4684
4685-static void probe_gatt_profile(struct gatt_db_attribute *attr, void *user_data)
4686+static void add_gatt_service(struct gatt_db_attribute *attr, void *user_data)
4687 {
4688 struct btd_device *device = user_data;
4689 struct btd_service *service;
4690@@ -3242,6 +3251,11 @@
4691 gatt_db_attribute_get_service_uuid(attr, &uuid);
4692 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
4693
4694+ /* Check if service was already probed */
4695+ l = find_service_with_uuid(device->services, uuid_str);
4696+ if (l)
4697+ goto done;
4698+
4699 /* Add UUID and probe service */
4700 btd_device_add_uuid(device, uuid_str);
4701
4702@@ -3250,21 +3264,24 @@
4703 if (!l)
4704 return;
4705
4706+done:
4707 /* Mark service as active to skip discovering it again */
4708 gatt_db_service_set_active(attr, true);
4709
4710 service = l->data;
4711 profile = btd_service_get_profile(service);
4712
4713- /* Don't claim attributes of external profiles */
4714- if (profile->external)
4715- return;
4716+ /* Claim attributes of internal profiles */
4717+ if (!profile->external) {
4718+ /* Mark the service as claimed by the existing profile. */
4719+ gatt_db_service_set_claimed(attr, true);
4720+ }
4721
4722- /* Mark the service as claimed by the existing profile. */
4723- gatt_db_service_set_claimed(attr, true);
4724+ /* Notify driver about the new connection */
4725+ service_accept(service);
4726 }
4727
4728-static void device_probe_gatt_profiles(struct btd_device *device)
4729+static void device_add_gatt_services(struct btd_device *device)
4730 {
4731 char addr[18];
4732
4733@@ -3275,7 +3292,7 @@
4734 return;
4735 }
4736
4737- gatt_db_foreach_service(device->db, NULL, probe_gatt_profile, device);
4738+ gatt_db_foreach_service(device->db, NULL, add_gatt_service, device);
4739 }
4740
4741 static void device_accept_gatt_profiles(struct btd_device *device)
4742@@ -3286,7 +3303,7 @@
4743 service_accept(l->data);
4744 }
4745
4746-static void device_remove_gatt_profile(struct btd_device *device,
4747+static void device_remove_gatt_service(struct btd_device *device,
4748 struct gatt_db_attribute *attr)
4749 {
4750 struct btd_service *service;
4751@@ -3323,16 +3340,12 @@
4752 {
4753 struct btd_device *device = user_data;
4754 GSList *new_service = NULL;
4755- bt_uuid_t uuid;
4756- char uuid_str[MAX_LEN_UUID_STR];
4757 uint16_t start, end;
4758- GSList *l;
4759
4760 if (!bt_gatt_client_is_ready(device->client))
4761 return;
4762
4763- gatt_db_attribute_get_service_data(attr, &start, &end, NULL, &uuid);
4764- bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
4765+ gatt_db_attribute_get_service_data(attr, &start, &end, NULL, NULL);
4766
4767 DBG("start: 0x%04x, end: 0x%04x", start, end);
4768
4769@@ -3344,21 +3357,9 @@
4770 if (!new_service)
4771 return;
4772
4773- l = find_service_with_uuid(device->services, uuid_str);
4774-
4775 device_register_primaries(device, new_service, -1);
4776
4777- /*
4778- * If the profile was probed for the first time then call accept on
4779- * the service.
4780- */
4781- if (!l) {
4782- l = find_service_with_uuid(device->services, uuid_str);
4783- if (l)
4784- service_accept(l->data);
4785- }
4786-
4787- btd_device_add_uuid(device, uuid_str);
4788+ add_gatt_service(attr, device);
4789
4790 btd_gatt_client_service_added(device->client_dbus, attr);
4791
4792@@ -3437,7 +3438,7 @@
4793 * remove it anyway.
4794 */
4795 if (device->client || device->temporary == TRUE)
4796- device_remove_gatt_profile(device, attr);
4797+ device_remove_gatt_service(device, attr);
4798
4799 g_free(l->data);
4800 device->uuids = g_slist_delete_link(device->uuids, l);
4801@@ -4518,7 +4519,7 @@
4802
4803 device_register_primaries(device, services, -1);
4804
4805- device_probe_gatt_profiles(device);
4806+ device_add_gatt_services(device);
4807
4808 device_svc_resolved(device, device->bdaddr_type, 0);
4809 }
4810@@ -4539,8 +4540,6 @@
4811
4812 register_gatt_services(device);
4813
4814- device_accept_gatt_profiles(device);
4815-
4816 btd_gatt_client_ready(device->client_dbus);
4817
4818 /*
4819@@ -4585,6 +4584,12 @@
4820 /* Notify attio so it can react to notifications */
4821 g_slist_foreach(device->attios, attio_connected, device->attrib);
4822
4823+ /*
4824+ * Notify notify existing service about the new connection so they can
4825+ * react to notifications while discovering services
4826+ */
4827+ device_accept_gatt_profiles(device);
4828+
4829 if (!bt_gatt_client_set_ready_handler(device->client,
4830 gatt_client_ready_cb,
4831 device, NULL)) {
4832@@ -4779,7 +4784,7 @@
4833 }
4834
4835 if (device->connect) {
4836- if (!device->le_state.svc_resolved)
4837+ if (!device->le_state.svc_resolved && !err)
4838 device_browse_gatt(device, NULL);
4839
4840 if (err < 0)
4841
4842=== modified file 'src/gatt-client.c'
4843--- src/gatt-client.c 2015-10-06 11:46:27 +0000
4844+++ src/gatt-client.c 2015-11-23 18:34:05 +0000
4845@@ -1527,7 +1527,7 @@
4846 service_properties,
4847 service, service_free)) {
4848 error("Unable to register GATT service with handle 0x%04x for "
4849- "device %s:",
4850+ "device %s",
4851 service->start_handle,
4852 client->devaddr);
4853 service_free(service);
4854
4855=== modified file 'src/profile.c'
4856--- src/profile.c 2015-09-15 13:42:52 +0000
4857+++ src/profile.c 2015-11-23 18:34:05 +0000
4858@@ -742,10 +742,14 @@
4859 for (l = ext_profiles; l != NULL; l = g_slist_next(l)) {
4860 struct ext_profile *ext = l->data;
4861
4862- if (!g_str_equal(ext->owner, owner))
4863+ /*
4864+ * Owner and path can be NULL if profile was registered by a
4865+ * plugin using external flag.
4866+ */
4867+ if (g_strcmp0(ext->owner, owner))
4868 continue;
4869
4870- if (g_str_equal(ext->path, path))
4871+ if (!g_strcmp0(ext->path, path))
4872 return ext;
4873 }
4874
4875
4876=== modified file 'src/service.c'
4877--- src/service.c 2015-09-15 13:42:52 +0000
4878+++ src/service.c 2015-11-23 18:34:05 +0000
4879@@ -184,6 +184,18 @@
4880 char addr[18];
4881 int err;
4882
4883+ switch (service->state) {
4884+ case BTD_SERVICE_STATE_UNAVAILABLE:
4885+ return -EINVAL;
4886+ case BTD_SERVICE_STATE_DISCONNECTED:
4887+ break;
4888+ case BTD_SERVICE_STATE_CONNECTING:
4889+ case BTD_SERVICE_STATE_CONNECTED:
4890+ return -EALREADY;
4891+ case BTD_SERVICE_STATE_DISCONNECTING:
4892+ return -EBUSY;
4893+ }
4894+
4895 if (!service->profile->accept)
4896 goto done;
4897
4898
4899=== modified file 'src/shared/ad.c'
4900--- src/shared/ad.c 2015-09-15 13:42:52 +0000
4901+++ src/shared/ad.c 2015-11-23 18:34:05 +0000
4902@@ -5,15 +5,19 @@
4903 * Copyright (C) 2015 Google Inc.
4904 *
4905 *
4906- * This program is free software; you can redistribute it and/or modify
4907- * it under the terms of the GNU General Public License as published by
4908- * the Free Software Foundation; either version 2 of the License, or
4909- * (at your option) any later version.
4910+ * This library is free software; you can redistribute it and/or
4911+ * modify it under the terms of the GNU Lesser General Public
4912+ * License as published by the Free Software Foundation; either
4913+ * version 2.1 of the License, or (at your option) any later version.
4914 *
4915- * This program is distributed in the hope that it will be useful,
4916+ * This library is distributed in the hope that it will be useful,
4917 * but WITHOUT ANY WARRANTY; without even the implied warranty of
4918- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4919- * GNU General Public License for more details.
4920+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4921+ * Lesser General Public License for more details.
4922+ *
4923+ * You should have received a copy of the GNU Lesser General Public
4924+ * License along with this library; if not, write to the Free Software
4925+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
4926 *
4927 */
4928
4929
4930=== modified file 'src/shared/ad.h'
4931--- src/shared/ad.h 2015-09-15 13:42:52 +0000
4932+++ src/shared/ad.h 2015-11-23 18:34:05 +0000
4933@@ -5,15 +5,19 @@
4934 * Copyright (C) 2015 Google Inc.
4935 *
4936 *
4937- * This program is free software; you can redistribute it and/or modify
4938- * it under the terms of the GNU General Public License as published by
4939- * the Free Software Foundation; either version 2 of the License, or
4940- * (at your option) any later version.
4941+ * This library is free software; you can redistribute it and/or
4942+ * modify it under the terms of the GNU Lesser General Public
4943+ * License as published by the Free Software Foundation; either
4944+ * version 2.1 of the License, or (at your option) any later version.
4945 *
4946- * This program is distributed in the hope that it will be useful,
4947+ * This library is distributed in the hope that it will be useful,
4948 * but WITHOUT ANY WARRANTY; without even the implied warranty of
4949- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4950- * GNU General Public License for more details.
4951+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
4952+ * Lesser General Public License for more details.
4953+ *
4954+ * You should have received a copy of the GNU Lesser General Public
4955+ * License along with this library; if not, write to the Free Software
4956+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
4957 *
4958 */
4959
4960
4961=== modified file 'src/shared/btsnoop.c'
4962--- src/shared/btsnoop.c 2015-09-15 13:42:52 +0000
4963+++ src/shared/btsnoop.c 2015-11-23 18:34:05 +0000
4964@@ -72,6 +72,7 @@
4965 uint16_t index;
4966 bool aborted;
4967 bool pklg_format;
4968+ bool pklg_v2;
4969 };
4970
4971 struct btsnoop *btsnoop_open(const char *path, unsigned long flags)
4972@@ -108,12 +109,14 @@
4973 goto failed;
4974
4975 /* Check for Apple Packet Logger format */
4976- if (hdr.id[0] != 0x00 || hdr.id[1] != 0x00)
4977+ if (hdr.id[0] != 0x00 ||
4978+ (hdr.id[1] != 0x00 && hdr.id[1] != 0x01))
4979 goto failed;
4980
4981 btsnoop->type = BTSNOOP_TYPE_MONITOR;
4982 btsnoop->index = 0xffff;
4983 btsnoop->pklg_format = true;
4984+ btsnoop->pklg_v2 = (hdr.id[1] == 0x01);
4985
4986 /* Apple Packet Logger format has no header */
4987 lseek(btsnoop->fd, 0, SEEK_SET);
4988@@ -242,6 +245,9 @@
4989 case BTSNOOP_OPCODE_SCO_TX_PKT:
4990 case BTSNOOP_OPCODE_SCO_RX_PKT:
4991 break;
4992+ case BTSNOOP_OPCODE_OPEN_INDEX:
4993+ case BTSNOOP_OPCODE_CLOSE_INDEX:
4994+ break;
4995 }
4996
4997 return 0xff;
4998@@ -334,11 +340,19 @@
4999 return false;
5000 }
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: