Hello community,

here is the log from the commit of package bluez for openSUSE:Factory checked 
in at 2017-06-02 10:31:30
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/bluez (Old)
 and      /work/SRC/openSUSE:Factory/.bluez.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "bluez"

Fri Jun  2 10:31:30 2017 rev:145 rq:498547 version:5.45

Changes:
--------
--- /work/SRC/openSUSE:Factory/bluez/bluez.changes      2017-03-05 
17:54:16.658417159 +0100
+++ /work/SRC/openSUSE:Factory/.bluez.new/bluez.changes 2017-06-02 
10:31:34.366822067 +0200
@@ -1,0 +2,15 @@
+Fri May 26 13:16:07 UTC 2017 - [email protected]
+
+- add bluez-5.45-disable-broken-tests.diff to disable two broken
+  tests (reported upstream but not yet fixed)
+
+-------------------------------------------------------------------
+Sat May  6 18:59:55 UTC 2017 - [email protected]
+
+- update to version 5.45:
+  This is mostly a bugfix release with fixes in ATT, GATT, OBEX
+  and AVDTP.
+  Feature-wise there are some new things as well, such as btmon
+  support decoding Bluetooth 5.0 HCI commands and events.
+
+-------------------------------------------------------------------
@@ -4 +19 @@
-- make testsuite run non-parallel (obs seems to have problems with
+- make testsuite run non-parallel (it has problems with running

Old:
----
  bluez-5.44.tar.xz

New:
----
  bluez-5.45-disable-broken-tests.diff
  bluez-5.45.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ bluez.spec ++++++
--- /var/tmp/diff_new_pack.6yu6Pj/_old  2017-06-02 10:31:35.066723173 +0200
+++ /var/tmp/diff_new_pack.6yu6Pj/_new  2017-06-02 10:31:35.070722608 +0200
@@ -18,7 +18,7 @@
 
 
 Name:           bluez
-Version:        5.44
+Version:        5.45
 Release:        0
 Summary:        Bluetooth Stack for Linux
 License:        GPL-2.0+
@@ -32,6 +32,8 @@
 Patch2:         bluez-sdp-unix-path.patch
 # PATCH-FIX-UPSTREAM: find the cups dir in libexec not in libdir
 Patch3:         bluez-cups-libexec.patch
+# workaround for broken tests (reported upstream but not yet fixed)
+Patch4:         bluez-5.45-disable-broken-tests.diff
 BuildRequires:  automake
 BuildRequires:  flex
 BuildRequires:  libtool
@@ -114,6 +116,7 @@
 %patch1 -p1
 %patch2 -p1
 %patch3 -p1
+%patch4 -p1
 mkdir dbus-apis
 cp -a doc/*.txt dbus-apis/
 # FIXME: Change the dbus service to be a real service, not systemd launched
@@ -122,6 +125,8 @@
 # END FIXME
 
 %build
+# because of patch4...
+autoreconf -fi
 # --enable-experimental is needed or btattach does not build (bug?)
 %configure \
        --disable-silent-rules  \
@@ -161,7 +166,7 @@
 %check
 %if ! 0%{?qemu_user_space_build}
 ##make %%{?_smp_mflags} check
-# deliberately not running parallel, as OBS seems to create spurious failures 
otherwise
+# deliberately not running parallel, as the test suite has spurious failures 
otherwise
 make check V=0
 %endif
 

++++++ bluez-5.45-disable-broken-tests.diff ++++++
diff --git a/Makefile.am b/Makefile.am
index 84e67a4..cac5283 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -395,7 +395,7 @@ unit_test_lib_SOURCES = unit/test-lib.c
 unit_test_lib_LDADD = src/libshared-glib.la \
                                lib/libbluetooth-internal.la @GLIB_LIBS@
 
-unit_tests += unit/test-gatt
+#unit_tests += unit/test-gatt
 
 unit_test_gatt_SOURCES = unit/test-gatt.c
 unit_test_gatt_LDADD = src/libshared-glib.la \
@@ -424,7 +424,7 @@ unit_test_gattrib_LDADD = lib/libbluetooth-internal.la \
                        @GLIB_LIBS@ @DBUS_LIBS@ -ldl -lrt
 
 if MIDI
-unit_tests += unit/test-midi
+#unit_tests += unit/test-midi
 unit_test_midi_CFLAGS = $(AM_CFLAGS) @ALSA_CFLAGS@ -DMIDI_TEST
 unit_test_midi_SOURCES = unit/test-midi.c \
                        profiles/midi/libmidi.h \
++++++ bluez-5.44.tar.xz -> bluez-5.45.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/ChangeLog new/bluez-5.45/ChangeLog
--- old/bluez-5.44/ChangeLog    2017-02-25 17:03:51.000000000 +0100
+++ new/bluez-5.45/ChangeLog    2017-05-04 23:06:44.000000000 +0200
@@ -1,3 +1,13 @@
+ver 5.45:
+       Fix issue with agent support in Bluetooth client tool.
+       Fix issue with handling re-connection policy.
+       Fix issue with handling unknown ATT commands.
+       Fix issue with handling GATT Service Includes property.
+       Fix issue with handling PullAll for OBEX transfers.
+       Fix issue with handling delay in AVDTP Suspend responses.
+       Fix issue with handling decoding of management frames.
+       Add support for frame counters in Bluetooth monitor tool.
+
 ver 5.44:
        Fix issue with GAP and GATT service registration.
        Fix issue with wrong address type for ATT sockets.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/client/gatt.c new/bluez-5.45/client/gatt.c
--- old/bluez-5.44/client/gatt.c        2016-09-26 14:29:00.000000000 +0200
+++ new/bluez-5.45/client/gatt.c        2017-05-04 23:06:44.000000000 +0200
@@ -299,7 +299,7 @@
        return NULL;
 }
 
-GDBusProxy *gatt_select_attribute(const char *path)
+static GDBusProxy *select_attribute(const char *path)
 {
        GDBusProxy *proxy;
 
@@ -314,6 +314,62 @@
        return select_proxy(path, descriptors);
 }
 
+static GDBusProxy *select_proxy_by_uuid(GDBusProxy *parent, const char *uuid,
+                                       GList *source)
+{
+       GList *l;
+       const char *value;
+       DBusMessageIter iter;
+
+       for (l = source; l; l = g_list_next(l)) {
+               GDBusProxy *proxy = l->data;
+
+               if (parent && !g_str_has_prefix(g_dbus_proxy_get_path(proxy),
+                                               g_dbus_proxy_get_path(parent)))
+                       continue;
+
+               if (g_dbus_proxy_get_property(proxy, "UUID", &iter) == FALSE)
+                       continue;
+
+               dbus_message_iter_get_basic(&iter, &value);
+
+               if (strcasecmp(uuid, value) == 0)
+                       return proxy;
+       }
+
+       return NULL;
+}
+
+static GDBusProxy *select_attribute_by_uuid(GDBusProxy *parent,
+                                                       const char *uuid)
+{
+       GDBusProxy *proxy;
+
+       proxy = select_proxy_by_uuid(parent, uuid, services);
+       if (proxy)
+               return proxy;
+
+       proxy = select_proxy_by_uuid(parent, uuid, characteristics);
+       if (proxy)
+               return proxy;
+
+       return select_proxy_by_uuid(parent, uuid, descriptors);
+}
+
+GDBusProxy *gatt_select_attribute(GDBusProxy *parent, const char *arg)
+{
+       if (arg[0] == '/')
+               return select_attribute(arg);
+
+       if (parent) {
+               GDBusProxy *proxy = select_attribute_by_uuid(parent, arg);
+               if (proxy)
+                       return proxy;
+       }
+
+       return select_attribute_by_uuid(parent, arg);
+}
+
 static char *attribute_generator(const char *text, int state, GList *source)
 {
        static int index, len;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/client/gatt.h new/bluez-5.45/client/gatt.h
--- old/bluez-5.44/client/gatt.h        2015-03-31 15:41:57.000000000 +0200
+++ new/bluez-5.45/client/gatt.h        2017-05-04 23:06:44.000000000 +0200
@@ -31,7 +31,7 @@
 void gatt_remove_descriptor(GDBusProxy *proxy);
 
 void gatt_list_attributes(const char *device);
-GDBusProxy *gatt_select_attribute(const char *path);
+GDBusProxy *gatt_select_attribute(GDBusProxy *parent, const char *path);
 char *gatt_attribute_generator(const char *text, int state);
 
 void gatt_read_attribute(GDBusProxy *proxy);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/client/main.c new/bluez-5.45/client/main.c
--- old/bluez-5.44/client/main.c        2016-09-26 14:29:00.000000000 +0200
+++ new/bluez-5.45/client/main.c        2017-05-04 23:06:44.000000000 +0200
@@ -670,7 +670,7 @@
 
                dbus_message_iter_get_basic(&iter, &str);
 
-               if (!strcmp(str, address))
+               if (!strcasecmp(str, address))
                        return adapter;
        }
 
@@ -691,7 +691,7 @@
 
                dbus_message_iter_get_basic(&iter, &str);
 
-               if (!strcmp(str, address))
+               if (!strcasecmp(str, address))
                        return proxy;
        }
 
@@ -1704,7 +1704,7 @@
                return;
        }
 
-       proxy = gatt_select_attribute(arg);
+       proxy = gatt_select_attribute(default_attr, arg);
        if (proxy)
                set_default_attribute(proxy);
 }
@@ -1720,7 +1720,7 @@
                return NULL;
        }
 
-       proxy = gatt_select_attribute(arg);
+       proxy = gatt_select_attribute(default_attr, arg);
        if (!proxy) {
                rl_printf("Attribute %s not available\n", arg);
                return NULL;
@@ -1878,7 +1878,7 @@
 
                dbus_message_iter_get_basic(&iter, &str);
 
-               if (!strncmp(str, text, len))
+               if (!strncasecmp(str, text, len))
                        return strdup(str);
         }
 
@@ -1910,7 +1910,7 @@
 
                dbus_message_iter_get_basic(&iter, &str);
 
-               if (!strncmp(str, text, len))
+               if (!strncasecmp(str, text, len))
                        return strdup(str);
        }
 
@@ -2130,9 +2130,9 @@
        { "list-attributes", "[dev]", cmd_list_attributes, "List attributes",
                                                        dev_generator },
        { "set-alias",    "<alias>",  cmd_set_alias, "Set device alias" },
-       { "select-attribute", "<attribute>",  cmd_select_attribute,
+       { "select-attribute", "<attribute/UUID>",  cmd_select_attribute,
                                "Select attribute", attribute_generator },
-       { "attribute-info", "[attribute]",  cmd_attribute_info,
+       { "attribute-info", "[attribute/UUID]",  cmd_attribute_info,
                                "Select attribute", attribute_generator },
        { "read",         NULL,       cmd_read, "Read attribute value" },
        { "write",        "<data=[xx xx ...]>", cmd_write,
@@ -2355,10 +2355,10 @@
 static gboolean parse_agent(const char *key, const char *value,
                                        gpointer user_data, GError **error)
 {
-       if (value)
-               auto_register_agent = g_strdup(value);
-       else
-               auto_register_agent = g_strdup("");
+       if (!value)
+               return FALSE;
+
+       auto_register_agent = g_strdup(value);
 
        return TRUE;
 }
@@ -2366,8 +2366,7 @@
 static GOptionEntry options[] = {
        { "version", 'v', 0, G_OPTION_ARG_NONE, &option_version,
                                "Show version information and exit" },
-       { "agent", 'a', G_OPTION_FLAG_OPTIONAL_ARG,
-                               G_OPTION_ARG_CALLBACK, parse_agent,
+       { "agent", 'a', 0, G_OPTION_ARG_CALLBACK, parse_agent,
                                "Register agent handler", "CAPABILITY" },
        { NULL },
 };
@@ -2385,6 +2384,8 @@
        GDBusClient *client;
        guint signal;
 
+       auto_register_agent = g_strdup("");
+
        context = g_option_context_new(NULL);
        g_option_context_add_main_entries(context, options, NULL);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/configure new/bluez-5.45/configure
--- old/bluez-5.44/configure    2017-02-25 17:04:41.000000000 +0100
+++ new/bluez-5.45/configure    2017-05-04 23:07:27.000000000 +0200
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for bluez 5.44.
+# Generated by GNU Autoconf 2.69 for bluez 5.45.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -587,8 +587,8 @@
 # Identity of this package.
 PACKAGE_NAME='bluez'
 PACKAGE_TARNAME='bluez'
-PACKAGE_VERSION='5.44'
-PACKAGE_STRING='bluez 5.44'
+PACKAGE_VERSION='5.45'
+PACKAGE_STRING='bluez 5.45'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -1460,7 +1460,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures bluez 5.44 to adapt to many kinds of systems.
+\`configure' configures bluez 5.45 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1530,7 +1530,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of bluez 5.44:";;
+     short | recursive ) echo "Configuration of bluez 5.45:";;
    esac
   cat <<\_ACEOF
 
@@ -1703,7 +1703,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-bluez configure 5.44
+bluez configure 5.45
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2068,7 +2068,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by bluez $as_me 5.44, which was
+It was created by bluez $as_me 5.45, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2932,7 +2932,7 @@
 
 # Define the identity of the package.
  PACKAGE='bluez'
- VERSION='5.44'
+ VERSION='5.45'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -15042,7 +15042,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by bluez $as_me 5.44, which was
+This file was extended by bluez $as_me 5.45, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -15108,7 +15108,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; 
s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-bluez config.status 5.44
+bluez config.status 5.45
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/configure.ac new/bluez-5.45/configure.ac
--- old/bluez-5.44/configure.ac 2017-02-25 17:03:51.000000000 +0100
+++ new/bluez-5.45/configure.ac 2017-05-04 23:06:44.000000000 +0200
@@ -1,5 +1,5 @@
 AC_PREREQ(2.60)
-AC_INIT(bluez, 5.44)
+AC_INIT(bluez, 5.45)
 
 AM_INIT_AUTOMAKE([foreign subdir-objects color-tests silent-rules
                                        tar-pax no-dist-gzip dist-xz])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/emulator/le.c new/bluez-5.45/emulator/le.c
--- old/bluez-5.44/emulator/le.c        2016-07-17 23:13:15.000000000 +0200
+++ new/bluez-5.45/emulator/le.c        2017-05-04 23:06:44.000000000 +0200
@@ -58,6 +58,10 @@
 #define MAX_RX_LEN             0x00fb
 #define MAX_RX_TIME            0x0848
 
+#define DEFAULT_ALL_PHYS       0x03
+#define DEFAULT_TX_PHYS                0x00
+#define DEFAULT_RX_PHYS                0x00
+
 struct bt_peer {
        uint8_t  addr_type;
        uint8_t  addr[6];
@@ -123,6 +127,10 @@
        uint8_t  le_resolv_enable;
        uint16_t le_resolv_timeout;
 
+       uint8_t  le_default_all_phys;
+       uint8_t  le_default_tx_phys;
+       uint8_t  le_default_rx_phys;
+
        struct bt_peer scan_cache[SCAN_CACHE_SIZE];
        uint8_t scan_cache_count;
 };
@@ -281,6 +289,37 @@
        hci->commands[35] |= 0x02;      /* LE Set Address Resolution Enable */
        hci->commands[35] |= 0x04;      /* LE Set Resolvable Private Address 
Timeout */
        hci->commands[35] |= 0x08;      /* LE Read Maximum Data Length */
+       hci->commands[35] |= 0x10;      /* LE Read PHY */
+       hci->commands[35] |= 0x20;      /* LE Set Default PHY */
+       hci->commands[35] |= 0x40;      /* LE Set PHY */
+       //hci->commands[35] |= 0x80;    /* LE Enhanced Receiver Test */
+       //hci->commands[36] |= 0x01;    /* LE Enhanced Transmitter Test */
+       //hci->commands[36] |= 0x02;    /* LE Set Advertising Set Random 
Address */
+       //hci->commands[36] |= 0x04;    /* LE Set Extended Advertising 
Parameters */
+       //hci->commands[36] |= 0x08;    /* LE Set Extended Advertising Data */
+       //hci->commands[36] |= 0x10;    /* LE Set Extended Scan Response Data */
+       //hci->commands[36] |= 0x20;    /* LE Set Extended Advertising Enable */
+       //hci->commands[36] |= 0x40;    /* LE Read Maximum Advertising Data 
Length */
+       //hci->commands[36] |= 0x80;    /* LE Read Number of Supported 
Advertising Sets */
+       //hci->commands[37] |= 0x01;    /* LE Remove Advertising Set */
+       //hci->commands[37] |= 0x02;    /* LE Clear Advertising Sets */
+       //hci->commands[37] |= 0x04;    /* LE Set Periodic Advertising 
Parameters */
+       //hci->commands[37] |= 0x08;    /* LE Set Periodic Advertising Data */
+       //hci->commands[37] |= 0x10;    /* LE Set Periodic Advertising Enable */
+       //hci->commands[37] |= 0x20;    /* LE Set Extended Scan Parameters */
+       //hci->commands[37] |= 0x40;    /* LE Set Extended Scan Enable */
+       //hci->commands[37] |= 0x80;    /* LE Extended Create Connection */
+       //hci->commands[38] |= 0x01;    /* LE Periodic Advertising Create Sync 
*/
+       //hci->commands[38] |= 0x02;    /* LE Periodic Advertising Create Sync 
Cancel */
+       //hci->commands[38] |= 0x04;    /* LE Periodic Advertising Terminate 
Sync */
+       //hci->commands[38] |= 0x08;    /* LE Add Device To Periodic Advertiser 
List */
+       //hci->commands[38] |= 0x10;    /* LE Remove Device From Periodic 
Advertiser List */
+       //hci->commands[38] |= 0x20;    /* LE Clear Periodic Advertiser List */
+       //hci->commands[38] |= 0x40;    /* LE Read Periodic Advertiser List 
Size */
+       //hci->commands[38] |= 0x80;    /* LE Read Transmit Power */
+       //hci->commands[39] |= 0x01;    /* LE Read RF Path Compensation */
+       //hci->commands[39] |= 0x02;    /* LE Write RF Path Compensation */
+       //hci->commands[39] |= 0x04;    /* LE Set Privacy Mode */
 
        memset(hci->features, 0, sizeof(hci->features));
        hci->features[4] |= 0x20;       /* BR/EDR Not Supported */
@@ -300,6 +339,15 @@
        //hci->le_event_mask[1] |= 0x01;        /* LE Generate DHKey Complete */
        //hci->le_event_mask[1] |= 0x02;        /* LE Enhanced Connection 
Complete */
        //hci->le_event_mask[1] |= 0x04;        /* LE Direct Advertising Report 
*/
+       //hci->le_event_mask[1] |= 0x08;        /* LE PHY Update Complete */
+       //hci->le_event_mask[1] |= 0x10;        /* LE Extended Advertising 
Report */
+       //hci->le_event_mask[1] |= 0x20;        /* LE Periodic Advertising Sync 
Established */
+       //hci->le_event_mask[1] |= 0x40;        /* LE Periodic Advertising 
Report */
+       //hci->le_event_mask[1] |= 0x80;        /* LE Periodic Advertising Sync 
Lost */
+       //hci->le_event_mask[2] |= 0x01;        /* LE Extended Scan Timeout */
+       //hci->le_event_mask[2] |= 0x02;        /* LE Extended Advertising Set 
Terminated */
+       //hci->le_event_mask[2] |= 0x04;        /* LE Scan Request Received */
+       //hci->le_event_mask[2] |= 0x08;        /* LE Channel Selection 
Algorithm */
 
        hci->le_mtu = 64;
        hci->le_max_pkt = 1;
@@ -313,6 +361,15 @@
        hci->le_features[0] |= 0x20;    /* LE Data Packet Length Extension */
        hci->le_features[0] |= 0x40;    /* LL Privacy */
        hci->le_features[0] |= 0x80;    /* Extended Scanner Filter Policies */
+       hci->le_features[1] |= 0x01;    /* LE 2M PHY */
+       hci->le_features[1] |= 0x02;    /* Stable Modulation Index - 
Transmitter */
+       hci->le_features[1] |= 0x04;    /* Stable Modulation Index - Receiver */
+       hci->le_features[1] |= 0x08;    /* LE Coded PHY */
+       //hci->le_features[1] |= 0x10;  /* LE Extended Advertising */
+       //hci->le_features[1] |= 0x20;  /* LE Periodic Advertising */
+       hci->le_features[1] |= 0x40;    /* Channel Selection Algorithm #2 */
+       hci->le_features[1] |= 0x80;    /* LE Power Class 1 */
+       hci->le_features[2] |= 0x01;    /* Minimum Number of Used Channels 
Procedure */
 
        memset(hci->le_random_addr, 0, sizeof(hci->le_random_addr));
 
@@ -369,6 +426,10 @@
        clear_resolv_list(hci);
        hci->le_resolv_enable = 0x00;
        hci->le_resolv_timeout = 0x0384;        /* 900 secs or 15 minutes */
+
+       hci->le_default_all_phys = DEFAULT_ALL_PHYS;
+       hci->le_default_tx_phys = DEFAULT_TX_PHYS;
+       hci->le_default_rx_phys = DEFAULT_RX_PHYS;
 }
 
 static void clear_scan_cache(struct bt_le *hci)
@@ -671,9 +732,9 @@
        struct bt_hci_rsp_read_local_version rsp;
 
        rsp.status = BT_HCI_ERR_SUCCESS;
-       rsp.hci_ver = 0x08;
+       rsp.hci_ver = 0x09;
        rsp.hci_rev = cpu_to_le16(0x0000);
-       rsp.lmp_ver = 0x08;
+       rsp.lmp_ver = 0x09;
        rsp.manufacturer = cpu_to_le16(hci->manufacturer);
        rsp.lmp_subver = cpu_to_le16(0x0000);
 
@@ -1645,6 +1706,99 @@
                                                        &rsp, sizeof(rsp));
 }
 
+static void cmd_le_read_phy(struct bt_le *hci, const void *data, uint8_t size)
+{
+       const struct bt_hci_cmd_le_read_phy *cmd = data;
+       struct bt_hci_rsp_le_read_phy rsp;
+
+       rsp.status = BT_HCI_ERR_SUCCESS;
+       rsp.handle = cmd->handle;
+       rsp.tx_phy = 0x01;      /* LE 1M */
+       rsp.rx_phy = 0x01;      /* LE 1M */
+
+       cmd_complete(hci, BT_HCI_CMD_LE_READ_PHY, &rsp, sizeof(rsp));
+}
+
+static void cmd_le_set_default_phy(struct bt_le *hci,
+                                               const void *data, uint8_t size)
+{
+       const struct bt_hci_cmd_le_set_default_phy *cmd = data;
+       uint8_t status, tx_phys, rx_phys;
+       uint8_t phys_mask;
+
+       phys_mask = (true << 0) | ((!!(hci->le_features[1] & 0x01)) << 1)
+                               | ((!!(hci->le_features[1] & 0x08)) << 2);
+
+       if (cmd->all_phys > 0x03) {
+               cmd_status(hci, BT_HCI_ERR_INVALID_PARAMETERS,
+                                       BT_HCI_CMD_LE_SET_DEFAULT_PHY);
+               return;
+       }
+
+       /* Transmitter PHYs preferences */
+       if (!(cmd->all_phys & 0x01)) {
+               /* At least one preference bit shall be set to 1 */
+               if (!cmd->tx_phys) {
+                       cmd_status(hci, BT_HCI_ERR_INVALID_PARAMETERS,
+                                       BT_HCI_CMD_LE_SET_DEFAULT_PHY);
+                       return;
+               }
+
+               if (cmd->tx_phys & ~phys_mask) {
+                       cmd_status(hci, BT_HCI_ERR_INVALID_PARAMETERS,
+                                       BT_HCI_CMD_LE_SET_DEFAULT_PHY);
+                       return;
+               }
+
+               tx_phys = cmd->tx_phys;
+       } else
+               tx_phys = 0x00;
+
+       /* Transmitter PHYs preferences */
+       if (!(cmd->all_phys & 0x02)) {
+               /* At least one preference bit shall be set to 1 */
+               if (!cmd->rx_phys) {
+                       cmd_status(hci, BT_HCI_ERR_INVALID_PARAMETERS,
+                                       BT_HCI_CMD_LE_SET_DEFAULT_PHY);
+                       return;
+               }
+
+               if (cmd->rx_phys & ~phys_mask) {
+                       cmd_status(hci, BT_HCI_ERR_INVALID_PARAMETERS,
+                                       BT_HCI_CMD_LE_SET_DEFAULT_PHY);
+                       return;
+               }
+
+               rx_phys = cmd->rx_phys;
+       } else
+               rx_phys = 0x00;
+
+       hci->le_default_all_phys = cmd->all_phys;
+       hci->le_default_tx_phys = tx_phys;
+       hci->le_default_rx_phys = rx_phys;
+
+       status = BT_HCI_ERR_SUCCESS;
+       cmd_complete(hci, BT_HCI_CMD_LE_SET_DEFAULT_PHY,
+                                               &status, sizeof(status));
+}
+
+static void cmd_le_set_phy(struct bt_le *hci, const void *data, uint8_t size)
+{
+       const struct bt_hci_cmd_le_set_phy *cmd = data;
+       struct bt_hci_evt_le_phy_update_complete evt;
+
+       cmd_status(hci, BT_HCI_ERR_SUCCESS, BT_HCI_CMD_LE_SET_PHY);
+
+       evt.status = BT_HCI_ERR_SUCCESS;
+       evt.handle = cmd->handle;
+       evt.tx_phy = 0x01;      /* LE 1M */
+       evt.rx_phy = 0x01;      /* LE 1M */
+
+       if (hci->le_event_mask[1] & 0x08)
+               le_meta_event(hci, BT_HCI_EVT_LE_PHY_UPDATE_COMPLETE,
+                                                       &evt, sizeof(evt));
+}
+
 static const struct {
        uint16_t opcode;
        void (*func) (struct bt_le *hci, const void *data, uint8_t size);
@@ -1732,6 +1886,12 @@
                                cmd_le_set_resolv_timeout, 2, true },
        { BT_HCI_CMD_LE_READ_MAX_DATA_LENGTH,
                                cmd_le_read_max_data_length, 0, true },
+       { BT_HCI_CMD_LE_READ_PHY,
+                               cmd_le_read_phy, 2, true },
+       { BT_HCI_CMD_LE_SET_DEFAULT_PHY,
+                               cmd_le_set_default_phy, 3, true },
+       { BT_HCI_CMD_LE_SET_PHY,
+                               cmd_le_set_phy, 7, true },
 
        { }
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/gobex/gobex-apparam.c 
new/bluez-5.45/gobex/gobex-apparam.c
--- old/bluez-5.44/gobex/gobex-apparam.c        2013-02-23 12:02:28.000000000 
+0100
+++ new/bluez-5.45/gobex/gobex-apparam.c        2017-05-04 23:06:44.000000000 
+0200
@@ -152,6 +152,9 @@
        GHashTableIter iter;
        gpointer key, value;
 
+       if (!apparam)
+               return 0;
+
        g_hash_table_iter_init(&iter, apparam->tags);
        while (g_hash_table_iter_next(&iter, &key, &value)) {
                struct apparam_tag *tag = value;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/monitor/avdtp.c 
new/bluez-5.45/monitor/avdtp.c
--- old/bluez-5.44/monitor/avdtp.c      2015-12-28 03:13:20.000000000 +0100
+++ new/bluez-5.45/monitor/avdtp.c      2017-05-04 23:06:44.000000000 +0200
@@ -776,7 +776,8 @@
                ret = avdtp_signalling_packet(&avdtp_frame);
                break;
        default:
-               packet_hexdump(frame->data, frame->size);
+               if (packet_has_filter(PACKET_FILTER_SHOW_A2DP_STREAM))
+                       packet_hexdump(frame->data, frame->size);
                return;
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/monitor/bt.h new/bluez-5.45/monitor/bt.h
--- old/bluez-5.44/monitor/bt.h 2015-10-30 04:30:13.000000000 +0100
+++ new/bluez-5.45/monitor/bt.h 2017-05-04 23:06:44.000000000 +0200
@@ -2134,6 +2134,33 @@
        uint16_t max_rx_time;
 } __attribute__ ((packed));
 
+#define BT_HCI_CMD_LE_READ_PHY                 0x2030
+struct bt_hci_cmd_le_read_phy {
+       uint16_t handle;
+} __attribute__((packed));
+struct bt_hci_rsp_le_read_phy {
+       uint8_t  status;
+       uint16_t handle;
+       uint8_t  tx_phy;
+       uint8_t  rx_phy;
+} __attribute__((packed));
+
+#define BT_HCI_CMD_LE_SET_DEFAULT_PHY          0x2031
+struct bt_hci_cmd_le_set_default_phy {
+       uint8_t  all_phys;
+       uint8_t  tx_phys;
+       uint8_t  rx_phys;
+} __attribute__((packed));
+
+#define BT_HCI_CMD_LE_SET_PHY                  0x2032
+struct bt_hci_cmd_le_set_phy {
+       uint16_t handle;
+       uint8_t  all_phys;
+       uint8_t  tx_phys;
+       uint8_t  rx_phys;
+       uint16_t phy_opts;
+} __attribute__((packed));
+
 #define BT_HCI_EVT_INQUIRY_COMPLETE            0x01
 struct bt_hci_evt_inquiry_complete {
        uint8_t  status;
@@ -2736,6 +2763,20 @@
        int8_t   rssi;
 } __attribute__ ((packed));
 
+#define BT_HCI_EVT_LE_PHY_UPDATE_COMPLETE      0x0c
+struct bt_hci_evt_le_phy_update_complete {
+       uint8_t  status;
+       uint16_t handle;
+       uint8_t  tx_phy;
+       uint8_t  rx_phy;
+} __attribute__ ((packed));
+
+#define BT_HCI_EVT_LE_CHAN_SELECT_ALG          0x14
+struct bt_hci_evt_le_chan_select_alg {
+       uint16_t handle;
+       uint8_t  algorithm;
+} __attribute__ ((packed));
+
 #define BT_HCI_ERR_SUCCESS                     0x00
 #define BT_HCI_ERR_UNKNOWN_COMMAND             0x01
 #define BT_HCI_ERR_UNKNOWN_CONN_ID             0x02
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/monitor/main.c 
new/bluez-5.45/monitor/main.c
--- old/bluez-5.44/monitor/main.c       2016-05-26 18:51:11.000000000 +0200
+++ new/bluez-5.45/monitor/main.c       2017-05-04 23:06:44.000000000 +0200
@@ -69,6 +69,7 @@
                "\t-t, --time             Show time instead of time offset\n"
                "\t-T, --date             Show time and date information\n"
                "\t-S, --sco              Dump SCO traffic\n"
+               "\t-A, --a2dp             Dump A2DP stream traffic\n"
                "\t-E, --ellisys [ip]     Send Ellisys HCI Injection\n"
                "\t-h, --help             Show help options\n");
 }
@@ -85,6 +86,7 @@
        { "time",    no_argument,       NULL, 't' },
        { "date",    no_argument,       NULL, 'T' },
        { "sco",     no_argument,       NULL, 'S' },
+       { "a2dp",    no_argument,       NULL, 'A' },
        { "ellisys", required_argument, NULL, 'E' },
        { "todo",    no_argument,       NULL, '#' },
        { "version", no_argument,       NULL, 'v' },
@@ -113,7 +115,7 @@
        for (;;) {
                int opt;
 
-               opt = getopt_long(argc, argv, "d:r:w:a:s:p:i:tTSE:vh",
+               opt = getopt_long(argc, argv, "d:r:w:a:s:p:i:tTSAE:vh",
                                                main_options, NULL);
                if (opt < 0)
                        break;
@@ -167,6 +169,9 @@
                case 'S':
                        filter_mask |= PACKET_FILTER_SHOW_SCO_DATA;
                        break;
+               case 'A':
+                       filter_mask |= PACKET_FILTER_SHOW_A2DP_STREAM;
+                       break;
                case 'E':
                        ellisys_server = optarg;
                        ellisys_port = 24352;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/monitor/packet.c 
new/bluez-5.45/monitor/packet.c
--- old/bluez-5.44/monitor/packet.c     2017-02-25 17:03:51.000000000 +0100
+++ new/bluez-5.45/monitor/packet.c     2017-05-04 23:06:45.000000000 +0200
@@ -58,6 +58,7 @@
 #include "packet.h"
 
 #define COLOR_CHANNEL_LABEL            COLOR_WHITE
+#define COLOR_FRAME_LABEL              COLOR_WHITE
 #define COLOR_INDEX_LABEL              COLOR_WHITE
 #define COLOR_TIMESTAMP                        COLOR_YELLOW
 
@@ -220,6 +221,11 @@
        return 0xff;
 }
 
+bool packet_has_filter(unsigned long filter)
+{
+       return filter_mask & filter;
+}
+
 void packet_set_filter(unsigned long filter)
 {
        filter_mask = filter;
@@ -259,6 +265,17 @@
 
 #define print_space(x) printf("%*c", (x), ' ');
 
+#define MAX_INDEX 16
+
+struct index_data {
+       uint8_t  type;
+       uint8_t  bdaddr[6];
+       uint16_t manufacturer;
+       size_t  frame;
+};
+
+static struct index_data index_list[MAX_INDEX];
+
 static void print_packet(struct timeval *tv, struct ucred *cred, char ident,
                                        uint16_t index, const char *channel,
                                        const char *color, const char *label,
@@ -267,6 +284,7 @@
        int col = num_columns();
        char line[256], ts_str[96];
        int n, ts_len = 0, ts_pos = 0, len = 0, pos = 0;
+       static size_t last_frame;
 
        if (channel) {
                if (use_color()) {
@@ -280,6 +298,20 @@
                        ts_pos += n;
                        ts_len += n;
                }
+       } else if (index != HCI_DEV_NONE &&
+                               index_list[index].frame != last_frame) {
+               if (use_color()) {
+                       n = sprintf(ts_str + ts_pos, "%s", COLOR_FRAME_LABEL);
+                       if (n > 0)
+                               ts_pos += n;
+               }
+
+               n = sprintf(ts_str + ts_pos, " #%zu", index_list[index].frame);
+               if (n > 0) {
+                       ts_pos += n;
+                       ts_len += n;
+               }
+               last_frame = index_list[index].frame;
        }
 
        if ((filter_mask & PACKET_FILTER_SHOW_INDEX) &&
@@ -3809,16 +3841,6 @@
                        addr[5], addr[4], addr[3], addr[2], addr[1], addr[0]);
 }
 
-#define MAX_INDEX 16
-
-struct index_data {
-       uint8_t  type;
-       uint8_t  bdaddr[6];
-       uint16_t manufacturer;
-};
-
-static struct index_data index_list[MAX_INDEX];
-
 void packet_monitor(struct timeval *tv, struct ucred *cred,
                                        uint16_t index, uint16_t opcode,
                                        const void *data, uint16_t size)
@@ -3830,10 +3852,11 @@
        uint16_t manufacturer;
        const char *ident;
 
-       if (index_filter && index_number != index)
-               return;
-
-       index_current = index;
+       if (index != HCI_DEV_NONE) {
+               if (index_filter && index_number != index)
+                       return;
+               index_current = index;
+       }
 
        if (tv && time_offset == ((time_t) -1))
                time_offset = tv->tv_sec;
@@ -6290,6 +6313,12 @@
        case 0x01:
                str = "Ignore not in white list";
                break;
+       case 0x02:
+               str = "Accept all advertisement, inc. directed unresolved RPA";
+               break;
+       case 0x03:
+               str = "Ignore not in white list, exc. directed unresolved RPA";
+               break;
        default:
                str = "Reserved";
                break;
@@ -6712,6 +6741,141 @@
        print_field("Max RX time: %d", le16_to_cpu(rsp->max_rx_time));
 }
 
+static void le_read_phy_cmd(const void *data, uint8_t size)
+{
+       const struct bt_hci_cmd_le_read_phy *cmd = data;
+
+       print_handle(cmd->handle);
+}
+
+static void print_le_phy(const char *prefix, uint8_t phy)
+{
+       const char *str;
+
+       switch (phy) {
+       case 0x01:
+               str = "LE 1M";
+               break;
+       case 0x02:
+               str = "LE 2M";
+               break;
+       case 0x03:
+               str = "LE Coded";
+               break;
+       default:
+               str = "Reserved";
+               break;
+       }
+
+       print_field("%s: %s (0x%2.2x)", prefix, str, phy);
+}
+
+static void le_read_phy_rsp(const void *data, uint8_t size)
+{
+       const struct bt_hci_rsp_le_read_phy *rsp = data;
+
+       print_status(rsp->status);
+       print_handle(rsp->handle);
+       print_le_phy("TX PHY", rsp->tx_phy);
+       print_le_phy("RX PHY", rsp->rx_phy);
+}
+
+static const struct {
+       uint8_t bit;
+       const char *str;
+} le_phys[] = {
+       {  0, "LE 1M"   },
+       {  1, "LE 2M"   },
+       {  2, "LE Coded"},
+       { }
+};
+
+static const struct {
+       uint8_t bit;
+       const char *str;
+} le_phy_preference[] = {
+       {  0, "No TX PHY preference"    },
+       {  1, "No RX PHY preference"    },
+       { }
+};
+
+static void print_le_phys_preference(uint8_t all_phys, uint8_t tx_phys,
+                                                       uint8_t rx_phys)
+{
+       int i;
+       uint8_t mask = all_phys;
+
+       print_field("All PHYs preference: 0x%2.2x", all_phys);
+
+       for (i = 0; le_phy_preference[i].str; i++) {
+               if (all_phys & (((uint8_t) 1) << le_phy_preference[i].bit)) {
+                       print_field("  %s", le_phy_preference[i].str);
+                       mask &= ~(((uint64_t) 1) << le_phy_preference[i].bit);
+               }
+       }
+
+       if (mask)
+               print_text(COLOR_UNKNOWN_OPTIONS_BIT, "  Reserved"
+                                                       " (0x%2.2x)", mask);
+
+       print_field("TX PHYs preference: 0x%2.2x", tx_phys);
+       mask = tx_phys;
+
+       for (i = 0; le_phys[i].str; i++) {
+               if (tx_phys & (((uint8_t) 1) << le_phys[i].bit)) {
+                       print_field("  %s", le_phys[i].str);
+                       mask &= ~(((uint64_t) 1) << le_phys[i].bit);
+               }
+       }
+
+       if (mask)
+               print_text(COLOR_UNKNOWN_OPTIONS_BIT, "  Reserved"
+                                                       " (0x%2.2x)", mask);
+
+       print_field("RX PHYs preference: 0x%2.2x", rx_phys);
+       mask = rx_phys;
+
+       for (i = 0; le_phys[i].str; i++) {
+               if (rx_phys & (((uint8_t) 1) << le_phys[i].bit)) {
+                       print_field("  %s", le_phys[i].str);
+                       mask &= ~(((uint64_t) 1) << le_phys[i].bit);
+               }
+       }
+
+       if (mask)
+               print_text(COLOR_UNKNOWN_OPTIONS_BIT, "  Reserved"
+                                                       " (0x%2.2x)", mask);
+}
+
+static void le_set_default_phy_cmd(const void *data, uint8_t size)
+{
+       const struct bt_hci_cmd_le_set_default_phy *cmd = data;
+
+       print_le_phys_preference(cmd->all_phys, cmd->tx_phys, cmd->rx_phys);
+}
+
+static void le_set_phy_cmd(const void *data, uint8_t size)
+{
+       const struct bt_hci_cmd_le_set_phy *cmd = data;
+       const char *str;
+
+       print_handle(cmd->handle);
+       print_le_phys_preference(cmd->all_phys, cmd->tx_phys, cmd->rx_phys);
+       switch (le16_to_cpu(cmd->phy_opts)) {
+       case 0x0001:
+               str = "S2 coding";
+               break;
+       case 0x0002:
+               str = "S8 coding";
+               break;
+       default:
+               str = "Reserved";
+               break;
+       }
+
+       print_field("PHY options preference: %s (0x%4.4x)", str, cmd->phy_opts);
+}
+
 struct opcode_data {
        uint16_t opcode;
        int bit;
@@ -7407,9 +7571,14 @@
        { 0x202f, 283, "LE Read Maximum Data Length",
                                null_cmd, 0, true,
                                le_read_max_data_length_rsp, 9, true },
-       { 0x2030, 284, "LE Read PHY" },
-       { 0x2031, 285, "LE Set Default PHY" },
-       { 0x2032, 286, "LE Set PHY" },
+       { 0x2030, 284, "LE Read PHY",
+                               le_read_phy_cmd, 2, true,
+                               le_read_phy_rsp, 5, true},
+       { 0x2031, 285, "LE Set Default PHY",
+                               le_set_default_phy_cmd, 3, true,
+                               status_rsp, 1, true },
+       { 0x2032, 286, "LE Set PHY",
+                               le_set_phy_cmd, 7, true},
        { 0x2033, 287, "LE Enhanced Receiver Test" },
        { 0x2034, 288, "LE Enhanced Transmitter Test" },
        { 0x2035, 289, "LE Set Advertising Set Random Address" },
@@ -8531,6 +8700,38 @@
                packet_hexdump(data + sizeof(*evt), size - sizeof(*evt));
 }
 
+static void le_phy_update_complete_evt(const void *data, uint8_t size)
+{
+       const struct bt_hci_evt_le_phy_update_complete *evt = data;
+
+       print_status(evt->status);
+       print_handle(evt->handle);
+       print_le_phy("TX PHY", evt->tx_phy);
+       print_le_phy("RX PHY", evt->rx_phy);
+}
+
+static void le_chan_select_alg_evt(const void *data, uint8_t size)
+{
+       const struct bt_hci_evt_le_chan_select_alg *evt = data;
+       const char *str;
+
+       print_handle(evt->handle);
+
+       switch (evt->algorithm) {
+       case 0x00:
+               str = "#1";
+               break;
+       case 0x01:
+               str = "#2";
+               break;
+       default:
+               str = "Reserved";
+               break;
+       }
+
+       print_field("Algorithm: %s (0x%2.2x)", str, evt->algorithm);
+}
+
 struct subevent_data {
        uint8_t subevent;
        const char *str;
@@ -8597,7 +8798,8 @@
                                le_enhanced_conn_complete_evt, 30, true },
        { 0x0b, "LE Direct Advertising Report",
                                le_direct_adv_report_evt, 1, false },
-       { 0x0c, "LE PHY Update Complete" },
+       { 0x0c, "LE PHY Update Complete",
+                               le_phy_update_complete_evt, 5, true},
        { 0x0d, "LE Extended Advertising Report" },
        { 0x0e, "LE Periodic Advertising Sync Established" },
        { 0x0f, "LE Periodic Advertising Report" },
@@ -8605,7 +8807,8 @@
        { 0x11, "LE Scan Timeout" },
        { 0x12, "LE Advertising Set Terminated" },
        { 0x13, "LE Scan Request Received" },
-       { 0x14, "LE Channel Selection Algorithm" },
+       { 0x14, "LE Channel Selection Algorithm",
+                               le_chan_select_alg_evt, 3, true},
        { }
 };
 
@@ -8972,6 +9175,8 @@
        char extra_str[25], vendor_str[150];
        int i;
 
+       index_list[index].frame++;
+
        if (size < HCI_COMMAND_HDR_SIZE) {
                sprintf(extra_str, "(len %d)", size);
                print_packet(tv, cred, '*', index, NULL, COLOR_ERROR,
@@ -9073,6 +9278,8 @@
        char extra_str[25];
        int i;
 
+       index_list[index].frame++;
+
        if (size < HCI_EVENT_HDR_SIZE) {
                sprintf(extra_str, "(len %d)", size);
                print_packet(tv, cred, '*', index, NULL, COLOR_ERROR,
@@ -9145,6 +9352,8 @@
        uint8_t flags = acl_flags(handle);
        char handle_str[16], extra_str[32];
 
+       index_list[index].frame++;
+
        if (size < HCI_ACL_HDR_SIZE) {
                if (in)
                        print_packet(tv, cred, '*', index, NULL, COLOR_ERROR,
@@ -9187,6 +9396,8 @@
        uint8_t flags = acl_flags(handle);
        char handle_str[16], extra_str[32];
 
+       index_list[index].frame++;
+
        if (size < HCI_SCO_HDR_SIZE) {
                if (in)
                        print_packet(tv, cred, '*', index, NULL, COLOR_ERROR,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/monitor/packet.h 
new/bluez-5.45/monitor/packet.h
--- old/bluez-5.44/monitor/packet.h     2016-09-26 14:29:00.000000000 +0200
+++ new/bluez-5.45/monitor/packet.h     2017-05-04 23:06:45.000000000 +0200
@@ -33,7 +33,9 @@
 #define PACKET_FILTER_SHOW_TIME_OFFSET (1 << 3)
 #define PACKET_FILTER_SHOW_ACL_DATA    (1 << 4)
 #define PACKET_FILTER_SHOW_SCO_DATA    (1 << 5)
+#define PACKET_FILTER_SHOW_A2DP_STREAM (1 << 6)
 
+bool packet_has_filter(unsigned long filter);
 void packet_set_filter(unsigned long filter);
 void packet_add_filter(unsigned long filter);
 void packet_del_filter(unsigned long filter);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/obexd/plugins/pbap.c 
new/bluez-5.45/obexd/plugins/pbap.c
--- old/bluez-5.44/obexd/plugins/pbap.c 2016-09-26 14:29:00.000000000 +0200
+++ new/bluez-5.45/obexd/plugins/pbap.c 2017-05-04 23:06:45.000000000 +0200
@@ -369,6 +369,7 @@
                /* Ignore all other parameter and return PhoneBookSize */
                uint16_t size = g_slist_length(pbap->cache.entries);
 
+               pbap->obj->firstpacket = TRUE;
                pbap->obj->apparam = g_obex_apparam_set_uint16(
                                                        pbap->obj->apparam,
                                                        PHONEBOOKSIZE_TAG,
@@ -892,8 +893,10 @@
 
        *hi = G_OBEX_HDR_APPARAM;
 
-       if (pbap->params->maxlistcount == 0)
+       if (obj->firstpacket) {
+               obj->firstpacket = FALSE;
                return g_obex_apparam_encode(obj->apparam, buf, mtu);
+       }
 
        return 0;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/plugins/policy.c 
new/bluez-5.45/plugins/policy.c
--- old/bluez-5.44/plugins/policy.c     2017-02-25 17:03:51.000000000 +0100
+++ new/bluez-5.45/plugins/policy.c     2017-05-04 23:06:45.000000000 +0200
@@ -649,7 +649,7 @@
         */
        reconnect = reconnect_add(service);
 
-       reconnect_reset(reconnect);
+       reconnect->active = false;
 
        /*
         * Should this device be reconnected? A matching UUID might not
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/profiles/audio/avdtp.c 
new/bluez-5.45/profiles/audio/avdtp.c
--- old/bluez-5.44/profiles/audio/avdtp.c       2017-02-25 17:03:51.000000000 
+0100
+++ new/bluez-5.45/profiles/audio/avdtp.c       2017-05-04 23:06:45.000000000 
+0200
@@ -86,6 +86,7 @@
 #define AVDTP_MSG_TYPE_REJECT                  0x03
 
 #define REQ_TIMEOUT 6
+#define SUSPEND_TIMEOUT 10
 #define ABORT_TIMEOUT 2
 #define DISCONNECT_TIMEOUT 1
 #define START_TIMEOUT 1
@@ -2538,7 +2539,7 @@
                        struct pending_req *req)
 {
        static int transaction = 0;
-       int err;
+       int err, timeout;
 
        if (session->state == AVDTP_SESSION_STATE_DISCONNECTED) {
                session->io = l2cap_connect(session);
@@ -2568,10 +2569,18 @@
 
        session->req = req;
 
-       req->timeout = g_timeout_add_seconds(req->signal_id == AVDTP_ABORT ?
-                                       ABORT_TIMEOUT : REQ_TIMEOUT,
-                                       request_timeout,
-                                       session);
+       switch (req->signal_id) {
+       case AVDTP_ABORT:
+               timeout = ABORT_TIMEOUT;
+               break;
+       case AVDTP_SUSPEND:
+               timeout = SUSPEND_TIMEOUT;
+               break;
+       default:
+               timeout = REQ_TIMEOUT;
+       }
+
+       req->timeout = g_timeout_add_seconds(timeout, request_timeout, session);
        return 0;
 
 failed:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/src/adapter.c new/bluez-5.45/src/adapter.c
--- old/bluez-5.44/src/adapter.c        2017-02-25 17:03:51.000000000 +0100
+++ new/bluez-5.45/src/adapter.c        2017-05-04 23:06:45.000000000 +0200
@@ -7107,7 +7107,7 @@
 
        ba2str(peer, device_addr);
 
-       snprintf(filename, sizeof(filename), STORAGEDIR "/%s/%s/info",
+       snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
                                        adapter_dir(adapter), device_addr);
 
        key_file = g_key_file_new();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/src/gatt-client.c 
new/bluez-5.45/src/gatt-client.c
--- old/bluez-5.44/src/gatt-client.c    2016-09-26 14:29:00.000000000 +0200
+++ new/bluez-5.45/src/gatt-client.c    2017-05-04 23:06:45.000000000 +0200
@@ -72,6 +72,7 @@
        bt_uuid_t uuid;
        char *path;
        struct queue *chrcs;
+       struct queue *incl_services;
 };
 
 typedef bool (*async_dbus_op_complete_t)(void *data);
@@ -1398,10 +1399,36 @@
        return TRUE;
 }
 
+static void append_incl_service_path(void *data, void *user_data)
+{
+       struct service *incl_service = data;
+       DBusMessageIter *array = user_data;
+
+       dbus_message_iter_append_basic(array, DBUS_TYPE_OBJECT_PATH,
+                                       &incl_service->path);
+}
+
+static gboolean service_get_includes(const GDBusPropertyTable *property,
+                                       DBusMessageIter *iter, void *data)
+{
+       struct service *service = data;
+       DBusMessageIter array;
+
+       dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "{o}", &array);
+
+       queue_foreach(service->incl_services, append_incl_service_path, &array);
+
+       dbus_message_iter_close_container(iter, &array);
+
+       return TRUE;
+
+}
+
 static const GDBusPropertyTable service_properties[] = {
        { "UUID", "s", service_get_uuid },
        { "Device", "o", service_get_device },
        { "Primary", "b", service_get_primary },
+       { "Includes", "ao", service_get_includes },
        { }
 };
 
@@ -1410,6 +1437,7 @@
        struct service *service = data;
 
        queue_destroy(service->chrcs, NULL);  /* List should be empty here */
+       queue_destroy(service->incl_services, NULL);
        g_free(service->path);
        free(service);
 }
@@ -1423,6 +1451,7 @@
 
        service = new0(struct service, 1);
        service->chrcs = queue_new();
+       service->incl_services = queue_new();
        service->client = client;
 
        gatt_db_attribute_get_service_data(attr, &service->start_handle,
@@ -1459,13 +1488,29 @@
        return service;
 }
 
+static void on_service_removed(void *data, void *user_data)
+{
+       struct service *service = data;
+       struct service *removed_service = user_data;
+
+       if (queue_remove(service->incl_services, removed_service))
+               g_dbus_emit_property_changed(btd_get_dbus_connection(),
+                                                       service->path,
+                                                       GATT_SERVICE_IFACE,
+                                                       "Includes");
+}
+
 static void unregister_service(void *data)
 {
        struct service *service = data;
+       struct btd_gatt_client *client = service->client;
 
        DBG("Removing GATT service: %s", service->path);
 
        queue_remove_all(service->chrcs, NULL, NULL, unregister_characteristic);
+       queue_remove_all(service->incl_services, NULL, NULL, NULL);
+
+       queue_foreach(client->services, on_service_removed, service);
 
        g_dbus_unregister_interface(btd_get_dbus_connection(), service->path,
                                                        GATT_SERVICE_IFACE);
@@ -1567,11 +1612,71 @@
        queue_push_tail(client->services, service);
 }
 
+static bool match_service_handle(const void *a, const void *b)
+{
+       const struct service *service = a;
+       uint16_t start_handle = PTR_TO_UINT(b);
+
+       return service->start_handle == start_handle;
+}
+
+struct update_incl_data {
+       struct service *service;
+       bool changed;
+};
+
+static void update_included_service(struct gatt_db_attribute *attrib,
+                                                       void *user_data)
+{
+       struct update_incl_data *update_data = user_data;
+       struct btd_gatt_client *client = update_data->service->client;
+       struct service *service = update_data->service;
+       struct service *incl_service;
+       uint16_t start_handle;
+
+       gatt_db_attribute_get_incl_data(attrib, NULL, &start_handle, NULL);
+
+       incl_service = queue_find(client->services, match_service_handle,
+                                               UINT_TO_PTR(start_handle));
+
+       if (!incl_service)
+               return;
+
+       /* Check if service is already on list */
+       if (queue_find(service->incl_services, NULL, incl_service))
+               return;
+
+       queue_push_tail(service->incl_services, incl_service);
+       update_data->changed = true;
+}
+
+static void update_included_services(void *data, void *user_data)
+{
+       struct btd_gatt_client *client = user_data;
+       struct service *service = data;
+       struct gatt_db_attribute *attr;
+       struct update_incl_data inc_data = {
+               .changed = false,
+               .service = service,
+       };
+
+       attr = gatt_db_get_attribute(client->db, service->start_handle);
+       gatt_db_service_foreach_incl(attr, update_included_service, &inc_data);
+
+       if (inc_data.changed)
+               g_dbus_emit_property_changed(btd_get_dbus_connection(),
+                                                       service->path,
+                                                       GATT_SERVICE_IFACE,
+                                                       "Includes");
+}
+
 static void create_services(struct btd_gatt_client *client)
 {
        DBG("Exporting objects for GATT services: %s", client->devaddr);
 
        gatt_db_foreach_service(client->db, NULL, export_service, client);
+
+       queue_foreach(client->services, update_included_services, client);
 }
 
 struct btd_gatt_client *btd_gatt_client_new(struct btd_device *device)
@@ -1689,14 +1794,8 @@
                return;
 
        export_service(attrib, client);
-}
 
-static bool match_service_handle(const void *a, const void *b)
-{
-       const struct service *service = a;
-       uint16_t start_handle = PTR_TO_UINT(b);
-
-       return service->start_handle == start_handle;
+       queue_foreach(client->services, update_included_services, client);
 }
 
 void btd_gatt_client_service_removed(struct btd_gatt_client *client,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/src/shared/att.c 
new/bluez-5.45/src/shared/att.c
--- old/bluez-5.44/src/shared/att.c     2016-10-28 14:57:27.000000000 +0200
+++ new/bluez-5.45/src/shared/att.c     2017-05-04 23:06:45.000000000 +0200
@@ -148,6 +148,9 @@
                        return att_opcode_type_table[i].type;
        }
 
+       if (opcode & ATT_OP_CMD_MASK)
+               return ATT_OP_TYPE_CMD;
+
        return ATT_OP_TYPE_UNKNOWN;
 }
 
@@ -838,10 +841,10 @@
        }
 
        /*
-        * If this was a request and no handler was registered for it, respond
-        * with "Not Supported"
+        * If this was not a command and no handler was registered for it,
+        * respond with "Not Supported"
         */
-       if (!found && get_op_type(opcode) == ATT_OP_TYPE_REQ)
+       if (!found && get_op_type(opcode) != ATT_OP_TYPE_CMD)
                respond_not_supported(att, opcode);
 
        bt_att_unref(att);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/src/shared/util.c 
new/bluez-5.45/src/shared/util.c
--- old/bluez-5.44/src/shared/util.c    2015-12-28 03:13:20.000000000 +0100
+++ new/bluez-5.45/src/shared/util.c    2017-05-04 23:06:45.000000000 +0200
@@ -117,7 +117,7 @@
        char filename[PATH_MAX];
        struct stat st;
 
-       snprintf(filename, sizeof(filename), "%s/%s", parent, name);
+       snprintf(filename, PATH_MAX, "%s/%s", parent, name);
        if (lstat(filename, &st) == 0 && S_ISDIR(st.st_mode))
                return DT_DIR;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/tools/bluemoon.c 
new/bluez-5.45/tools/bluemoon.c
--- old/bluez-5.44/tools/bluemoon.c     2016-05-26 18:51:11.000000000 +0200
+++ new/bluez-5.45/tools/bluemoon.c     2017-05-04 23:06:45.000000000 +0200
@@ -621,6 +621,7 @@
        { 0x0a, "iBT 2.1 (AG620)"       },
        { 0x0b, "iBT 3.0 (LnP)"         },
        { 0x0c, "iBT 3.0 (WsP)"         },
+       { 0x12, "iBT 3.5 (ThP)"         },
        { }
 };
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/tools/obexctl.c 
new/bluez-5.45/tools/obexctl.c
--- old/bluez-5.44/tools/obexctl.c      2015-07-07 19:21:11.000000000 +0200
+++ new/bluez-5.45/tools/obexctl.c      2017-05-04 23:06:45.000000000 +0200
@@ -1710,7 +1710,7 @@
                return;
        }
 
-       if (strcmp(argv[1], "*") == 0)
+       if (strcmp(argv[1], "*") == 0 || strcmp(argv[1], "*.vcf") == 0)
                return pbap_pull_all(proxy, argc, argv);
 
        return pbap_pull(proxy, argc, argv);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/tools/smp-tester.c 
new/bluez-5.45/tools/smp-tester.c
--- old/bluez-5.44/tools/smp-tester.c   2016-09-26 14:29:00.000000000 +0200
+++ new/bluez-5.45/tools/smp-tester.c   2017-05-04 23:06:45.000000000 +0200
@@ -416,7 +416,7 @@
 static const uint8_t smp_sc_req_1[] = {        0x01,   /* Pairing Request */
                                        0x03,   /* NoInputNoOutput */
                                        0x00,   /* OOB Flag */
-                                       0x09,   /* Bonding - no MITM, SC */
+                                       0x29,   /* Bonding - no MITM, SC, CT2 */
                                        0x10,   /* Max key size */
                                        0x0d,   /* Init. key dist. */
                                        0x0d,   /* Rsp. key dist. */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluez-5.44/unit/test-gatt.c 
new/bluez-5.45/unit/test-gatt.c
--- old/bluez-5.44/unit/test-gatt.c     2016-10-28 14:57:27.000000000 +0200
+++ new/bluez-5.45/unit/test-gatt.c     2017-05-04 23:06:45.000000000 +0200
@@ -90,6 +90,11 @@
                .size = sizeof(data(args)),                     \
        }
 
+#define false_pdu()                                            \
+       {                                                       \
+               .valid = false,                                 \
+       }
+
 #define define_test(name, function, type, bt_uuid, db,                 \
                test_step, args...)                                     \
        do {                                                            \
@@ -403,6 +408,13 @@
        if (pdu->valid && (pdu->size == 0)) {
                test_debug("(no action expected)", "GATT: ");
                context->pdu_offset++;
+
+               /* Quit the context if we processed the last PDU */
+               if (!context->data->pdu_list[context->pdu_offset].valid) {
+                       context_quit(context);
+                       return FALSE;
+               }
+
                return send_pdu(context);
        }
 
@@ -4461,5 +4473,17 @@
                        raw_pdu(0x18, 0x01),
                        raw_pdu(0x01, 0x18, 0x25, 0x00, 0x06));
 
+       define_test_server("/robustness/unkown-request",
+                       test_server, service_db_1, NULL,
+                       raw_pdu(0x03, 0x00, 0x02),
+                       raw_pdu(0xbf, 0x00),
+                       raw_pdu(0x01, 0xbf, 0x00, 0x00, 0x06));
+
+       define_test_server("/robustness/unkown-command",
+                       test_server, service_db_1, NULL,
+                       raw_pdu(0x03, 0x00, 0x02),
+                       raw_pdu(0xff, 0x00),
+                       raw_pdu());
+
        return tester_run();
 }


Reply via email to