[pulseaudio] snapshot, with wip bt headset2 patches (#1045548, #1067470)

Rex Dieter rdieter at fedoraproject.org
Wed Oct 22 14:20:16 UTC 2014


commit 311762276ed52abbae3a8521ac12d8bf0ea57999
Author: Rex Dieter <rdieter at math.unl.edu>
Date:   Wed Oct 22 09:20:18 2014 -0500

    snapshot, with wip bt headset2 patches (#1045548,#1067470)

 0001-bluez5-device-use-get_profile_direction.patch |   74 +++
 0002-bluez5-util-add-dispose-function.patch        |   48 ++
 ...d-native-add-a-new-native-headset-backend.patch |  490 ++++++++++++++++++++
 ...ch-on-port-available-Don-t-switch-profile.patch |   35 --
 0039-Name-HDMI-outputs-uniquely.patch              |   77 ---
 ...x-crash-on-empty-UDP-packets-CVE-2014-397.patch |   58 ---
 pulseaudio-4.0-kde_autostart_phase.patch           |   16 -
 pulseaudio-x11_device_manager.patch                |   14 -
 pulseaudio.spec                                    |   55 ++-
 sources                                            |    2 +-
 10 files changed, 642 insertions(+), 227 deletions(-)
---
diff --git a/0001-bluez5-device-use-get_profile_direction.patch b/0001-bluez5-device-use-get_profile_direction.patch
new file mode 100644
index 0000000..d447c31
--- /dev/null
+++ b/0001-bluez5-device-use-get_profile_direction.patch
@@ -0,0 +1,74 @@
+From def5cd8f4a7e29dd52c93308bfcaf9d0a33b5232 Mon Sep 17 00:00:00 2001
+From: Wim Taymans <wtaymans at redhat.com>
+Date: Mon, 1 Sep 2014 10:43:46 +0200
+Subject: [PATCH 1/3] bluez5-device: use get_profile_direction
+
+Use the get_profile_direction() helper function to decide when to add a
+source and a sink instead of enumerating profiles.
+---
+ src/modules/bluetooth/module-bluez5-device.c | 32 +++++++++++++---------------
+ 1 file changed, 15 insertions(+), 17 deletions(-)
+
+diff --git a/src/modules/bluetooth/module-bluez5-device.c b/src/modules/bluetooth/module-bluez5-device.c
+index 48e498b..15731d1 100644
+--- a/src/modules/bluetooth/module-bluez5-device.c
++++ b/src/modules/bluetooth/module-bluez5-device.c
+@@ -1210,6 +1210,19 @@ static int setup_transport(struct userdata *u) {
+ }
+ 
+ /* Run from main thread */
++static pa_direction_t get_profile_direction(pa_bluetooth_profile_t p) {
++    static const pa_direction_t profile_direction[] = {
++        [PA_BLUETOOTH_PROFILE_A2DP_SINK] = PA_DIRECTION_OUTPUT,
++        [PA_BLUETOOTH_PROFILE_A2DP_SOURCE] = PA_DIRECTION_INPUT,
++        [PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
++        [PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
++        [PA_BLUETOOTH_PROFILE_OFF] = 0
++    };
++
++    return profile_direction[p];
++}
++
++/* Run from main thread */
+ static int init_profile(struct userdata *u) {
+     int r = 0;
+     pa_assert(u);
+@@ -1220,13 +1233,11 @@ static int init_profile(struct userdata *u) {
+ 
+     pa_assert(u->transport);
+ 
+-    if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT ||
+-        u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY)
++    if (get_profile_direction (u->profile) & PA_DIRECTION_OUTPUT)
+         if (add_sink(u) < 0)
+             r = -1;
+ 
+-    if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT ||
+-        u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY)
++    if (get_profile_direction (u->profile) & PA_DIRECTION_INPUT)
+         if (add_source(u) < 0)
+             r = -1;
+ 
+@@ -1546,19 +1557,6 @@ static char *cleanup_name(const char *name) {
+ }
+ 
+ /* Run from main thread */
+-static pa_direction_t get_profile_direction(pa_bluetooth_profile_t p) {
+-    static const pa_direction_t profile_direction[] = {
+-        [PA_BLUETOOTH_PROFILE_A2DP_SINK] = PA_DIRECTION_OUTPUT,
+-        [PA_BLUETOOTH_PROFILE_A2DP_SOURCE] = PA_DIRECTION_INPUT,
+-        [PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
+-        [PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
+-        [PA_BLUETOOTH_PROFILE_OFF] = 0
+-    };
+-
+-    return profile_direction[p];
+-}
+-
+-/* Run from main thread */
+ static pa_available_t get_port_availability(struct userdata *u, pa_direction_t direction) {
+     pa_available_t result = PA_AVAILABLE_NO;
+     unsigned i;
+-- 
+2.1.0
+
diff --git a/0002-bluez5-util-add-dispose-function.patch b/0002-bluez5-util-add-dispose-function.patch
new file mode 100644
index 0000000..70b4941
--- /dev/null
+++ b/0002-bluez5-util-add-dispose-function.patch
@@ -0,0 +1,48 @@
+From 91164da48032b078783defaa3cf1f1e173525af0 Mon Sep 17 00:00:00 2001
+From: Wim Taymans <wtaymans at redhat.com>
+Date: Mon, 1 Sep 2014 13:12:27 +0200
+Subject: [PATCH 2/3] bluez5-util: add dispose function
+
+Add a dispose function to the transport that is called before freeing
+the transport. Useful for cleaning up extra userdata.
+---
+ src/modules/bluetooth/bluez5-util.c | 2 ++
+ src/modules/bluetooth/bluez5-util.h | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c
+index 1ee2f33..50f977e 100644
+--- a/src/modules/bluetooth/bluez5-util.c
++++ b/src/modules/bluetooth/bluez5-util.c
+@@ -205,6 +205,8 @@ void pa_bluetooth_transport_unlink(pa_bluetooth_transport *t) {
+ void pa_bluetooth_transport_free(pa_bluetooth_transport *t) {
+     pa_assert(t);
+ 
++    if (t->dispose)
++        t->dispose (t);
+     pa_bluetooth_transport_unlink(t);
+ 
+     pa_xfree(t->owner);
+diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h
+index 8db4a17..fde2e78 100644
+--- a/src/modules/bluetooth/bluez5-util.h
++++ b/src/modules/bluetooth/bluez5-util.h
+@@ -60,6 +60,7 @@ typedef enum pa_bluetooth_transport_state {
+ 
+ typedef int (*pa_bluetooth_transport_acquire_cb)(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu);
+ typedef void (*pa_bluetooth_transport_release_cb)(pa_bluetooth_transport *t);
++typedef void (*pa_bluetooth_transport_dispose_cb)(pa_bluetooth_transport *t);
+ 
+ struct pa_bluetooth_transport {
+     pa_bluetooth_device *device;
+@@ -76,6 +77,7 @@ struct pa_bluetooth_transport {
+ 
+     pa_bluetooth_transport_acquire_cb acquire;
+     pa_bluetooth_transport_release_cb release;
++    pa_bluetooth_transport_dispose_cb dispose;
+     void *userdata;
+ };
+ 
+-- 
+2.1.0
+
diff --git a/0003-backend-native-add-a-new-native-headset-backend.patch b/0003-backend-native-add-a-new-native-headset-backend.patch
new file mode 100644
index 0000000..407d1c6
--- /dev/null
+++ b/0003-backend-native-add-a-new-native-headset-backend.patch
@@ -0,0 +1,490 @@
+From 682329bb2fc4dc337bf980aae86aa9fa1b6608ab Mon Sep 17 00:00:00 2001
+From: Wim Taymans <wtaymans at redhat.com>
+Date: Mon, 1 Sep 2014 15:18:22 +0200
+Subject: [PATCH 3/3] backend-native: add a new native headset backend
+
+Add a simple native headset backend that implements support for the
+blutooth HSP profile.
+This allows pulseaudio to output audio to a Headset using the HSP profile.
+
+Make the native backend the default.
+---
+ configure.ac                           |   6 +-
+ src/modules/bluetooth/backend-native.c | 443 +++++++++++++++++++++++++++++++++
+ 2 files changed, 446 insertions(+), 3 deletions(-)
+ create mode 100644 src/modules/bluetooth/backend-native.c
+
+diff --git a/configure.ac b/configure.ac
+index 74bea71..9a595cb 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1032,14 +1032,14 @@ AM_CONDITIONAL([HAVE_BLUEZ], [test "x$HAVE_BLUEZ" = x1])
+ ## Bluetooth Headset profiles backend ##
+ 
+ AC_ARG_WITH(bluetooth_headset_backend,
+-    AS_HELP_STRING([--with-bluetooth-headset-backend=<ofono|null>],[Backend for Bluetooth headset profiles (ofono)]))
++    AS_HELP_STRING([--with-bluetooth-headset-backend=<ofono|native|null>],[Backend for Bluetooth headset profiles (native)]))
+ if test -z "$with_bluetooth_headset_backend" ; then
+-    BLUETOOTH_HEADSET_BACKEND=ofono
++    BLUETOOTH_HEADSET_BACKEND=native
+ else
+     BLUETOOTH_HEADSET_BACKEND=$with_bluetooth_headset_backend
+ fi
+ 
+-AS_IF([test "x$BLUETOOTH_HEADSET_BACKEND" != "xofono" && test "x$BLUETOOTH_HEADSET_BACKEND" != "xnull"],
++AS_IF([test "x$BLUETOOTH_HEADSET_BACKEND" != "xofono" && test "x$BLUETOOTH_HEADSET_BACKEND" != "xnull" && test "x$BLUETOOTH_HEADSET_BACKEND" != "xnative"],
+     [AC_MSG_ERROR([*** Invalid Bluetooth Headset backend])])
+ 
+ AC_SUBST(BLUETOOTH_HEADSET_BACKEND)
+diff --git a/src/modules/bluetooth/backend-native.c b/src/modules/bluetooth/backend-native.c
+new file mode 100644
+index 0000000..b3c4220
+--- /dev/null
++++ b/src/modules/bluetooth/backend-native.c
+@@ -0,0 +1,443 @@
++/***
++  This file is part of PulseAudio.
++
++  Copyright 2014 Wim Taymans <wim.taymans at gmail.com>
++
++  PulseAudio is free software; you can redistribute it and/or modify
++  it under the terms of the GNU Lesser General Public License as
++  published by the Free Software Foundation; either version 2.1 of the
++  License, or (at your option) any later version.
++
++  PulseAudio is distributed in the hope that it will be useful, but
++  WITHOUT ANY WARRANTY; without even the implied warranty of
++  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++  General Public License for more details.
++
++  You should have received a copy of the GNU Lesser General Public
++  License along with PulseAudio; if not, write to the Free Software
++  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
++  USA.
++***/
++
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <pulsecore/shared.h>
++#include <pulsecore/core-error.h>
++#include <pulsecore/core-util.h>
++#include <pulsecore/dbus-shared.h>
++#include <pulsecore/log.h>
++
++#include <errno.h>
++#include <sys/types.h>
++#include <sys/socket.h>
++
++#include <bluetooth/bluetooth.h>
++#include <bluetooth/sco.h>
++
++#include "bluez5-util.h"
++
++struct pa_bluetooth_backend {
++  pa_core *core;
++  pa_dbus_connection *connection;
++  pa_bluetooth_discovery *discovery;
++
++  PA_LLIST_HEAD(pa_dbus_pending, pending);
++};
++
++struct transport_rfcomm {
++    int rfcomm_fd;
++    pa_io_event *rfcomm_io;
++    pa_mainloop_api *mainloop;
++};
++
++#define BLUEZ_SERVICE "org.bluez"
++#define BLUEZ_MEDIA_TRANSPORT_INTERFACE BLUEZ_SERVICE ".MediaTransport1"
++
++#define BLUEZ_ERROR_NOT_SUPPORTED "org.bluez.Error.NotSupported"
++
++#define BLUEZ_PROFILE_MANAGER_INTERFACE BLUEZ_SERVICE ".ProfileManager1"
++#define BLUEZ_PROFILE_INTERFACE BLUEZ_SERVICE ".Profile1"
++
++#define HSP_AG_PROFILE "/Profile/HSPAGProfile"
++
++#define PROFILE_INTROSPECT_XML                                          \
++    DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE                           \
++    "<node>"                                                            \
++    " <interface name=\"" BLUEZ_PROFILE_INTERFACE "\">"                 \
++    "  <method name=\"Release\">"                                       \
++    "  </method>"                                                       \
++    "  <method name=\"RequestDisconnection\">"                          \
++    "   <arg name=\"device\" direction=\"in\" type=\"o\"/>"             \
++    "  </method>"                                                       \
++    "  <method name=\"NewConnection\">"                                 \
++    "   <arg name=\"device\" direction=\"in\" type=\"o\"/>"             \
++    "   <arg name=\"fd\" direction=\"in\" type=\"h\"/>"                 \
++    "   <arg name=\"opts\" direction=\"in\" type=\"a{sv}\"/>"           \
++    "  </method>"                                                       \
++    " </interface>"                                                     \
++    " <interface name=\"org.freedesktop.DBus.Introspectable\">"         \
++    "  <method name=\"Introspect\">"                                    \
++    "   <arg name=\"data\" type=\"s\" direction=\"out\"/>"              \
++    "  </method>"                                                       \
++    " </interface>"                                                     \
++    "</node>"
++
++static pa_dbus_pending* send_and_add_to_pending(pa_bluetooth_backend *backend, DBusMessage *m,
++                                                DBusPendingCallNotifyFunction func, void *call_data) {
++    pa_dbus_pending *p;
++    DBusPendingCall *call;
++
++    pa_assert(backend);
++    pa_assert(m);
++
++    pa_assert_se(dbus_connection_send_with_reply(pa_dbus_connection_get(backend->connection), m, &call, -1));
++
++    p = pa_dbus_pending_new(pa_dbus_connection_get(backend->connection), m, call, backend, call_data);
++    PA_LLIST_PREPEND(pa_dbus_pending, backend->pending, p);
++    dbus_pending_call_set_notify(call, func, p, NULL);
++
++    return p;
++}
++
++static int bluez5_sco_acquire_cb(pa_bluetooth_transport *t, bool optional, size_t *imtu, size_t *omtu) {
++    pa_bluetooth_device *d = t->device;
++    struct sockaddr_sco addr;
++    int err, i;
++    int sock;
++    bdaddr_t src;
++    bdaddr_t dst;
++    const char *src_addr, *dst_addr;
++
++    src_addr = d->adapter->address;
++    dst_addr = d->address;
++
++    for (i = 5; i >= 0; i--, src_addr += 3)
++        src.b[i] = strtol(src_addr, NULL, 16);
++    for (i = 5; i >= 0; i--, dst_addr += 3)
++        dst.b[i] = strtol(dst_addr, NULL, 16);
++
++    sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
++    if (sock < 0) {
++        pa_log_error("socket(SEQPACKET, SCO) %s", pa_cstrerror(errno));
++        return -1;
++    }
++
++    memset(&addr, 0, sizeof(addr));
++    addr.sco_family = AF_BLUETOOTH;
++    bacpy(&addr.sco_bdaddr, &src);
++
++    if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
++        pa_log_error("bind(): %s", pa_cstrerror(errno));
++        goto fail_close;
++    }
++
++    memset(&addr, 0, sizeof(addr));
++    addr.sco_family = AF_BLUETOOTH;
++    bacpy(&addr.sco_bdaddr, &dst);
++
++    pa_log_info ("doing connect\n");
++    err = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
++    if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS)) {
++        pa_log_error("connect(): %s", pa_cstrerror(errno));
++        goto fail_close;
++    }
++
++    if (imtu)
++        *imtu = 48;
++
++    if (omtu)
++        *omtu = 48;
++
++    return sock;
++
++fail_close:
++    close(sock);
++    return -1;
++}
++
++static void bluez5_sco_release_cb(pa_bluetooth_transport *t) {
++    pa_log_info("Transport %s released", t->path);
++    /* device will close the SCO socket for us */
++}
++
++static void register_profile_reply(DBusPendingCall *pending, void *userdata) {
++    DBusMessage *r;
++    pa_dbus_pending *p;
++    pa_bluetooth_backend *b;
++    char *profile;
++
++    pa_assert(pending);
++    pa_assert_se(p = userdata);
++    pa_assert_se(b = p->context_data);
++    pa_assert_se(profile = p->call_data);
++    pa_assert_se(r = dbus_pending_call_steal_reply(pending));
++
++    if (dbus_message_is_error(r, BLUEZ_ERROR_NOT_SUPPORTED)) {
++        pa_log_info("Couldn't register profile %s because it is disabled in BlueZ", profile);
++        goto finish;
++    }
++
++    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
++        pa_log_error(BLUEZ_PROFILE_MANAGER_INTERFACE ".RegisterProfile() failed: %s: %s", dbus_message_get_error_name(r),
++                     pa_dbus_get_error_message(r));
++        goto finish;
++    }
++
++finish:
++    dbus_message_unref(r);
++
++    PA_LLIST_REMOVE(pa_dbus_pending, b->pending, p);
++    pa_dbus_pending_free(p);
++
++    pa_xfree(profile);
++}
++
++static void register_profile(pa_bluetooth_backend *b, const char *profile, const char *uuid) {
++    DBusMessage *m;
++    DBusMessageIter i, d;
++
++    pa_log_debug("Registering Profile %s", profile);
++
++    pa_assert_se(m = dbus_message_new_method_call(BLUEZ_SERVICE, "/org/bluez", BLUEZ_PROFILE_MANAGER_INTERFACE, "RegisterProfile"));
++
++    dbus_message_iter_init_append(m, &i);
++    dbus_message_iter_append_basic(&i, DBUS_TYPE_OBJECT_PATH, &profile);
++    dbus_message_iter_append_basic(&i, DBUS_TYPE_STRING, &uuid);
++    dbus_message_iter_open_container(&i, DBUS_TYPE_ARRAY, DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING
++                                         DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &d);
++    dbus_message_iter_close_container(&i, &d);
++
++    send_and_add_to_pending(b, m, register_profile_reply, pa_xstrdup(profile));
++}
++
++static void rfcomm_io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void*userdata) {
++    pa_bluetooth_transport *t = userdata;
++
++    pa_assert(io);
++    pa_assert(t);
++
++    if (events & (PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR)) {
++        pa_log("Lost RFCOMM connection.");
++        goto fail;
++    }
++
++    if (events & PA_IO_EVENT_INPUT) {
++        char buf[512];
++        ssize_t len;
++
++        len = read (fd, buf, 511);
++        buf[len] = 0;
++        pa_log("RFCOMM << %s", buf);
++
++        pa_log("RFCOMM >> OK");
++        len = write (fd, "\r\nOK\r\n", 5);
++        /* we ignore any errors, it's not critical and real errors should
++         * be caught with the HANGUP and ERROR events handled above */
++        if (len < 0)
++            pa_log_error("RFCOMM write error: %s", pa_cstrerror(errno));
++    }
++    return;
++
++fail:
++    pa_bluetooth_transport_unlink(t);
++    pa_bluetooth_transport_free(t);
++    return;
++}
++
++static void transport_dispose(pa_bluetooth_transport *t) {
++    struct transport_rfcomm *trfc = t->userdata;
++
++    trfc->mainloop->io_free(trfc->rfcomm_io);
++    shutdown (trfc->rfcomm_fd, SHUT_RDWR);
++    close (trfc->rfcomm_fd);
++
++    pa_xfree(trfc);
++}
++
++
++static DBusMessage *profile_new_connection(DBusConnection *conn, DBusMessage *m, void *userdata) {
++    pa_bluetooth_backend *b = userdata;
++    pa_bluetooth_device *d;
++    pa_bluetooth_transport *t;
++    pa_bluetooth_profile_t p;
++    DBusMessage *r;
++    int fd;
++    const char *sender, *path, *handler;
++    DBusMessageIter arg_i;
++    char *pathfd;
++    struct transport_rfcomm *trfc;
++
++    if (!dbus_message_iter_init(m, &arg_i) || !pa_streq(dbus_message_get_signature(m), "oha{sv}")) {
++        pa_log_error("Invalid signature found in NewConnection");
++        goto fail;
++    }
++
++    handler = dbus_message_get_path(m);
++    pa_assert (pa_streq(handler, HSP_AG_PROFILE));
++
++    pa_assert(dbus_message_iter_get_arg_type(&arg_i) == DBUS_TYPE_OBJECT_PATH);
++    dbus_message_iter_get_basic(&arg_i, &path);
++
++    d = pa_bluetooth_discovery_get_device_by_path(b->discovery, path);
++    if (d == NULL) {
++        pa_log_error("Device doesnt exist for %s", path);
++        goto fail;
++    }
++
++    pa_assert_se(dbus_message_iter_next(&arg_i));
++
++    pa_assert(dbus_message_iter_get_arg_type(&arg_i) == DBUS_TYPE_UNIX_FD);
++    dbus_message_iter_get_basic(&arg_i, &fd);
++
++    pa_log_debug("dbus: NewConnection path=%s, fd=%d", path, fd);
++
++    sender = dbus_message_get_sender(m);
++
++    p = PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT;
++    pathfd = pa_sprintf_malloc ("%s/fd%d", path, fd);
++    d->transports[p] = t = pa_bluetooth_transport_new(d, sender, pathfd, p, NULL, 0);
++    pa_xfree(pathfd);
++
++    t->acquire = bluez5_sco_acquire_cb;
++    t->release = bluez5_sco_release_cb;
++    t->dispose = transport_dispose;
++
++    trfc =  pa_xnew0(struct transport_rfcomm, 1);
++    trfc->rfcomm_fd = fd;
++    trfc->mainloop = b->core->mainloop;
++    trfc->rfcomm_io = trfc->mainloop->io_new(b->core->mainloop, fd, PA_IO_EVENT_INPUT|PA_IO_EVENT_HANGUP,
++        rfcomm_io_callback, t);
++    t->userdata =  trfc;
++
++    pa_bluetooth_transport_put(t);
++
++    pa_log_debug("Transport %s available for profile %s", t->path, pa_bluetooth_profile_to_string(t->profile));
++
++    pa_assert_se(r = dbus_message_new_method_return(m));
++
++    return r;
++
++fail:
++    pa_assert_se(r = dbus_message_new_error(m, "org.bluez.Error.InvalidArguments", "Unable to handle new connection"));
++    return r;
++}
++
++static DBusMessage *profile_request_disconnection(DBusConnection *conn, DBusMessage *m, void *userdata) {
++    DBusMessage *r;
++
++    pa_assert_se(r = dbus_message_new_method_return(m));
++
++    return r;
++}
++
++static DBusHandlerResult profile_handler(DBusConnection *c, DBusMessage *m, void *userdata) {
++    pa_bluetooth_backend *b = userdata;
++    DBusMessage *r = NULL;
++    const char *path, *interface, *member;
++
++    pa_assert(b);
++
++    path = dbus_message_get_path(m);
++    interface = dbus_message_get_interface(m);
++    member = dbus_message_get_member(m);
++
++    pa_log_debug("dbus: path=%s, interface=%s, member=%s", path, interface, member);
++
++    if (!pa_streq(path, HSP_AG_PROFILE))
++        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
++
++    if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
++        const char *xml = PROFILE_INTROSPECT_XML;
++
++        pa_assert_se(r = dbus_message_new_method_return(m));
++        pa_assert_se(dbus_message_append_args(r, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID));
++
++    } else if (dbus_message_is_method_call(m, BLUEZ_PROFILE_INTERFACE, "Release")) {
++    } else if (dbus_message_is_method_call(m, BLUEZ_PROFILE_INTERFACE, "RequestDisconnection")) {
++        r = profile_request_disconnection(c, m, userdata);
++    } else if (dbus_message_is_method_call(m, BLUEZ_PROFILE_INTERFACE, "NewConnection"))
++        r = profile_new_connection(c, m, userdata);
++    else
++        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
++
++    if (r) {
++        pa_assert_se(dbus_connection_send(pa_dbus_connection_get(b->connection), r, NULL));
++        dbus_message_unref(r);
++    }
++
++    return DBUS_HANDLER_RESULT_HANDLED;
++}
++
++static void profile_init(pa_bluetooth_backend *b, pa_bluetooth_profile_t profile) {
++    static const DBusObjectPathVTable vtable_profile = {
++        .message_function = profile_handler,
++    };
++    const char *object_name;
++    const char *uuid;
++
++    pa_assert(b);
++
++    switch(profile) {
++        case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
++            object_name = HSP_AG_PROFILE;
++            uuid = PA_BLUETOOTH_UUID_HSP_AG;
++            break;
++        default:
++            pa_assert_not_reached();
++            break;
++    }
++    pa_assert_se(dbus_connection_register_object_path(pa_dbus_connection_get(b->connection),
++                  object_name, &vtable_profile, b));
++    register_profile (b, object_name, uuid);
++}
++
++static void profile_done(pa_bluetooth_backend *b, pa_bluetooth_profile_t profile) {
++    pa_assert(b);
++
++    switch(profile) {
++        case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
++            dbus_connection_unregister_object_path(pa_dbus_connection_get(b->connection), HSP_AG_PROFILE);
++            break;
++        default:
++            pa_assert_not_reached();
++            break;
++    }
++}
++
++pa_bluetooth_backend *pa_bluetooth_backend_new(pa_core *c, pa_bluetooth_discovery *y) {
++    pa_bluetooth_backend *backend;
++    DBusError err;
++
++    pa_log_debug("Bluetooth Headset Backend API support using the NULL backend");
++
++    backend = pa_xnew0(pa_bluetooth_backend, 1);
++    backend->core = c;
++
++    dbus_error_init(&err);
++    if (!(backend->connection = pa_dbus_bus_get(c, DBUS_BUS_SYSTEM, &err))) {
++        pa_log("Failed to get D-Bus connection: %s", err.message);
++        dbus_error_free(&err);
++        pa_xfree(backend);
++        return NULL;
++    }
++
++    backend->discovery = y;
++
++    profile_init(backend, PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT);
++
++    return backend;
++}
++
++void pa_bluetooth_backend_free(pa_bluetooth_backend *backend) {
++    pa_assert(backend);
++
++    pa_dbus_free_pending_list(&backend->pending);
++
++    profile_done(backend, PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT);
++
++    pa_dbus_connection_unref(backend->connection);
++
++    pa_xfree(backend);
++}
+-- 
+2.1.0
+
diff --git a/pulseaudio.spec b/pulseaudio.spec
index bb56447..5057abe 100644
--- a/pulseaudio.spec
+++ b/pulseaudio.spec
@@ -1,9 +1,10 @@
 %global pa_major   5.0
 #global pa_minor   0
 
-#global gitrel     266
-#global gitcommit  f81e3e1d7852c05b4b737ac7dac4db95798f0117
-#global shortcommit %(c=%{gitcommit}; echo ${c:0:5})
+%global snap       20141019
+%global gitrel     287
+%global gitcommit  4971dc9ed695256cfb179c5ef4d7bf43d3826ba2
+%global shortcommit %(c=%{gitcommit}; echo ${c:0:5})
 
 %ifarch %{ix86} x86_64 %{arm}
 %global with_webrtc 1
@@ -18,7 +19,7 @@
 Name:           pulseaudio
 Summary:        Improved Linux Sound Server
 Version:        %{pa_major}%{?pa_minor:.%{pa_minor}}
-Release:        10%{?gitcommit:.git%{shortcommit}}%{?dist}
+Release:        20%{?snap:.%{snap}git%{shortcommit}}%{?dist}
 License:        LGPLv2+
 URL:            http://www.freedesktop.org/wiki/Software/PulseAudio
 %if 0%{?gitrel}
@@ -31,17 +32,12 @@ Source0:        http://freedesktop.org/software/pulseaudio/releases/pulseaudio-%
 Source1:        default.pa-for-gdm
 
 ## upstream patches
-# https://bugzilla.redhat.com/show_bug.cgi?id=1035025
-# https://bugs.freedesktop.org/show_bug.cgi?id=73375
-Patch036: 0036-module-switch-on-port-available-Don-t-switch-profile.patch
-Patch039: 0039-Name-HDMI-outputs-uniquely.patch
-Patch112: 0112-rtp-recv-fix-crash-on-empty-UDP-packets-CVE-2014-397.patch
 
 ## upstreamable patches
-# simplify and ship only 1 autostart file
-Patch501: pulseaudio-x11_device_manager.patch
-# set X-KDE-autostart-phase=1
-Patch502: pulseaudio-4.0-kde_autostart_phase.patch
+# WIP bluetooth headset work from http://cgit.freedesktop.org/~wtay/pulseaudio/log/?h=headset2
+Patch1: 0001-bluez5-device-use-get_profile_direction.patch
+Patch2: 0002-bluez5-util-add-dispose-function.patch
+Patch3: 0003-backend-native-add-a-new-native-headset-backend.patch
 
 BuildRequires:  m4
 BuildRequires:  libtool-ltdl-devel
@@ -220,15 +216,16 @@ Requires(pre):  gdm
 %description gdm-hooks
 This package contains GDM integration hooks for the PulseAudio sound server.
 
+
 %prep
 %setup -q -T -b0 -n %{name}-%{version}%{?gitrel:-%{gitrel}-g%{shortcommit}}
 
-%patch036 -p1 -b .0036
-%patch039 -p1 -b .0039
-%patch112 -p1 -b .0112
+%patch1 -p1 -b .0001
+%patch2 -p1 -b .0002
+%patch3 -p1 -b .0003
 
-%patch501 -p1 -b .x11_device_manager
-%patch502 -p1 -b .kde_autostart_phase
+# needed by patch3
+./bootstrap.sh
 
 sed -i.no_consolekit -e \
   's/^load-module module-console-kit/#load-module module-console-kit/' \
@@ -244,9 +241,10 @@ sed -i -e 's|"/lib /usr/lib|"/%{_lib} %{_libdir}|' configure
 %endif
 %endif
 
-%build
 
+%build
 %configure \
+  --disable-silent-rules \
   --disable-static \
   --disable-rpath \
   --with-system-user=pulse \
@@ -270,6 +268,7 @@ sed -i -e 's|"/lib /usr/lib|"/%{_lib} %{_libdir}|' configure
 make %{?_smp_mflags} V=1
 make doxygen
 
+
 %install
 make install DESTDIR=$RPM_BUILD_ROOT
 
@@ -300,9 +299,6 @@ install -p -m644 -D %{SOURCE1} $RPM_BUILD_ROOT%{_localstatedir}/lib/gdm/.pulse/d
 rm -fv $RPM_BUILD_ROOT%{_libdir}/*.la $RPM_BUILD_ROOT%{_libdir}/pulse-%{pa_major}/modules/*.la
 # PA_MODULE_DEPRECATED("Please use module-udev-detect instead of module-detect!");
 rm -fv $RPM_BUILD_ROOT%{_libdir}/pulse-%{pa_major}/modules/module-detect.so
-# x11_device_manager folds -kde functionality into single -x11 autostart, so this
-# one is no longer needed
-rm -fv $RPM_BUILD_ROOT%{_sysconfdir}/xdg/autostart/pulseaudio-kde.desktop
 
 %find_lang %{name}
 
@@ -442,6 +438,9 @@ exit 0
 %{_prefix}/lib/udev/rules.d/90-pulseaudio.rules
 %dir %{_libexecdir}/pulse
 %attr(0700, pulse, pulse) %dir %{_localstatedir}/lib/pulse
+%dir %{_datadir}/zsh/
+%dir %{_datadir}/zsh/site-functions/
+%{_datadir}/zsh/site-functions/_pulseaudio
 
 %files qpaeq
 %{_bindir}/qpaeq
@@ -458,15 +457,12 @@ exit 0
 
 %files module-x11
 %{_sysconfdir}/xdg/autostart/pulseaudio.desktop
-## no longer included per x11_device_manager.patch
-#config %{_sysconfdir}/xdg/autostart/pulseaudio-kde.desktop
-%{_bindir}/start-pulseaudio-kde
+#{_bindir}/start-pulseaudio-kde
 %{_bindir}/start-pulseaudio-x11
 %{_libdir}/pulse-%{pa_major}/modules/module-x11-bell.so
 %{_libdir}/pulse-%{pa_major}/modules/module-x11-publish.so
 %{_libdir}/pulse-%{pa_major}/modules/module-x11-xsmp.so
 %{_libdir}/pulse-%{pa_major}/modules/module-x11-cork-request.so
-%{_mandir}/man1/start-pulseaudio-kde.1.gz
 %{_mandir}/man1/start-pulseaudio-x11.1.gz
 
 %files module-zeroconf
@@ -529,6 +525,9 @@ exit 0
 %{_datadir}/vala/vapi/libpulse.deps
 %{_datadir}/vala/vapi/libpulse-mainloop-glib.vapi
 %{_datadir}/vala/vapi/libpulse-mainloop-glib.deps
+%{_datadir}/vala/vapi/libpulse-simple.deps
+%{_datadir}/vala/vapi/libpulse-simple.vapi
+
 %dir %{_libdir}/cmake
 %{_libdir}/cmake/PulseAudio/
 
@@ -558,7 +557,11 @@ exit 0
 %attr(0700, gdm, gdm) %dir %{_localstatedir}/lib/gdm/.pulse
 %attr(0600, gdm, gdm) %{_localstatedir}/lib/gdm/.pulse/default.pa
 
+
 %changelog
+* Wed Oct 22 2014 Rex Dieter <rdieter at fedoraproject.org> 5.0-20.20141007git4971d
+- snapshot, with wip bt headset2 patches (#1045548,#1067470)
+
 * Sun Aug 17 2014 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 5.0-10
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
 
diff --git a/sources b/sources
index d75a87f..f54d595 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-c43749838612f4860465e83ed62ca38e  pulseaudio-5.0.tar.xz
+8872ddac114237c314887dafb526a928  pulseaudio-5.0-287-g4971d.tar.xz


More information about the scm-commits mailing list