SHA256
1
0
forked from pool/pulseaudio

Accepting request 912469 from home:oholecek:branches:multimedia:libs

- Update to PulseAudio 15
  - drop esound compat support
  - drop gconf support
  - convert to mason build system
  - disable doxygen doc generation
  - dropped patches:
      drop bluetooth patches integrated in release:
       0001-bluetooth-use-consistent-profile-names.patch
       0002-bluetooth-separate-HSP-and-HFP.patch
       0003-bluetooth-add-correct-HFP-rfcomm-negotiation.patch
       0004-bluetooth-make-native-the-default-backend.patch
       0005-bluetooth-enable-module-bluez5-discover-argument-ena.patch
       0006-bluetooth-fix-headset-auto-ofono-handover.patch
       0007-bluetooth-prefer-headset-HFP-HF-connection-with-nati.patch
       0008-bluetooth-complete-bluetooth-profile-separation.patch
       0009-bluetooth-use-device-flag-to-prevent-assertion-failu.patch
       0010-bluetooth-rename-enable_hs_role-to-enable_shared_pro.patch
       0011-bluetooth-clean-up-rfcomm_write-usage.patch
      drop parecord patches integrated in release
       parecord-fix-Failed-to-open-audio-file-for-FLAC-and-.patch
       parecord-really-fix-recording-OGG.patch
  - refresh disabled-start.diff patch
  - new features:
   * Support for LDAC and AptX bluetooth codecs, plus "SBC XQ" (SBC with higher-quality parameters)
   * Support for HFP bluetooth profiles
   * Support for Bluetooth A2DP AVRCP Absolute Volume
   * ALSA path configuration files can now be placed in user home directory
   * module-virtual-surround-sink rewritten
   * More options for module-jackdbus-detect
   * Improved hardware support
     * SteelSeries Arctis 9
     * HP Thunderbolt Dock 120W G2
     * Behringer U-Phoria UMC22
     * OnePlus Type-C Bullets
     * Sennheiser GSX 1000/1200 PRO
   * New udev variable: PULSE_MODARGS
   * max_latency_msec argument added to module-null-source
   * module-filter-apply can take filter parameters from device properties
   * module-match can now be loaded multiple times
   * Improvements to FreeBSD support
   * Windows support added to Meson
   * Additional commands for pactl
   * Card profiles can be set to sticky
   * The startup script can now read additional configuration from the /etc/pulse/default.pa.d/ directory
   ** Notes for application developers
   * New API for sending messages from clients to PulseAudio objects
   * New mechanism for applications to disable shared memory on their connection to PulseAudio
  ( https://www.freedesktop.org/wiki/Software/PulseAudio/Notes/15.0/ )

OBS-URL: https://build.opensuse.org/request/show/912469
OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/pulseaudio?expand=0&rev=240
This commit is contained in:
Takashi Iwai 2021-08-17 07:37:02 +00:00 committed by Git OBS Bridge
parent 7b55b57381
commit 0478a78359
18 changed files with 97 additions and 2306 deletions

View File

@ -1,397 +0,0 @@
From 709909a1fca31e9a00883e724c533832a4d4349d Mon Sep 17 00:00:00 2001
From: James Bottomley <James.Bottomley@HansenPartnership.com>
Date: Sat, 20 Aug 2016 10:39:30 -0700
Subject: [PATCH 01/11] bluetooth: use consistent profile names
The PA_BLUETOOTH_PROFILE names should mirror the PA_BLUETOOTH_UUID
names using profile_function instead of randomly made up names. Fix
this with the transformation:
PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT -> PA_BLUETOOTH_PROFILE_HSP_HS
PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY -> PA_BLUETOOTH_PROFILE_HFP_AG
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
---
v4: update for PA 11.0
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/491>
---
src/modules/bluetooth/backend-native.c | 28 +++++++-------
src/modules/bluetooth/backend-ofono.c | 4 +-
src/modules/bluetooth/bluez5-util.c | 10 ++---
src/modules/bluetooth/bluez5-util.h | 4 +-
src/modules/bluetooth/module-bluez5-device.c | 54 +++++++++++++--------------
5 files changed, 50 insertions(+), 50 deletions(-)
--- a/src/modules/bluetooth/backend-native.c
+++ b/src/modules/bluetooth/backend-native.c
@@ -449,7 +449,7 @@ static void set_speaker_gain(pa_bluetoot
/* If we are in the AG role, we send a command to the head set to change
* the speaker gain. In the HS role, source and sink are swapped, so
* in this case we notify the AG that the microphone gain has changed */
- if (t->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT) {
+ if (t->profile == PA_BLUETOOTH_PROFILE_HSP_HS) {
len = sprintf(buf, "\r\n+VGS=%d\r\n", gain);
pa_log_debug("RFCOMM >> +VGS=%d", gain);
} else {
@@ -476,7 +476,7 @@ static void set_microphone_gain(pa_bluet
/* If we are in the AG role, we send a command to the head set to change
* the microphone gain. In the HS role, source and sink are swapped, so
* in this case we notify the AG that the speaker gain has changed */
- if (t->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT) {
+ if (t->profile == PA_BLUETOOTH_PROFILE_HSP_HS) {
len = sprintf(buf, "\r\n+VGM=%d\r\n", gain);
pa_log_debug("RFCOMM >> +VGM=%d", gain);
} else {
@@ -509,9 +509,9 @@ static DBusMessage *profile_new_connecti
handler = dbus_message_get_path(m);
if (pa_streq(handler, HSP_AG_PROFILE)) {
- p = PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT;
+ p = PA_BLUETOOTH_PROFILE_HSP_HS;
} else if (pa_streq(handler, HSP_HS_PROFILE)) {
- p = PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY;
+ p = PA_BLUETOOTH_PROFILE_HFP_AG;
} else {
pa_log_error("Invalid handler");
goto fail;
@@ -626,11 +626,11 @@ static void profile_init(pa_bluetooth_ba
pa_assert(b);
switch (profile) {
- case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
+ case PA_BLUETOOTH_PROFILE_HSP_HS:
object_name = HSP_AG_PROFILE;
uuid = PA_BLUETOOTH_UUID_HSP_AG;
break;
- case PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY:
+ case PA_BLUETOOTH_PROFILE_HFP_AG:
object_name = HSP_HS_PROFILE;
uuid = PA_BLUETOOTH_UUID_HSP_HS;
break;
@@ -647,10 +647,10 @@ static void profile_done(pa_bluetooth_ba
pa_assert(b);
switch (profile) {
- case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
+ case PA_BLUETOOTH_PROFILE_HSP_HS:
dbus_connection_unregister_object_path(pa_dbus_connection_get(b->connection), HSP_AG_PROFILE);
break;
- case PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY:
+ case PA_BLUETOOTH_PROFILE_HFP_AG:
dbus_connection_unregister_object_path(pa_dbus_connection_get(b->connection), HSP_HS_PROFILE);
break;
default:
@@ -665,9 +665,9 @@ void pa_bluetooth_native_backend_enable_
return;
if (enable_hs_role)
- profile_init(native_backend, PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY);
+ profile_init(native_backend, PA_BLUETOOTH_PROFILE_HFP_AG);
else
- profile_done(native_backend, PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY);
+ profile_done(native_backend, PA_BLUETOOTH_PROFILE_HFP_AG);
native_backend->enable_hs_role = enable_hs_role;
}
@@ -693,8 +693,8 @@ pa_bluetooth_backend *pa_bluetooth_nativ
backend->enable_hs_role = enable_hs_role;
if (enable_hs_role)
- profile_init(backend, PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY);
- profile_init(backend, PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT);
+ profile_init(backend, PA_BLUETOOTH_PROFILE_HFP_AG);
+ profile_init(backend, PA_BLUETOOTH_PROFILE_HSP_HS);
return backend;
}
@@ -705,8 +705,8 @@ void pa_bluetooth_native_backend_free(pa
pa_dbus_free_pending_list(&backend->pending);
if (backend->enable_hs_role)
- profile_done(backend, PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY);
- profile_done(backend, PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT);
+ profile_done(backend, PA_BLUETOOTH_PROFILE_HFP_AG);
+ profile_done(backend, PA_BLUETOOTH_PROFILE_HSP_HS);
pa_dbus_connection_unref(backend->connection);
--- a/src/modules/bluetooth/backend-ofono.c
+++ b/src/modules/bluetooth/backend-ofono.c
@@ -303,7 +303,7 @@ static void hf_audio_agent_card_found(pa
const char *key, *value;
struct hf_audio_card *card;
pa_bluetooth_device *d;
- pa_bluetooth_profile_t p = PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY;
+ pa_bluetooth_profile_t p = PA_BLUETOOTH_PROFILE_HFP_AG;
pa_assert(backend);
pa_assert(path);
@@ -337,7 +337,7 @@ static void hf_audio_agent_card_found(pa
card->local_address = pa_xstrdup(value);
} else if (pa_streq(key, "Type")) {
if (pa_streq(value, "gateway"))
- p = PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT;
+ p = PA_BLUETOOTH_PROFILE_HSP_HS;
}
pa_log_debug("%s: %s", key, value);
--- a/src/modules/bluetooth/bluez5-util.c
+++ b/src/modules/bluetooth/bluez5-util.c
@@ -176,11 +176,11 @@ static bool device_supports_profile(pa_b
return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_A2DP_SINK);
case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_A2DP_SOURCE);
- case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
+ case PA_BLUETOOTH_PROFILE_HSP_HS:
return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS)
|| !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS_ALT)
|| !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_HF);
- case PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY:
+ case PA_BLUETOOTH_PROFILE_HFP_AG:
return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_AG)
|| !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_AG);
case PA_BLUETOOTH_PROFILE_OFF:
@@ -1021,7 +1021,7 @@ void pa_bluetooth_discovery_set_ofono_ru
pa_bluetooth_device *d;
PA_HASHMAP_FOREACH(d, y->devices, state) {
- if (device_supports_profile(d, PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY)) {
+ if (device_supports_profile(d, PA_BLUETOOTH_PROFILE_HFP_AG)) {
DBusMessage *m;
pa_assert_se(m = dbus_message_new_method_call(BLUEZ_SERVICE, d->path, "org.bluez.Device1", "Disconnect"));
@@ -1265,9 +1265,9 @@ const char *pa_bluetooth_profile_to_stri
return "a2dp_sink";
case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
return "a2dp_source";
- case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
+ case PA_BLUETOOTH_PROFILE_HSP_HS:
return "headset_head_unit";
- case PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY:
+ case PA_BLUETOOTH_PROFILE_HFP_AG:
return "headset_audio_gateway";
case PA_BLUETOOTH_PROFILE_OFF:
return "off";
--- a/src/modules/bluetooth/bluez5-util.h
+++ b/src/modules/bluetooth/bluez5-util.h
@@ -57,8 +57,8 @@ typedef enum pa_bluetooth_hook {
typedef enum profile {
PA_BLUETOOTH_PROFILE_A2DP_SINK,
PA_BLUETOOTH_PROFILE_A2DP_SOURCE,
- PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT,
- PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY,
+ PA_BLUETOOTH_PROFILE_HSP_HS,
+ PA_BLUETOOTH_PROFILE_HFP_AG,
PA_BLUETOOTH_PROFILE_OFF
} pa_bluetooth_profile_t;
#define PA_BLUETOOTH_PROFILE_COUNT PA_BLUETOOTH_PROFILE_OFF
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -253,8 +253,8 @@ static int sco_process_render(struct use
int saved_errno;
pa_assert(u);
- pa_assert(u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT ||
- u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY);
+ pa_assert(u->profile == PA_BLUETOOTH_PROFILE_HSP_HS ||
+ u->profile == PA_BLUETOOTH_PROFILE_HFP_AG);
pa_assert(u->sink);
pa_sink_render_full(u->sink, u->write_block_size, &memchunk);
@@ -323,8 +323,8 @@ static int sco_process_push(struct userd
pa_usec_t tstamp = 0;
pa_assert(u);
- pa_assert(u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT ||
- u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY);
+ pa_assert(u->profile == PA_BLUETOOTH_PROFILE_HSP_HS ||
+ u->profile == PA_BLUETOOTH_PROFILE_HFP_AG);
pa_assert(u->source);
pa_assert(u->read_smoother);
@@ -767,7 +767,7 @@ static void handle_sink_block_size_chang
/* Run from I/O thread */
static void transport_config_mtu(struct userdata *u) {
- if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY) {
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
u->read_block_size = u->read_link_mtu;
u->write_block_size = u->write_link_mtu;
@@ -984,7 +984,7 @@ static void source_set_volume_cb(pa_sour
pa_cvolume_set(&s->real_volume, u->decoder_sample_spec.channels, volume);
/* Set soft volume when in headset role */
- if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY)
+ if (u->profile == PA_BLUETOOTH_PROFILE_HFP_AG)
pa_cvolume_set(&s->soft_volume, u->decoder_sample_spec.channels, volume);
/* If we are in the AG role, we send a command to the head set to change
@@ -1007,7 +1007,7 @@ static int add_source(struct userdata *u
data.namereg_fail = false;
pa_proplist_sets(data.proplist, "bluetooth.protocol", pa_bluetooth_profile_to_string(u->profile));
pa_source_new_data_set_sample_spec(&data, &u->decoder_sample_spec);
- if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT)
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS)
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
connect_ports(u, &data, PA_DIRECTION_INPUT);
@@ -1015,10 +1015,10 @@ static int add_source(struct userdata *u
if (!u->transport_acquired)
switch (u->profile) {
case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
- case PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY:
+ case PA_BLUETOOTH_PROFILE_HFP_AG:
data.suspend_cause = PA_SUSPEND_USER;
break;
- case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
+ case PA_BLUETOOTH_PROFILE_HSP_HS:
/* u->stream_fd contains the error returned by the last transport_acquire()
* EAGAIN means we are waiting for a NewConnection signal */
if (u->stream_fd == -EAGAIN)
@@ -1043,7 +1043,7 @@ static int add_source(struct userdata *u
u->source->parent.process_msg = source_process_msg;
u->source->set_state_in_io_thread = source_set_state_in_io_thread_cb;
- if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY) {
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
pa_source_set_set_volume_callback(u->source, source_set_volume_cb);
u->source->n_volume_steps = 16;
}
@@ -1168,7 +1168,7 @@ static void sink_set_volume_cb(pa_sink *
pa_cvolume_set(&s->real_volume, u->encoder_sample_spec.channels, volume);
/* Set soft volume when in headset role */
- if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY)
+ if (u->profile == PA_BLUETOOTH_PROFILE_HFP_AG)
pa_cvolume_set(&s->soft_volume, u->encoder_sample_spec.channels, volume);
/* If we are in the AG role, we send a command to the head set to change
@@ -1191,17 +1191,17 @@ static int add_sink(struct userdata *u)
data.namereg_fail = false;
pa_proplist_sets(data.proplist, "bluetooth.protocol", pa_bluetooth_profile_to_string(u->profile));
pa_sink_new_data_set_sample_spec(&data, &u->encoder_sample_spec);
- if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT)
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS)
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
connect_ports(u, &data, PA_DIRECTION_OUTPUT);
if (!u->transport_acquired)
switch (u->profile) {
- case PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY:
+ case PA_BLUETOOTH_PROFILE_HFP_AG:
data.suspend_cause = PA_SUSPEND_USER;
break;
- case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
+ case PA_BLUETOOTH_PROFILE_HSP_HS:
/* u->stream_fd contains the error returned by the last transport_acquire()
* EAGAIN means we are waiting for a NewConnection signal */
if (u->stream_fd == -EAGAIN)
@@ -1228,7 +1228,7 @@ static int add_sink(struct userdata *u)
u->sink->parent.process_msg = sink_process_msg;
u->sink->set_state_in_io_thread = sink_set_state_in_io_thread_cb;
- if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY) {
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
u->sink->n_volume_steps = 16;
}
@@ -1237,7 +1237,7 @@ static int add_sink(struct userdata *u)
/* Run from main thread */
static int transport_config(struct userdata *u) {
- if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY) {
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
u->encoder_sample_spec.format = PA_SAMPLE_S16LE;
u->encoder_sample_spec.channels = 1;
u->encoder_sample_spec.rate = 8000;
@@ -1288,7 +1288,7 @@ static int setup_transport(struct userda
u->transport = t;
- if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY)
+ if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG)
transport_acquire(u, true); /* In case of error, the sink/sources will be created suspended */
else {
int transport_error;
@@ -1306,8 +1306,8 @@ static pa_direction_t get_profile_direct
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_HSP_HS] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
+ [PA_BLUETOOTH_PROFILE_HFP_AG] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
[PA_BLUETOOTH_PROFILE_OFF] = 0
};
@@ -1621,7 +1621,7 @@ static int start_thread(struct userdata
/* If we are in the headset role, the sink should not become default
* unless there is no other sound device available. */
- if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY)
+ if (u->profile == PA_BLUETOOTH_PROFILE_HFP_AG)
u->sink->priority = 1500;
pa_sink_put(u->sink);
@@ -1637,7 +1637,7 @@ static int start_thread(struct userdata
/* If we are in the headset role or the device is an a2dp source,
* the source should not become default unless there is no other
* sound device available. */
- if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY || u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE)
+ if (u->profile == PA_BLUETOOTH_PROFILE_HFP_AG || u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE)
u->source->priority = 1500;
pa_source_put(u->source);
@@ -1898,7 +1898,7 @@ static pa_card_profile *create_card_prof
p = PA_CARD_PROFILE_DATA(cp);
break;
- case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
+ case PA_BLUETOOTH_PROFILE_HSP_HS:
cp = pa_card_profile_new(name, _("Headset Head Unit (HSP/HFP)"), sizeof(pa_bluetooth_profile_t));
cp->priority = 30;
cp->n_sinks = 1;
@@ -1911,7 +1911,7 @@ static pa_card_profile *create_card_prof
p = PA_CARD_PROFILE_DATA(cp);
break;
- case PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY:
+ case PA_BLUETOOTH_PROFILE_HFP_AG:
cp = pa_card_profile_new(name, _("Headset Audio Gateway (HSP/HFP)"), sizeof(pa_bluetooth_profile_t));
cp->priority = 10;
cp->n_sinks = 1;
@@ -1986,9 +1986,9 @@ static int uuid_to_profile(const char *u
else if (pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SOURCE))
*_r = PA_BLUETOOTH_PROFILE_A2DP_SOURCE;
else if (pa_bluetooth_uuid_is_hsp_hs(uuid) || pa_streq(uuid, PA_BLUETOOTH_UUID_HFP_HF))
- *_r = PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT;
+ *_r = PA_BLUETOOTH_PROFILE_HSP_HS;
else if (pa_streq(uuid, PA_BLUETOOTH_UUID_HSP_AG) || pa_streq(uuid, PA_BLUETOOTH_UUID_HFP_AG))
- *_r = PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY;
+ *_r = PA_BLUETOOTH_PROFILE_HFP_AG;
else
return -PA_ERR_INVALID;
@@ -2199,7 +2199,7 @@ static pa_hook_result_t transport_speake
volume++;
pa_cvolume_set(&v, u->encoder_sample_spec.channels, volume);
- if (t->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT)
+ if (t->profile == PA_BLUETOOTH_PROFILE_HSP_HS)
pa_sink_volume_changed(u->sink, &v);
else
pa_sink_set_volume(u->sink, &v, true, true);
@@ -2227,7 +2227,7 @@ static pa_hook_result_t transport_microp
pa_cvolume_set(&v, u->decoder_sample_spec.channels, volume);
- if (t->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT)
+ if (t->profile == PA_BLUETOOTH_PROFILE_HSP_HS)
pa_source_volume_changed(u->source, &v);
else
pa_source_set_volume(u->source, &v, true, true);

View File

@ -1,490 +0,0 @@
From 66ed99a13da289f25bdb8381d30cfb5f82f9cab6 Mon Sep 17 00:00:00 2001
From: James Bottomley <James.Bottomley@HansenPartnership.com>
Date: Thu, 18 Aug 2016 08:48:48 -0700
Subject: [PATCH 02/11] bluetooth: separate HSP and HFP
When all headsets supported both HSP and HFP, life was good and we
only needed to implement HSP in the native backend. Unfortunately
some headsets have started supporting HFP only. Unfortuantely, we
can't simply switch to HFP only because that might break older HSP
only headsets meaning we need to support both HSP and HFP separately.
This patch separates them from a joint profile to being two separate
ones. The older one retains the headset_head_unit name, meaning any
saved parameters will still select this (keeping us backward
compatible). It also introduces a new headset_handsfree.
For headsets that support both HSP and HFP, the two profiles will
become separately visible and selectable. This will only matter once
we start adding features to HFP that HSP can't support (like wideband
audio).
Signed-off-by: <James.Bottomley@HansenPartnership.com>
---
v6:
- merge profile switching fixes patch from Rodrigo Araujo
v5:
- rename option to enable_native_hfp_hf
- don't call profile_done for HFP_HF unless it was initialised
v3:
- Update for PA 11.0
v2:
- fold in review feedback
- add global disable option for not registering HFP
v3:
- change parameter to enable_profile_hfp
- update device_supports_profile to be aware of hfp/hsp exclusivity
- change parameter to enable_profile_hfp_hf
bluetooth: separate HSP and HFP (to me merged with this patch)
Hi.
First, just to say that your patches are going great. Finally I can use
the microphone of my HFP only headset (a version of a Bluedio T2+).
So far, I've only encontered one problem: the auto_switch option of
module_bluetooth_policy stops working. Dug through the code and I think
you missed a few spots were you have to hangle the new headset_handsfree
profile in module_bluetooth_policy.c
Applying the following after applying your v5 patches fixed the issue
for me, now when I start making a VOIP call the profile switches to
headset_handsfree and the mic works automatically, and when the call
finishes it reverts back to a2dp.
Thanks and best regards.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/491>
---
src/modules/bluetooth/backend-native.c | 17 ++++++
src/modules/bluetooth/bluez5-util.c | 34 ++++++++++++-
src/modules/bluetooth/bluez5-util.h | 4 +
src/modules/bluetooth/module-bluetooth-policy.c | 10 ++--
src/modules/bluetooth/module-bluez5-device.c | 60 ++++++++++++++++++++----
src/modules/bluetooth/module-bluez5-discover.c | 6 ++
6 files changed, 112 insertions(+), 19 deletions(-)
--- a/src/modules/bluetooth/backend-native.c
+++ b/src/modules/bluetooth/backend-native.c
@@ -62,6 +62,7 @@ struct transport_data {
#define BLUEZ_PROFILE_INTERFACE BLUEZ_SERVICE ".Profile1"
#define HSP_AG_PROFILE "/Profile/HSPAGProfile"
+#define HFP_AG_PROFILE "/Profile/HFPAGProfile"
#define HSP_HS_PROFILE "/Profile/HSPHSProfile"
/* RFCOMM channel for HSP headset role
@@ -512,6 +513,8 @@ static DBusMessage *profile_new_connecti
p = PA_BLUETOOTH_PROFILE_HSP_HS;
} else if (pa_streq(handler, HSP_HS_PROFILE)) {
p = PA_BLUETOOTH_PROFILE_HFP_AG;
+ } else if (pa_streq(handler, HFP_AG_PROFILE)) {
+ p = PA_BLUETOOTH_PROFILE_HFP_HF;
} else {
pa_log_error("Invalid handler");
goto fail;
@@ -589,7 +592,8 @@ static DBusHandlerResult profile_handler
pa_log_debug("dbus: path=%s, interface=%s, member=%s", path, interface, member);
- if (!pa_streq(path, HSP_AG_PROFILE) && !pa_streq(path, HSP_HS_PROFILE))
+ if (!pa_streq(path, HSP_AG_PROFILE) && !pa_streq(path, HSP_HS_PROFILE)
+ && !pa_streq(path, HFP_AG_PROFILE))
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
@@ -634,6 +638,10 @@ static void profile_init(pa_bluetooth_ba
object_name = HSP_HS_PROFILE;
uuid = PA_BLUETOOTH_UUID_HSP_HS;
break;
+ case PA_BLUETOOTH_PROFILE_HFP_HF:
+ object_name = HFP_AG_PROFILE;
+ uuid = PA_BLUETOOTH_UUID_HFP_AG;
+ break;
default:
pa_assert_not_reached();
break;
@@ -653,6 +661,9 @@ static void profile_done(pa_bluetooth_ba
case PA_BLUETOOTH_PROFILE_HFP_AG:
dbus_connection_unregister_object_path(pa_dbus_connection_get(b->connection), HSP_HS_PROFILE);
break;
+ case PA_BLUETOOTH_PROFILE_HFP_HF:
+ dbus_connection_unregister_object_path(pa_dbus_connection_get(b->connection), HFP_AG_PROFILE);
+ break;
default:
pa_assert_not_reached();
break;
@@ -695,6 +706,8 @@ pa_bluetooth_backend *pa_bluetooth_nativ
if (enable_hs_role)
profile_init(backend, PA_BLUETOOTH_PROFILE_HFP_AG);
profile_init(backend, PA_BLUETOOTH_PROFILE_HSP_HS);
+ if (pa_bluetooth_discovery_get_enable_native_hfp_hf(y))
+ profile_init(backend, PA_BLUETOOTH_PROFILE_HFP_HF);
return backend;
}
@@ -707,6 +720,8 @@ void pa_bluetooth_native_backend_free(pa
if (backend->enable_hs_role)
profile_done(backend, PA_BLUETOOTH_PROFILE_HFP_AG);
profile_done(backend, PA_BLUETOOTH_PROFILE_HSP_HS);
+ if (pa_bluetooth_discovery_get_enable_native_hfp_hf(backend->discovery))
+ profile_done(backend, PA_BLUETOOTH_PROFILE_HFP_HF);
pa_dbus_connection_unref(backend->connection);
--- a/src/modules/bluetooth/bluez5-util.c
+++ b/src/modules/bluetooth/bluez5-util.c
@@ -94,6 +94,7 @@ struct pa_bluetooth_discovery {
int headset_backend;
pa_bluetooth_backend *ofono_backend, *native_backend;
PA_LLIST_HEAD(pa_dbus_pending, pending);
+ bool enable_native_hfp_hf;
};
static pa_dbus_pending* send_and_add_to_pending(pa_bluetooth_discovery *y, DBusMessage *m,
@@ -171,15 +172,29 @@ static const char *transport_state_to_st
}
static bool device_supports_profile(pa_bluetooth_device *device, pa_bluetooth_profile_t profile) {
+ bool show_hfp, show_hsp, enable_native_hfp_hf;
+
+ enable_native_hfp_hf = pa_bluetooth_discovery_get_enable_native_hfp_hf(device->discovery);
+
+ if (enable_native_hfp_hf) {
+ show_hfp = pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_HF);
+ show_hsp = !show_hfp;
+ } else {
+ show_hfp = false;
+ show_hsp = true;
+ }
+
switch (profile) {
case PA_BLUETOOTH_PROFILE_A2DP_SINK:
return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_A2DP_SINK);
case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_A2DP_SOURCE);
case PA_BLUETOOTH_PROFILE_HSP_HS:
- return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS)
- || !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS_ALT)
- || !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_HF);
+ return show_hsp
+ && ( !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS)
+ || !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS_ALT));
+ case PA_BLUETOOTH_PROFILE_HFP_HF:
+ return show_hfp && !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_HF);
case PA_BLUETOOTH_PROFILE_HFP_AG:
return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_AG)
|| !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_AG);
@@ -539,6 +554,14 @@ pa_bluetooth_device* pa_bluetooth_discov
return NULL;
}
+bool pa_bluetooth_discovery_get_enable_native_hfp_hf(pa_bluetooth_discovery *y)
+{
+ pa_assert(y);
+ pa_assert(PA_REFCNT_VALUE(y) > 0);
+
+ return y->enable_native_hfp_hf;
+}
+
pa_bluetooth_device* pa_bluetooth_discovery_get_device_by_address(pa_bluetooth_discovery *y, const char *remote, const char *local) {
pa_bluetooth_device *d;
void *state = NULL;
@@ -1267,6 +1290,8 @@ const char *pa_bluetooth_profile_to_stri
return "a2dp_source";
case PA_BLUETOOTH_PROFILE_HSP_HS:
return "headset_head_unit";
+ case PA_BLUETOOTH_PROFILE_HFP_HF:
+ return "headset_handsfree";
case PA_BLUETOOTH_PROFILE_HFP_AG:
return "headset_audio_gateway";
case PA_BLUETOOTH_PROFILE_OFF:
@@ -1582,7 +1607,7 @@ static void endpoint_done(pa_bluetooth_d
dbus_connection_unregister_object_path(pa_dbus_connection_get(y->connection), endpoint);
}
-pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c, int headset_backend) {
+pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c, int headset_backend, bool enable_native_hfp_hf) {
pa_bluetooth_discovery *y;
DBusError err;
DBusConnection *conn;
@@ -1594,6 +1619,7 @@ pa_bluetooth_discovery* pa_bluetooth_dis
PA_REFCNT_INIT(y);
y->core = c;
y->headset_backend = headset_backend;
+ y->enable_native_hfp_hf = enable_native_hfp_hf;
y->adapters = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL,
(pa_free_cb_t) adapter_free);
y->devices = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL,
--- a/src/modules/bluetooth/bluez5-util.h
+++ b/src/modules/bluetooth/bluez5-util.h
@@ -58,6 +58,7 @@ typedef enum profile {
PA_BLUETOOTH_PROFILE_A2DP_SINK,
PA_BLUETOOTH_PROFILE_A2DP_SOURCE,
PA_BLUETOOTH_PROFILE_HSP_HS,
+ PA_BLUETOOTH_PROFILE_HFP_HF,
PA_BLUETOOTH_PROFILE_HFP_AG,
PA_BLUETOOTH_PROFILE_OFF
} pa_bluetooth_profile_t;
@@ -178,8 +179,9 @@ static inline bool pa_bluetooth_uuid_is_
#define HEADSET_BACKEND_NATIVE 1
#define HEADSET_BACKEND_AUTO 2
-pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *core, int headset_backend);
+pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *core, int headset_backend, bool default_profile_hfp);
pa_bluetooth_discovery* pa_bluetooth_discovery_ref(pa_bluetooth_discovery *y);
void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y);
void pa_bluetooth_discovery_set_ofono_running(pa_bluetooth_discovery *y, bool is_running);
+bool pa_bluetooth_discovery_get_enable_native_hfp_hf(pa_bluetooth_discovery *y);
#endif
--- a/src/modules/bluetooth/module-bluetooth-policy.c
+++ b/src/modules/bluetooth/module-bluetooth-policy.c
@@ -156,7 +156,7 @@ static void card_set_profile(struct user
if (!pa_streq(profile->name, "a2dp_sink"))
continue;
} else {
- if (!pa_streq(profile->name, "headset_head_unit"))
+ if (!pa_streq(profile->name, "headset_head_unit") && !pa_streq(profile->name, "headset_handsfree"))
continue;
}
@@ -191,7 +191,7 @@ static void switch_profile(pa_card *card
return;
/* Skip card if does not have active hsp profile */
- if (!pa_streq(card->active_profile->name, "headset_head_unit"))
+ if (!pa_streq(card->active_profile->name, "headset_head_unit") && !pa_streq(card->active_profile->name, "headset_handsfree"))
return;
/* Skip card if already has active a2dp profile */
@@ -203,7 +203,7 @@ static void switch_profile(pa_card *card
return;
/* Skip card if already has active hsp profile */
- if (pa_streq(card->active_profile->name, "headset_head_unit"))
+ if (pa_streq(card->active_profile->name, "headset_head_unit") || pa_streq(card->active_profile->name, "headset_handsfree"))
return;
}
@@ -358,7 +358,9 @@ static pa_hook_result_t profile_availabl
return PA_HOOK_OK;
/* Do not automatically switch profiles for headsets, just in case */
- if (pa_streq(profile->name, "a2dp_sink") || pa_streq(profile->name, "headset_head_unit"))
+ if (pa_streq(profile->name, "a2dp_sink") ||
+ pa_streq(profile->name, "headset_head_unit") ||
+ pa_streq(profile->name, "headset_handsfree"))
return PA_HOOK_OK;
is_active_profile = card->active_profile == profile;
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -254,6 +254,7 @@ static int sco_process_render(struct use
pa_assert(u);
pa_assert(u->profile == PA_BLUETOOTH_PROFILE_HSP_HS ||
+ u->profile == PA_BLUETOOTH_PROFILE_HFP_HF ||
u->profile == PA_BLUETOOTH_PROFILE_HFP_AG);
pa_assert(u->sink);
@@ -324,6 +325,7 @@ static int sco_process_push(struct userd
pa_assert(u);
pa_assert(u->profile == PA_BLUETOOTH_PROFILE_HSP_HS ||
+ u->profile == PA_BLUETOOTH_PROFILE_HFP_HF||
u->profile == PA_BLUETOOTH_PROFILE_HFP_AG);
pa_assert(u->source);
pa_assert(u->read_smoother);
@@ -767,7 +769,9 @@ static void handle_sink_block_size_chang
/* Run from I/O thread */
static void transport_config_mtu(struct userdata *u) {
- if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS
+ || u->profile == PA_BLUETOOTH_PROFILE_HFP_HF
+ || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
u->read_block_size = u->read_link_mtu;
u->write_block_size = u->write_link_mtu;
@@ -1007,7 +1011,8 @@ static int add_source(struct userdata *u
data.namereg_fail = false;
pa_proplist_sets(data.proplist, "bluetooth.protocol", pa_bluetooth_profile_to_string(u->profile));
pa_source_new_data_set_sample_spec(&data, &u->decoder_sample_spec);
- if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS)
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS
+ || u->profile == PA_BLUETOOTH_PROFILE_HFP_HF)
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
connect_ports(u, &data, PA_DIRECTION_INPUT);
@@ -1019,6 +1024,7 @@ static int add_source(struct userdata *u
data.suspend_cause = PA_SUSPEND_USER;
break;
case PA_BLUETOOTH_PROFILE_HSP_HS:
+ case PA_BLUETOOTH_PROFILE_HFP_HF:
/* u->stream_fd contains the error returned by the last transport_acquire()
* EAGAIN means we are waiting for a NewConnection signal */
if (u->stream_fd == -EAGAIN)
@@ -1043,7 +1049,9 @@ static int add_source(struct userdata *u
u->source->parent.process_msg = source_process_msg;
u->source->set_state_in_io_thread = source_set_state_in_io_thread_cb;
- if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS
+ || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG
+ || u->profile == PA_BLUETOOTH_PROFILE_HFP_HF) {
pa_source_set_set_volume_callback(u->source, source_set_volume_cb);
u->source->n_volume_steps = 16;
}
@@ -1191,7 +1199,8 @@ static int add_sink(struct userdata *u)
data.namereg_fail = false;
pa_proplist_sets(data.proplist, "bluetooth.protocol", pa_bluetooth_profile_to_string(u->profile));
pa_sink_new_data_set_sample_spec(&data, &u->encoder_sample_spec);
- if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS)
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS
+ || u->profile == PA_BLUETOOTH_PROFILE_HFP_HF)
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
connect_ports(u, &data, PA_DIRECTION_OUTPUT);
@@ -1202,6 +1211,7 @@ static int add_sink(struct userdata *u)
data.suspend_cause = PA_SUSPEND_USER;
break;
case PA_BLUETOOTH_PROFILE_HSP_HS:
+ case PA_BLUETOOTH_PROFILE_HFP_HF:
/* u->stream_fd contains the error returned by the last transport_acquire()
* EAGAIN means we are waiting for a NewConnection signal */
if (u->stream_fd == -EAGAIN)
@@ -1228,7 +1238,9 @@ static int add_sink(struct userdata *u)
u->sink->parent.process_msg = sink_process_msg;
u->sink->set_state_in_io_thread = sink_set_state_in_io_thread_cb;
- if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS
+ || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG
+ || u->profile == PA_BLUETOOTH_PROFILE_HFP_HF) {
pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
u->sink->n_volume_steps = 16;
}
@@ -1237,7 +1249,9 @@ static int add_sink(struct userdata *u)
/* Run from main thread */
static int transport_config(struct userdata *u) {
- if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS
+ || u->profile == PA_BLUETOOTH_PROFILE_HFP_HF
+ || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
u->encoder_sample_spec.format = PA_SAMPLE_S16LE;
u->encoder_sample_spec.channels = 1;
u->encoder_sample_spec.rate = 8000;
@@ -1307,6 +1321,7 @@ static pa_direction_t get_profile_direct
[PA_BLUETOOTH_PROFILE_A2DP_SINK] = PA_DIRECTION_OUTPUT,
[PA_BLUETOOTH_PROFILE_A2DP_SOURCE] = PA_DIRECTION_INPUT,
[PA_BLUETOOTH_PROFILE_HSP_HS] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
+ [PA_BLUETOOTH_PROFILE_HFP_HF] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
[PA_BLUETOOTH_PROFILE_HFP_AG] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
[PA_BLUETOOTH_PROFILE_OFF] = 0
};
@@ -1899,7 +1914,20 @@ static pa_card_profile *create_card_prof
break;
case PA_BLUETOOTH_PROFILE_HSP_HS:
- cp = pa_card_profile_new(name, _("Headset Head Unit (HSP/HFP)"), sizeof(pa_bluetooth_profile_t));
+ cp = pa_card_profile_new(name, _("Headset Head Unit (HSP)"), sizeof(pa_bluetooth_profile_t));
+ cp->priority = 30;
+ cp->n_sinks = 1;
+ cp->n_sources = 1;
+ cp->max_sink_channels = 1;
+ cp->max_source_channels = 1;
+ pa_hashmap_put(input_port->profiles, cp->name, cp);
+ pa_hashmap_put(output_port->profiles, cp->name, cp);
+
+ p = PA_CARD_PROFILE_DATA(cp);
+ break;
+
+ case PA_BLUETOOTH_PROFILE_HFP_HF:
+ cp = pa_card_profile_new(name, _("Headset Handsfree (HFP)"), sizeof(pa_bluetooth_profile_t));
cp->priority = 30;
cp->n_sinks = 1;
cp->n_sources = 1;
@@ -1985,8 +2013,10 @@ static int uuid_to_profile(const char *u
*_r = PA_BLUETOOTH_PROFILE_A2DP_SINK;
else if (pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SOURCE))
*_r = PA_BLUETOOTH_PROFILE_A2DP_SOURCE;
- else if (pa_bluetooth_uuid_is_hsp_hs(uuid) || pa_streq(uuid, PA_BLUETOOTH_UUID_HFP_HF))
+ else if (pa_bluetooth_uuid_is_hsp_hs(uuid))
*_r = PA_BLUETOOTH_PROFILE_HSP_HS;
+ else if (pa_streq(uuid, PA_BLUETOOTH_UUID_HFP_HF))
+ *_r = PA_BLUETOOTH_PROFILE_HFP_HF;
else if (pa_streq(uuid, PA_BLUETOOTH_UUID_HSP_AG) || pa_streq(uuid, PA_BLUETOOTH_UUID_HFP_AG))
*_r = PA_BLUETOOTH_PROFILE_HFP_AG;
else
@@ -2005,6 +2035,7 @@ static int add_card(struct userdata *u)
pa_bluetooth_profile_t *p;
const char *uuid;
void *state;
+ bool enable_native_hfp_hf, has_both;
pa_assert(u);
pa_assert(u->device);
@@ -2035,9 +2066,22 @@ static int add_card(struct userdata *u)
create_card_ports(u, data.ports);
+ enable_native_hfp_hf = pa_bluetooth_discovery_get_enable_native_hfp_hf(u->discovery);
+
+ has_both = enable_native_hfp_hf && pa_hashmap_get(d->uuids, PA_BLUETOOTH_UUID_HFP_HF) && pa_hashmap_get(d->uuids, PA_BLUETOOTH_UUID_HSP_HS);
PA_HASHMAP_FOREACH(uuid, d->uuids, state) {
pa_bluetooth_profile_t profile;
+ if (!enable_native_hfp_hf && pa_streq(uuid, PA_BLUETOOTH_UUID_HFP_HF)) {
+ pa_log_info("device supports HFP but disabling profile as requested");
+ continue;
+ }
+
+ if (has_both && pa_streq(uuid, PA_BLUETOOTH_UUID_HSP_HS)) {
+ pa_log_info("device support HSP and HFP, selecting HFP only");
+ continue;
+ }
+
if (uuid_to_profile(uuid, &profile) < 0)
continue;
--- a/src/modules/bluetooth/module-bluez5-discover.c
+++ b/src/modules/bluetooth/module-bluez5-discover.c
@@ -103,6 +103,7 @@ int pa__init(pa_module *m) {
const char *headset_str;
int headset_backend;
bool autodetect_mtu;
+ bool enable_native_hfp_hf = true;
pa_assert(m);
@@ -126,6 +127,9 @@ int pa__init(pa_module *m) {
autodetect_mtu = false;
if (pa_modargs_get_value_boolean(ma, "autodetect_mtu", &autodetect_mtu) < 0) {
pa_log("Invalid boolean value for autodetect_mtu parameter");
+ }
+ if (pa_modargs_get_value_boolean(ma, "enable_native_hfp_hf", &enable_native_hfp_hf) < 0) {
+ pa_log("enable_native_hfp_hf must be true or false");
goto fail;
}
@@ -135,7 +139,7 @@ int pa__init(pa_module *m) {
u->autodetect_mtu = autodetect_mtu;
u->loaded_device_paths = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
- if (!(u->discovery = pa_bluetooth_discovery_get(u->core, headset_backend)))
+ if (!(u->discovery = pa_bluetooth_discovery_get(u->core, headset_backend, enable_native_hfp_hf)))
goto fail;
u->device_connection_changed_slot =

View File

@ -1,228 +0,0 @@
From 485a64642e8da895f1b71ccc3d8aee78f5645639 Mon Sep 17 00:00:00 2001
From: James Bottomley <James.Bottomley@HansenPartnership.com>
Date: Sat, 20 Aug 2016 10:56:14 -0700
Subject: [PATCH 03/11] bluetooth: add correct HFP rfcomm negotiation
HFP 1.6 requires a stateful negotiation of AT commands. The prior
version got away with initialising HFP simply by replying 'OK' to
every negotiation attempt. This one actually tries to parse the state
and make sure the negotiation occurs correctly
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
---
v4:
- Update for PA 11.0
- Finally sort out CIND negotiaton for complex headsets
v3:
- remove internal debugging
- added comment for t->config being not null for hfp
- removed unused returns from hfp_rfcomm_handle()
- remove rfcomm comment
- use pa_startswith
- simplify negotiation
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/491>
---
src/modules/bluetooth/backend-native.c | 124 +++++++++++++++++++++++++++++++--
src/modules/bluetooth/bluez5-util.c | 5 +
src/modules/bluetooth/bluez5-util.h | 2
3 files changed, 125 insertions(+), 6 deletions(-)
--- a/src/modules/bluetooth/backend-native.c
+++ b/src/modules/bluetooth/backend-native.c
@@ -61,6 +61,43 @@ struct transport_data {
#define BLUEZ_PROFILE_MANAGER_INTERFACE BLUEZ_SERVICE ".ProfileManager1"
#define BLUEZ_PROFILE_INTERFACE BLUEZ_SERVICE ".Profile1"
+struct hfp_config {
+ uint32_t capabilities;
+ int state;
+};
+
+/*
+ * the separate hansfree headset (HF) and Audio Gateway (AG) features
+ */
+enum hfp_hf_features {
+ HFP_HF_EC_NR = 0,
+ HFP_HF_CALL_WAITING = 1,
+ HFP_HF_CLI = 2,
+ HFP_HF_VR = 3,
+ HFP_HF_RVOL = 4,
+ HFP_HF_ESTATUS = 5,
+ HFP_HF_ECALL = 6,
+ HFP_HF_CODECS = 7,
+};
+
+enum hfp_ag_features {
+ HFP_AG_THREE_WAY = 0,
+ HFP_AG_EC_NR = 1,
+ HFP_AG_VR = 2,
+ HFP_AG_RING = 3,
+ HFP_AG_NUM_TAG = 4,
+ HFP_AG_REJECT = 5,
+ HFP_AG_ESTATUS = 6,
+ HFP_AG_ECALL = 7,
+ HFP_AG_EERR = 8,
+ HFP_AG_CODECS = 9,
+};
+
+/* gateway features we support, which is as little as we can get away with */
+static uint32_t hfp_features =
+ /* HFP 1.6 requires this */
+ (1 << HFP_AG_ESTATUS );
+
#define HSP_AG_PROFILE "/Profile/HSPAGProfile"
#define HFP_AG_PROFILE "/Profile/HFPAGProfile"
#define HSP_HS_PROFILE "/Profile/HSPHSProfile"
@@ -109,6 +146,27 @@ static pa_dbus_pending* send_and_add_to_
return p;
}
+static void rfcomm_write(int fd, const char *str)
+{
+ size_t len;
+ char buf[512];
+
+ pa_log_debug("RFCOMM >> %s", str);
+ sprintf(buf, "\r\n%s\r\n", str);
+ len = write(fd, buf, strlen(buf));
+
+ if (len != strlen(buf))
+ pa_log_error("RFCOMM write error: %s", pa_cstrerror(errno));
+}
+
+static void hfp_send_features(int fd)
+{
+ char buf[512];
+
+ sprintf(buf, "+BRSF: %d", hfp_features);
+ rfcomm_write(fd, buf);
+}
+
static int sco_do_connect(pa_bluetooth_transport *t) {
pa_bluetooth_device *d = t->device;
struct sockaddr_sco addr;
@@ -352,6 +410,61 @@ static void register_profile(pa_bluetoot
send_and_add_to_pending(b, m, register_profile_reply, pa_xstrdup(profile));
}
+static void transport_put(pa_bluetooth_transport *t)
+{
+ pa_bluetooth_transport_put(t);
+
+ pa_log_debug("Transport %s available for profile %s", t->path, pa_bluetooth_profile_to_string(t->profile));
+}
+
+static bool hfp_rfcomm_handle(int fd, pa_bluetooth_transport *t, const char *buf)
+{
+ struct hfp_config *c = t->config;
+ int val;
+
+ /* stateful negotiation */
+ if (c->state == 0 && sscanf(buf, "AT+BRSF=%d", &val) == 1) {
+ c->capabilities = val;
+ pa_log_info("HFP capabilities returns 0x%x", val);
+ hfp_send_features(fd);
+ c->state = 1;
+ return true;
+ } else if (c->state == 1 && pa_startswith(buf, "AT+CIND=?")) {
+ /* we declare minimal no indicators */
+ rfcomm_write(fd, "+CIND: "
+ /* many indicators can be supported, only call and
+ * callheld are mandatory, so that's all we repy */
+ "(\"call\",(0-1)),"
+ "(\"callheld\",(0-2))");
+ c->state = 2;
+ return true;
+ } else if (c->state == 2 && pa_startswith(buf, "AT+CIND?")) {
+ rfcomm_write(fd, "+CIND: 0,0");
+ c->state = 3;
+ return true;
+ } else if ((c->state == 2 || c->state == 3) && pa_startswith(buf, "AT+CMER=")) {
+ rfcomm_write(fd, "\r\nOK\r\n");
+ c->state = 4;
+ transport_put(t);
+ return false;
+ }
+
+ /* if we get here, negotiation should be complete */
+ if (c->state != 4) {
+ pa_log_error("HFP negotiation failed in state %d with inbound %s\n",
+ c->state, buf);
+ rfcomm_write(fd, "ERROR");
+ return false;
+ }
+
+ /*
+ * once we're fully connected, just reply OK to everything
+ * it will just be the headset sending the occasional status
+ * update, but we process only the ones we care about
+ */
+ return true;
+}
+
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;
@@ -398,6 +511,8 @@ static void rfcomm_io_callback(pa_mainlo
do_reply = true;
} else if (sscanf(buf, "AT+CKPD=%d", &dummy) == 1) {
do_reply = true;
+ } else if (t->config) { /* t->config is only non-null for hfp profile */
+ do_reply = hfp_rfcomm_handle(fd, t, buf);
} else {
do_reply = false;
}
@@ -540,7 +655,9 @@ static DBusMessage *profile_new_connecti
sender = dbus_message_get_sender(m);
pathfd = pa_sprintf_malloc ("%s/fd%d", path, fd);
- t = pa_bluetooth_transport_new(d, sender, pathfd, p, NULL, 0);
+ t = pa_bluetooth_transport_new(d, sender, pathfd, p, NULL,
+ p == PA_BLUETOOTH_PROFILE_HFP_HF ?
+ sizeof(struct hfp_config) : 0);
pa_xfree(pathfd);
t->acquire = sco_acquire_cb;
@@ -558,9 +675,8 @@ static DBusMessage *profile_new_connecti
sco_listen(t);
- pa_bluetooth_transport_put(t);
-
- pa_log_debug("Transport %s available for profile %s", t->path, pa_bluetooth_profile_to_string(t->profile));
+ if (p != PA_BLUETOOTH_PROFILE_HFP_HF)
+ transport_put(t);
pa_assert_se(r = dbus_message_new_method_return(m));
--- a/src/modules/bluetooth/bluez5-util.c
+++ b/src/modules/bluetooth/bluez5-util.c
@@ -152,7 +152,10 @@ pa_bluetooth_transport *pa_bluetooth_tra
if (size > 0) {
t->config = pa_xnew(uint8_t, size);
- memcpy(t->config, config, size);
+ if (config)
+ memcpy(t->config, config, size);
+ else
+ memset(t->config, 0, size);
}
return t;
--- a/src/modules/bluetooth/bluez5-util.h
+++ b/src/modules/bluetooth/bluez5-util.h
@@ -84,7 +84,7 @@ struct pa_bluetooth_transport {
pa_bluetooth_profile_t profile;
uint8_t codec;
- uint8_t *config;
+ void *config;
size_t config_size;
const pa_a2dp_codec *a2dp_codec;

View File

@ -1,43 +0,0 @@
From cb193e19ee9dc04b54ee62dfba2b194ec275ad5c Mon Sep 17 00:00:00 2001
From: James Bottomley <James.Bottomley@HansenPartnership.com>
Date: Thu, 21 Sep 2017 11:49:45 -0700
Subject: [PATCH 04/11] bluetooth: make native the default backend
Change default backend from 'auto' to 'native' so that in the usual
install pulseaudio uses the native backend with HFP_HF handling.
set default to false unless the backend is the native one, in which
case the default becomes true.
Additionally set default value of enable_native_hfp_hf to false unless
the backend is the native one, in which case the default becomes
true. so that we only bind the HFP_HF end point in the native case
(leaving it free for ofono in the ofono backend or auto case)
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/491>
---
src/modules/bluetooth/module-bluez5-discover.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/src/modules/bluetooth/module-bluez5-discover.c
+++ b/src/modules/bluetooth/module-bluez5-discover.c
@@ -92,7 +92,7 @@ static pa_hook_result_t device_connectio
}
#ifdef HAVE_BLUEZ_5_NATIVE_HEADSET
-const char *default_headset_backend = "auto";
+const char *default_headset_backend = "native";
#else
const char *default_headset_backend = "ofono";
#endif
@@ -124,6 +124,9 @@ int pa__init(pa_module *m) {
goto fail;
}
+ /* default value if no module parameter */
+ enable_native_hfp_hf = (headset_backend == HEADSET_BACKEND_NATIVE);
+
autodetect_mtu = false;
if (pa_modargs_get_value_boolean(ma, "autodetect_mtu", &autodetect_mtu) < 0) {
pa_log("Invalid boolean value for autodetect_mtu parameter");

View File

@ -1,27 +0,0 @@
From 8491477b3e02c17881abd65818784e268a8e75d6 Mon Sep 17 00:00:00 2001
From: "Igor V. Kovalenko" <igor.v.kovalenko@gmail.com>
Date: Thu, 28 Jan 2021 15:37:36 +0300
Subject: [PATCH 05/11] bluetooth: enable module-bluez5-discover argument
enable_native_hfp_hf
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/491>
---
src/modules/bluetooth/module-bluez5-discover.c | 2 ++
1 file changed, 2 insertions(+)
--- a/src/modules/bluetooth/module-bluez5-discover.c
+++ b/src/modules/bluetooth/module-bluez5-discover.c
@@ -37,11 +37,13 @@ PA_MODULE_LOAD_ONCE(true);
PA_MODULE_USAGE(
"headset=ofono|native|auto"
"autodetect_mtu=<boolean>"
+ "enable_native_hfp_hf=<boolean, enable HFP support in native backend>"
);
static const char* const valid_modargs[] = {
"headset",
"autodetect_mtu",
+ "enable_native_hfp_hf",
NULL
};

View File

@ -1,131 +0,0 @@
From 70171158eeda4e3ae44a6a2dd22b25cc6932dd04 Mon Sep 17 00:00:00 2001
From: "Igor V. Kovalenko" <igor.v.kovalenko@gmail.com>
Date: Thu, 28 Jan 2021 09:08:53 +0300
Subject: [PATCH 06/11] bluetooth: fix headset=auto ofono handover
Native backend implements HFP AG but not HFP HF yet, therefore headset=auto
functionality is still needed if HFP HF is required.
To make headset=auto work again, drop both HFP AG and HSP AG roles while
performing handover from native backend when oFono is detected running.
While at it, restore profile description to Headset Head Unit (HSP/HFP)
to note that HFP may be still provided via oFono backend.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/491>
---
src/modules/bluetooth/backend-native.c | 31 +++++++++++++++++----------
src/modules/bluetooth/bluez5-util.c | 8 +++---
src/modules/bluetooth/module-bluez5-device.c | 2 -
3 files changed, 25 insertions(+), 16 deletions(-)
--- a/src/modules/bluetooth/backend-native.c
+++ b/src/modules/bluetooth/backend-native.c
@@ -41,6 +41,7 @@ struct pa_bluetooth_backend {
pa_dbus_connection *connection;
pa_bluetooth_discovery *discovery;
bool enable_hs_role;
+ bool enable_hfp_hf;
PA_LLIST_HEAD(pa_dbus_pending, pending);
};
@@ -786,15 +787,24 @@ static void profile_done(pa_bluetooth_ba
}
}
+static void native_backend_apply_profile_registration_change(pa_bluetooth_backend *native_backend, bool enable_hs_role) {
+ if (enable_hs_role) {
+ profile_init(native_backend, PA_BLUETOOTH_PROFILE_HFP_AG);
+ if (native_backend->enable_hfp_hf)
+ profile_init(native_backend, PA_BLUETOOTH_PROFILE_HFP_HF);
+ } else {
+ profile_done(native_backend, PA_BLUETOOTH_PROFILE_HFP_AG);
+ if (native_backend->enable_hfp_hf)
+ profile_done(native_backend, PA_BLUETOOTH_PROFILE_HFP_HF);
+ }
+}
+
void pa_bluetooth_native_backend_enable_hs_role(pa_bluetooth_backend *native_backend, bool enable_hs_role) {
if (enable_hs_role == native_backend->enable_hs_role)
return;
- if (enable_hs_role)
- profile_init(native_backend, PA_BLUETOOTH_PROFILE_HFP_AG);
- else
- profile_done(native_backend, PA_BLUETOOTH_PROFILE_HFP_AG);
+ native_backend_apply_profile_registration_change(native_backend, enable_hs_role);
native_backend->enable_hs_role = enable_hs_role;
}
@@ -818,12 +828,12 @@ pa_bluetooth_backend *pa_bluetooth_nativ
backend->discovery = y;
backend->enable_hs_role = enable_hs_role;
+ backend->enable_hfp_hf = pa_bluetooth_discovery_get_enable_native_hfp_hf(y);
+
+ if (backend->enable_hs_role)
+ native_backend_apply_profile_registration_change(backend, true);
- if (enable_hs_role)
- profile_init(backend, PA_BLUETOOTH_PROFILE_HFP_AG);
profile_init(backend, PA_BLUETOOTH_PROFILE_HSP_HS);
- if (pa_bluetooth_discovery_get_enable_native_hfp_hf(y))
- profile_init(backend, PA_BLUETOOTH_PROFILE_HFP_HF);
return backend;
}
@@ -834,10 +844,9 @@ void pa_bluetooth_native_backend_free(pa
pa_dbus_free_pending_list(&backend->pending);
if (backend->enable_hs_role)
- profile_done(backend, PA_BLUETOOTH_PROFILE_HFP_AG);
+ native_backend_apply_profile_registration_change(backend, false);
+
profile_done(backend, PA_BLUETOOTH_PROFILE_HSP_HS);
- if (pa_bluetooth_discovery_get_enable_native_hfp_hf(backend->discovery))
- profile_done(backend, PA_BLUETOOTH_PROFILE_HFP_HF);
pa_dbus_connection_unref(backend->connection);
--- a/src/modules/bluetooth/bluez5-util.c
+++ b/src/modules/bluetooth/bluez5-util.c
@@ -1040,14 +1040,16 @@ void pa_bluetooth_discovery_set_ofono_ru
if (y->headset_backend != HEADSET_BACKEND_AUTO)
return;
- /* If ofono starts running, all devices that might be connected to the HS role
+ pa_bluetooth_native_backend_enable_hs_role(y->native_backend, !is_running);
+
+ /* If ofono starts running, all devices that might be connected to the HS roles or HFP AG role
* need to be disconnected, so that the devices can be handled by ofono */
if (is_running) {
void *state;
pa_bluetooth_device *d;
PA_HASHMAP_FOREACH(d, y->devices, state) {
- if (device_supports_profile(d, PA_BLUETOOTH_PROFILE_HFP_AG)) {
+ if (device_supports_profile(d, PA_BLUETOOTH_PROFILE_HFP_AG) || device_supports_profile(d, PA_BLUETOOTH_PROFILE_HFP_HF)) {
DBusMessage *m;
pa_assert_se(m = dbus_message_new_method_call(BLUEZ_SERVICE, d->path, "org.bluez.Device1", "Disconnect"));
@@ -1057,8 +1059,6 @@ void pa_bluetooth_discovery_set_ofono_ru
}
}
}
-
- pa_bluetooth_native_backend_enable_hs_role(y->native_backend, !is_running);
}
static void get_managed_objects_reply(DBusPendingCall *pending, void *userdata) {
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -1914,7 +1914,7 @@ static pa_card_profile *create_card_prof
break;
case PA_BLUETOOTH_PROFILE_HSP_HS:
- cp = pa_card_profile_new(name, _("Headset Head Unit (HSP)"), sizeof(pa_bluetooth_profile_t));
+ cp = pa_card_profile_new(name, _("Headset Head Unit (HSP/HFP)"), sizeof(pa_bluetooth_profile_t));
cp->priority = 30;
cp->n_sinks = 1;
cp->n_sources = 1;

View File

@ -1,56 +0,0 @@
From 815dd2d6278f17591fa04966b0e4c5a8b102cf0b Mon Sep 17 00:00:00 2001
From: "Igor V. Kovalenko" <igor.v.kovalenko@gmail.com>
Date: Fri, 29 Jan 2021 09:28:36 +0300
Subject: [PATCH 07/11] bluetooth: prefer headset HFP HF connection with native
backend
When HFP HF support is enabled in native backend, peer HFP HF profile connection
is preferred over same peer HSP HS profile connection if peer supports both
profiles.
Enforce the preference by rejecting HSP HS profile connections from such peer.
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/491>
---
src/modules/bluetooth/backend-native.c | 10 ++++++++++
src/modules/bluetooth/module-bluez5-device.c | 10 ----------
2 files changed, 10 insertions(+), 10 deletions(-)
--- a/src/modules/bluetooth/backend-native.c
+++ b/src/modules/bluetooth/backend-native.c
@@ -645,6 +645,16 @@ static DBusMessage *profile_new_connecti
goto fail;
}
+ if (pa_bluetooth_discovery_get_enable_native_hfp_hf(b->discovery)) {
+ if (p == PA_BLUETOOTH_PROFILE_HSP_HS && pa_hashmap_get(d->uuids, PA_BLUETOOTH_UUID_HFP_HF)) {
+ /* If peer connecting to HSP Audio Gateway supports HFP HF profile
+ * reject this connection to force it to connect to HSP Audio Gateway instead.
+ */
+ pa_log_info("HFP HF enabled in native backend and is supported by peer, rejecting HSP HS peer connection");
+ 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);
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -2072,16 +2072,6 @@ static int add_card(struct userdata *u)
PA_HASHMAP_FOREACH(uuid, d->uuids, state) {
pa_bluetooth_profile_t profile;
- if (!enable_native_hfp_hf && pa_streq(uuid, PA_BLUETOOTH_UUID_HFP_HF)) {
- pa_log_info("device supports HFP but disabling profile as requested");
- continue;
- }
-
- if (has_both && pa_streq(uuid, PA_BLUETOOTH_UUID_HSP_HS)) {
- pa_log_info("device support HSP and HFP, selecting HFP only");
- continue;
- }
-
if (uuid_to_profile(uuid, &profile) < 0)
continue;

View File

@ -1,398 +0,0 @@
From 698fb3bc26a679063c081cc3089cd9d515d34a4a Mon Sep 17 00:00:00 2001
From: "Igor V. Kovalenko" <igor.v.kovalenko@gmail.com>
Date: Fri, 29 Jan 2021 21:32:09 +0300
Subject: [PATCH 08/11] bluetooth: complete bluetooth profile separation
This is a follow-up change to review of these series on pulseaudio-discuss
https://lists.freedesktop.org/archives/pulseaudio-discuss/2017-September/028801.html
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/491>
---
src/modules/bluetooth/backend-native.c | 14 +++---
src/modules/bluetooth/backend-ofono.c | 2
src/modules/bluetooth/bluez5-util.c | 11 +++-
src/modules/bluetooth/bluez5-util.h | 1
src/modules/bluetooth/module-bluetooth-policy.c | 18 ++++----
src/modules/bluetooth/module-bluez5-device.c | 54 +++++++++++++++++-------
6 files changed, 64 insertions(+), 36 deletions(-)
--- a/src/modules/bluetooth/backend-native.c
+++ b/src/modules/bluetooth/backend-native.c
@@ -566,7 +566,7 @@ static void set_speaker_gain(pa_bluetoot
/* If we are in the AG role, we send a command to the head set to change
* the speaker gain. In the HS role, source and sink are swapped, so
* in this case we notify the AG that the microphone gain has changed */
- if (t->profile == PA_BLUETOOTH_PROFILE_HSP_HS) {
+ if (t->profile == PA_BLUETOOTH_PROFILE_HSP_HS || t->profile == PA_BLUETOOTH_PROFILE_HFP_HF) {
len = sprintf(buf, "\r\n+VGS=%d\r\n", gain);
pa_log_debug("RFCOMM >> +VGS=%d", gain);
} else {
@@ -593,7 +593,7 @@ static void set_microphone_gain(pa_bluet
/* If we are in the AG role, we send a command to the head set to change
* the microphone gain. In the HS role, source and sink are swapped, so
* in this case we notify the AG that the speaker gain has changed */
- if (t->profile == PA_BLUETOOTH_PROFILE_HSP_HS) {
+ if (t->profile == PA_BLUETOOTH_PROFILE_HSP_HS || t->profile == PA_BLUETOOTH_PROFILE_HFP_HF) {
len = sprintf(buf, "\r\n+VGM=%d\r\n", gain);
pa_log_debug("RFCOMM >> +VGM=%d", gain);
} else {
@@ -628,7 +628,7 @@ static DBusMessage *profile_new_connecti
if (pa_streq(handler, HSP_AG_PROFILE)) {
p = PA_BLUETOOTH_PROFILE_HSP_HS;
} else if (pa_streq(handler, HSP_HS_PROFILE)) {
- p = PA_BLUETOOTH_PROFILE_HFP_AG;
+ p = PA_BLUETOOTH_PROFILE_HSP_AG;
} else if (pa_streq(handler, HFP_AG_PROFILE)) {
p = PA_BLUETOOTH_PROFILE_HFP_HF;
} else {
@@ -761,7 +761,7 @@ static void profile_init(pa_bluetooth_ba
object_name = HSP_AG_PROFILE;
uuid = PA_BLUETOOTH_UUID_HSP_AG;
break;
- case PA_BLUETOOTH_PROFILE_HFP_AG:
+ case PA_BLUETOOTH_PROFILE_HSP_AG:
object_name = HSP_HS_PROFILE;
uuid = PA_BLUETOOTH_UUID_HSP_HS;
break;
@@ -785,7 +785,7 @@ static void profile_done(pa_bluetooth_ba
case PA_BLUETOOTH_PROFILE_HSP_HS:
dbus_connection_unregister_object_path(pa_dbus_connection_get(b->connection), HSP_AG_PROFILE);
break;
- case PA_BLUETOOTH_PROFILE_HFP_AG:
+ case PA_BLUETOOTH_PROFILE_HSP_AG:
dbus_connection_unregister_object_path(pa_dbus_connection_get(b->connection), HSP_HS_PROFILE);
break;
case PA_BLUETOOTH_PROFILE_HFP_HF:
@@ -799,11 +799,11 @@ static void profile_done(pa_bluetooth_ba
static void native_backend_apply_profile_registration_change(pa_bluetooth_backend *native_backend, bool enable_hs_role) {
if (enable_hs_role) {
- profile_init(native_backend, PA_BLUETOOTH_PROFILE_HFP_AG);
+ profile_init(native_backend, PA_BLUETOOTH_PROFILE_HSP_AG);
if (native_backend->enable_hfp_hf)
profile_init(native_backend, PA_BLUETOOTH_PROFILE_HFP_HF);
} else {
- profile_done(native_backend, PA_BLUETOOTH_PROFILE_HFP_AG);
+ profile_done(native_backend, PA_BLUETOOTH_PROFILE_HSP_AG);
if (native_backend->enable_hfp_hf)
profile_done(native_backend, PA_BLUETOOTH_PROFILE_HFP_HF);
}
--- a/src/modules/bluetooth/backend-ofono.c
+++ b/src/modules/bluetooth/backend-ofono.c
@@ -337,7 +337,7 @@ static void hf_audio_agent_card_found(pa
card->local_address = pa_xstrdup(value);
} else if (pa_streq(key, "Type")) {
if (pa_streq(value, "gateway"))
- p = PA_BLUETOOTH_PROFILE_HSP_HS;
+ p = PA_BLUETOOTH_PROFILE_HFP_HF;
}
pa_log_debug("%s: %s", key, value);
--- a/src/modules/bluetooth/bluez5-util.c
+++ b/src/modules/bluetooth/bluez5-util.c
@@ -196,11 +196,12 @@ static bool device_supports_profile(pa_b
return show_hsp
&& ( !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS)
|| !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS_ALT));
+ case PA_BLUETOOTH_PROFILE_HSP_AG:
+ return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_AG);
case PA_BLUETOOTH_PROFILE_HFP_HF:
return show_hfp && !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_HF);
case PA_BLUETOOTH_PROFILE_HFP_AG:
- return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_AG)
- || !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_AG);
+ return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_AG);
case PA_BLUETOOTH_PROFILE_OFF:
pa_assert_not_reached();
}
@@ -1293,10 +1294,12 @@ const char *pa_bluetooth_profile_to_stri
return "a2dp_source";
case PA_BLUETOOTH_PROFILE_HSP_HS:
return "headset_head_unit";
+ case PA_BLUETOOTH_PROFILE_HSP_AG:
+ return "headset_audio_gateway";
case PA_BLUETOOTH_PROFILE_HFP_HF:
- return "headset_handsfree";
+ return "handsfree_head_unit";
case PA_BLUETOOTH_PROFILE_HFP_AG:
- return "headset_audio_gateway";
+ return "handsfree_audio_gateway";
case PA_BLUETOOTH_PROFILE_OFF:
return "off";
}
--- a/src/modules/bluetooth/bluez5-util.h
+++ b/src/modules/bluetooth/bluez5-util.h
@@ -58,6 +58,7 @@ typedef enum profile {
PA_BLUETOOTH_PROFILE_A2DP_SINK,
PA_BLUETOOTH_PROFILE_A2DP_SOURCE,
PA_BLUETOOTH_PROFILE_HSP_HS,
+ PA_BLUETOOTH_PROFILE_HSP_AG,
PA_BLUETOOTH_PROFILE_HFP_HF,
PA_BLUETOOTH_PROFILE_HFP_AG,
PA_BLUETOOTH_PROFILE_OFF
--- a/src/modules/bluetooth/module-bluetooth-policy.c
+++ b/src/modules/bluetooth/module-bluetooth-policy.c
@@ -38,7 +38,7 @@ PA_MODULE_LOAD_ONCE(true);
PA_MODULE_USAGE(
"auto_switch=<Switch between hsp and a2dp profile? (0 - never, 1 - media.role=phone, 2 - heuristic> "
"a2dp_source=<Handle a2dp_source card profile (sink role)?> "
- "ag=<Handle headset_audio_gateway card profile (headset role)?> ");
+ "ag=<Handle headset_audio_gateway or handsfree_audio_gateway card profile (headset role)?> ");
static const char* const valid_modargs[] = {
"auto_switch",
@@ -86,7 +86,7 @@ static pa_hook_result_t source_put_hook_
if (u->enable_a2dp_source && pa_streq(s, "a2dp_source"))
role = "music";
- else if (u->enable_ag && pa_streq(s, "headset_audio_gateway"))
+ else if (u->enable_ag && (pa_streq(s, "headset_audio_gateway") || pa_streq(s, "handsfree_audio_gateway")))
role = "phone";
else {
pa_log_debug("Profile %s cannot be selected for loopback", s);
@@ -125,7 +125,7 @@ static pa_hook_result_t sink_put_hook_ca
if (!s)
return PA_HOOK_OK;
- if (u->enable_ag && pa_streq(s, "headset_audio_gateway"))
+ if (u->enable_ag && (pa_streq(s, "headset_audio_gateway") || pa_streq(s, "handsfree_audio_gateway")))
role = "phone";
else {
pa_log_debug("Profile %s cannot be selected for loopback", s);
@@ -156,7 +156,7 @@ static void card_set_profile(struct user
if (!pa_streq(profile->name, "a2dp_sink"))
continue;
} else {
- if (!pa_streq(profile->name, "headset_head_unit") && !pa_streq(profile->name, "headset_handsfree"))
+ if (!pa_streq(profile->name, "headset_head_unit") && !pa_streq(profile->name, "handsfree_head_unit"))
continue;
}
@@ -190,8 +190,8 @@ static void switch_profile(pa_card *card
if (!pa_hashmap_remove(u->will_need_revert_card_map, card))
return;
- /* Skip card if does not have active hsp profile */
- if (!pa_streq(card->active_profile->name, "headset_head_unit") && !pa_streq(card->active_profile->name, "headset_handsfree"))
+ /* Skip card if does not have active headset profile */
+ if (!pa_streq(card->active_profile->name, "headset_head_unit") && !pa_streq(card->active_profile->name, "handsfree_head_unit"))
return;
/* Skip card if already has active a2dp profile */
@@ -202,8 +202,8 @@ static void switch_profile(pa_card *card
if (!pa_streq(card->active_profile->name, "a2dp_sink"))
return;
- /* Skip card if already has active hsp profile */
- if (pa_streq(card->active_profile->name, "headset_head_unit") || pa_streq(card->active_profile->name, "headset_handsfree"))
+ /* Skip card if already has active headset profile */
+ if (pa_streq(card->active_profile->name, "headset_head_unit") || pa_streq(card->active_profile->name, "handsfree_head_unit"))
return;
}
@@ -360,7 +360,7 @@ static pa_hook_result_t profile_availabl
/* Do not automatically switch profiles for headsets, just in case */
if (pa_streq(profile->name, "a2dp_sink") ||
pa_streq(profile->name, "headset_head_unit") ||
- pa_streq(profile->name, "headset_handsfree"))
+ pa_streq(profile->name, "handsfree_head_unit"))
return PA_HOOK_OK;
is_active_profile = card->active_profile == profile;
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -254,8 +254,9 @@ static int sco_process_render(struct use
pa_assert(u);
pa_assert(u->profile == PA_BLUETOOTH_PROFILE_HSP_HS ||
- u->profile == PA_BLUETOOTH_PROFILE_HFP_HF ||
- u->profile == PA_BLUETOOTH_PROFILE_HFP_AG);
+ u->profile == PA_BLUETOOTH_PROFILE_HSP_AG ||
+ u->profile == PA_BLUETOOTH_PROFILE_HFP_HF ||
+ u->profile == PA_BLUETOOTH_PROFILE_HFP_AG);
pa_assert(u->sink);
pa_sink_render_full(u->sink, u->write_block_size, &memchunk);
@@ -325,8 +326,9 @@ static int sco_process_push(struct userd
pa_assert(u);
pa_assert(u->profile == PA_BLUETOOTH_PROFILE_HSP_HS ||
- u->profile == PA_BLUETOOTH_PROFILE_HFP_HF||
- u->profile == PA_BLUETOOTH_PROFILE_HFP_AG);
+ u->profile == PA_BLUETOOTH_PROFILE_HSP_AG ||
+ u->profile == PA_BLUETOOTH_PROFILE_HFP_HF ||
+ u->profile == PA_BLUETOOTH_PROFILE_HFP_AG);
pa_assert(u->source);
pa_assert(u->read_smoother);
@@ -770,6 +772,7 @@ static void handle_sink_block_size_chang
/* Run from I/O thread */
static void transport_config_mtu(struct userdata *u) {
if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS
+ || u->profile == PA_BLUETOOTH_PROFILE_HSP_AG
|| u->profile == PA_BLUETOOTH_PROFILE_HFP_HF
|| u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
u->read_block_size = u->read_link_mtu;
@@ -988,7 +991,7 @@ static void source_set_volume_cb(pa_sour
pa_cvolume_set(&s->real_volume, u->decoder_sample_spec.channels, volume);
/* Set soft volume when in headset role */
- if (u->profile == PA_BLUETOOTH_PROFILE_HFP_AG)
+ if (u->profile == PA_BLUETOOTH_PROFILE_HFP_AG || u->profile == PA_BLUETOOTH_PROFILE_HSP_AG)
pa_cvolume_set(&s->soft_volume, u->decoder_sample_spec.channels, volume);
/* If we are in the AG role, we send a command to the head set to change
@@ -1021,6 +1024,7 @@ static int add_source(struct userdata *u
switch (u->profile) {
case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
case PA_BLUETOOTH_PROFILE_HFP_AG:
+ case PA_BLUETOOTH_PROFILE_HSP_AG:
data.suspend_cause = PA_SUSPEND_USER;
break;
case PA_BLUETOOTH_PROFILE_HSP_HS:
@@ -1050,6 +1054,7 @@ static int add_source(struct userdata *u
u->source->set_state_in_io_thread = source_set_state_in_io_thread_cb;
if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS
+ || u->profile == PA_BLUETOOTH_PROFILE_HSP_AG
|| u->profile == PA_BLUETOOTH_PROFILE_HFP_AG
|| u->profile == PA_BLUETOOTH_PROFILE_HFP_HF) {
pa_source_set_set_volume_callback(u->source, source_set_volume_cb);
@@ -1176,7 +1181,7 @@ static void sink_set_volume_cb(pa_sink *
pa_cvolume_set(&s->real_volume, u->encoder_sample_spec.channels, volume);
/* Set soft volume when in headset role */
- if (u->profile == PA_BLUETOOTH_PROFILE_HFP_AG)
+ if (u->profile == PA_BLUETOOTH_PROFILE_HFP_AG || u->profile == PA_BLUETOOTH_PROFILE_HSP_AG)
pa_cvolume_set(&s->soft_volume, u->encoder_sample_spec.channels, volume);
/* If we are in the AG role, we send a command to the head set to change
@@ -1208,6 +1213,7 @@ static int add_sink(struct userdata *u)
if (!u->transport_acquired)
switch (u->profile) {
case PA_BLUETOOTH_PROFILE_HFP_AG:
+ case PA_BLUETOOTH_PROFILE_HSP_AG:
data.suspend_cause = PA_SUSPEND_USER;
break;
case PA_BLUETOOTH_PROFILE_HSP_HS:
@@ -1239,6 +1245,7 @@ static int add_sink(struct userdata *u)
u->sink->set_state_in_io_thread = sink_set_state_in_io_thread_cb;
if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS
+ || u->profile == PA_BLUETOOTH_PROFILE_HSP_AG
|| u->profile == PA_BLUETOOTH_PROFILE_HFP_AG
|| u->profile == PA_BLUETOOTH_PROFILE_HFP_HF) {
pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
@@ -1250,6 +1257,7 @@ static int add_sink(struct userdata *u)
/* Run from main thread */
static int transport_config(struct userdata *u) {
if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS
+ || u->profile == PA_BLUETOOTH_PROFILE_HSP_AG
|| u->profile == PA_BLUETOOTH_PROFILE_HFP_HF
|| u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
u->encoder_sample_spec.format = PA_SAMPLE_S16LE;
@@ -1302,7 +1310,7 @@ static int setup_transport(struct userda
u->transport = t;
- if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG)
+ if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG || u->profile == PA_BLUETOOTH_PROFILE_HSP_AG)
transport_acquire(u, true); /* In case of error, the sink/sources will be created suspended */
else {
int transport_error;
@@ -1321,6 +1329,7 @@ static pa_direction_t get_profile_direct
[PA_BLUETOOTH_PROFILE_A2DP_SINK] = PA_DIRECTION_OUTPUT,
[PA_BLUETOOTH_PROFILE_A2DP_SOURCE] = PA_DIRECTION_INPUT,
[PA_BLUETOOTH_PROFILE_HSP_HS] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
+ [PA_BLUETOOTH_PROFILE_HSP_AG] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
[PA_BLUETOOTH_PROFILE_HFP_HF] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
[PA_BLUETOOTH_PROFILE_HFP_AG] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
[PA_BLUETOOTH_PROFILE_OFF] = 0
@@ -1636,7 +1645,7 @@ static int start_thread(struct userdata
/* If we are in the headset role, the sink should not become default
* unless there is no other sound device available. */
- if (u->profile == PA_BLUETOOTH_PROFILE_HFP_AG)
+ if (u->profile == PA_BLUETOOTH_PROFILE_HFP_AG || u->profile == PA_BLUETOOTH_PROFILE_HSP_AG)
u->sink->priority = 1500;
pa_sink_put(u->sink);
@@ -1652,7 +1661,7 @@ static int start_thread(struct userdata
/* If we are in the headset role or the device is an a2dp source,
* the source should not become default unless there is no other
* sound device available. */
- if (u->profile == PA_BLUETOOTH_PROFILE_HFP_AG || u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE)
+ if (u->profile == PA_BLUETOOTH_PROFILE_HFP_AG || u->profile == PA_BLUETOOTH_PROFILE_HSP_AG || u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE)
u->source->priority = 1500;
pa_source_put(u->source);
@@ -1914,7 +1923,7 @@ static pa_card_profile *create_card_prof
break;
case PA_BLUETOOTH_PROFILE_HSP_HS:
- cp = pa_card_profile_new(name, _("Headset Head Unit (HSP/HFP)"), sizeof(pa_bluetooth_profile_t));
+ cp = pa_card_profile_new(name, _("Headset Head Unit (HSP)"), sizeof(pa_bluetooth_profile_t));
cp->priority = 30;
cp->n_sinks = 1;
cp->n_sources = 1;
@@ -1926,8 +1935,21 @@ static pa_card_profile *create_card_prof
p = PA_CARD_PROFILE_DATA(cp);
break;
+ case PA_BLUETOOTH_PROFILE_HSP_AG:
+ cp = pa_card_profile_new(name, _("Headset Audio Gateway (HSP)"), sizeof(pa_bluetooth_profile_t));
+ cp->priority = 10;
+ cp->n_sinks = 1;
+ cp->n_sources = 1;
+ cp->max_sink_channels = 1;
+ cp->max_source_channels = 1;
+ pa_hashmap_put(input_port->profiles, cp->name, cp);
+ pa_hashmap_put(output_port->profiles, cp->name, cp);
+
+ p = PA_CARD_PROFILE_DATA(cp);
+ break;
+
case PA_BLUETOOTH_PROFILE_HFP_HF:
- cp = pa_card_profile_new(name, _("Headset Handsfree (HFP)"), sizeof(pa_bluetooth_profile_t));
+ cp = pa_card_profile_new(name, _("Handsfree Head Unit (HFP)"), sizeof(pa_bluetooth_profile_t));
cp->priority = 30;
cp->n_sinks = 1;
cp->n_sources = 1;
@@ -1940,7 +1962,7 @@ static pa_card_profile *create_card_prof
break;
case PA_BLUETOOTH_PROFILE_HFP_AG:
- cp = pa_card_profile_new(name, _("Headset Audio Gateway (HSP/HFP)"), sizeof(pa_bluetooth_profile_t));
+ cp = pa_card_profile_new(name, _("Handsfree Audio Gateway (HFP)"), sizeof(pa_bluetooth_profile_t));
cp->priority = 10;
cp->n_sinks = 1;
cp->n_sources = 1;
@@ -2017,7 +2039,9 @@ static int uuid_to_profile(const char *u
*_r = PA_BLUETOOTH_PROFILE_HSP_HS;
else if (pa_streq(uuid, PA_BLUETOOTH_UUID_HFP_HF))
*_r = PA_BLUETOOTH_PROFILE_HFP_HF;
- else if (pa_streq(uuid, PA_BLUETOOTH_UUID_HSP_AG) || pa_streq(uuid, PA_BLUETOOTH_UUID_HFP_AG))
+ else if (pa_streq(uuid, PA_BLUETOOTH_UUID_HSP_AG))
+ *_r = PA_BLUETOOTH_PROFILE_HSP_AG;
+ else if (pa_streq(uuid, PA_BLUETOOTH_UUID_HFP_AG))
*_r = PA_BLUETOOTH_PROFILE_HFP_AG;
else
return -PA_ERR_INVALID;
@@ -2233,7 +2257,7 @@ static pa_hook_result_t transport_speake
volume++;
pa_cvolume_set(&v, u->encoder_sample_spec.channels, volume);
- if (t->profile == PA_BLUETOOTH_PROFILE_HSP_HS)
+ if (t->profile == PA_BLUETOOTH_PROFILE_HSP_HS || t->profile == PA_BLUETOOTH_PROFILE_HFP_HF)
pa_sink_volume_changed(u->sink, &v);
else
pa_sink_set_volume(u->sink, &v, true, true);
@@ -2261,7 +2285,7 @@ static pa_hook_result_t transport_microp
pa_cvolume_set(&v, u->decoder_sample_spec.channels, volume);
- if (t->profile == PA_BLUETOOTH_PROFILE_HSP_HS)
+ if (t->profile == PA_BLUETOOTH_PROFILE_HSP_HS || t->profile == PA_BLUETOOTH_PROFILE_HFP_HF)
pa_source_volume_changed(u->source, &v);
else
pa_source_set_volume(u->source, &v, true, true);

View File

@ -1,79 +0,0 @@
From c884ae8c7453c038d7359758e81dbaf3499a2368 Mon Sep 17 00:00:00 2001
From: "Igor V. Kovalenko" <igor.v.kovalenko@gmail.com>
Date: Mon, 1 Feb 2021 20:51:18 +0300
Subject: [PATCH 09/11] bluetooth: use device flag to prevent assertion failure
during shutdown
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/491>
---
src/modules/bluetooth/backend-native.c | 2 +-
src/modules/bluetooth/bluez5-util.c | 7 +++----
src/modules/bluetooth/bluez5-util.h | 1 +
src/modules/bluetooth/module-bluez5-device.c | 4 ----
4 files changed, 5 insertions(+), 9 deletions(-)
--- a/src/modules/bluetooth/backend-native.c
+++ b/src/modules/bluetooth/backend-native.c
@@ -645,7 +645,7 @@ static DBusMessage *profile_new_connecti
goto fail;
}
- if (pa_bluetooth_discovery_get_enable_native_hfp_hf(b->discovery)) {
+ if (d->enable_hfp_hf) {
if (p == PA_BLUETOOTH_PROFILE_HSP_HS && pa_hashmap_get(d->uuids, PA_BLUETOOTH_UUID_HFP_HF)) {
/* If peer connecting to HSP Audio Gateway supports HFP HF profile
* reject this connection to force it to connect to HSP Audio Gateway instead.
--- a/src/modules/bluetooth/bluez5-util.c
+++ b/src/modules/bluetooth/bluez5-util.c
@@ -175,11 +175,9 @@ static const char *transport_state_to_st
}
static bool device_supports_profile(pa_bluetooth_device *device, pa_bluetooth_profile_t profile) {
- bool show_hfp, show_hsp, enable_native_hfp_hf;
+ bool show_hfp, show_hsp;
- enable_native_hfp_hf = pa_bluetooth_discovery_get_enable_native_hfp_hf(device->discovery);
-
- if (enable_native_hfp_hf) {
+ if (device->enable_hfp_hf) {
show_hfp = pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_HF);
show_hsp = !show_hfp;
} else {
@@ -537,6 +535,7 @@ static pa_bluetooth_device* device_creat
d = pa_xnew0(pa_bluetooth_device, 1);
d->discovery = y;
+ d->enable_hfp_hf = pa_bluetooth_discovery_get_enable_native_hfp_hf(y);
d->path = pa_xstrdup(path);
d->uuids = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL, pa_xfree);
--- a/src/modules/bluetooth/bluez5-util.h
+++ b/src/modules/bluetooth/bluez5-util.h
@@ -107,6 +107,7 @@ struct pa_bluetooth_device {
pa_bluetooth_discovery *discovery;
pa_bluetooth_adapter *adapter;
+ bool enable_hfp_hf;
bool properties_received;
bool tried_to_link_with_adapter;
bool valid;
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -2059,7 +2059,6 @@ static int add_card(struct userdata *u)
pa_bluetooth_profile_t *p;
const char *uuid;
void *state;
- bool enable_native_hfp_hf, has_both;
pa_assert(u);
pa_assert(u->device);
@@ -2090,9 +2089,6 @@ static int add_card(struct userdata *u)
create_card_ports(u, data.ports);
- enable_native_hfp_hf = pa_bluetooth_discovery_get_enable_native_hfp_hf(u->discovery);
-
- has_both = enable_native_hfp_hf && pa_hashmap_get(d->uuids, PA_BLUETOOTH_UUID_HFP_HF) && pa_hashmap_get(d->uuids, PA_BLUETOOTH_UUID_HSP_HS);
PA_HASHMAP_FOREACH(uuid, d->uuids, state) {
pa_bluetooth_profile_t profile;

View File

@ -1,113 +0,0 @@
From 0a36c1544d7e995be4528c4dfda43d7de1bbacc5 Mon Sep 17 00:00:00 2001
From: "Igor V. Kovalenko" <igor.v.kovalenko@gmail.com>
Date: Tue, 16 Feb 2021 08:46:19 +0300
Subject: [PATCH 10/11] bluetooth: rename enable_hs_role to
enable_shared_profiles
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/491>
---
src/modules/bluetooth/backend-native.c | 22 +++++++++++-----------
src/modules/bluetooth/bluez5-util.c | 2 +-
src/modules/bluetooth/bluez5-util.h | 8 ++++----
3 files changed, 16 insertions(+), 16 deletions(-)
--- a/src/modules/bluetooth/backend-native.c
+++ b/src/modules/bluetooth/backend-native.c
@@ -40,7 +40,7 @@ struct pa_bluetooth_backend {
pa_core *core;
pa_dbus_connection *connection;
pa_bluetooth_discovery *discovery;
- bool enable_hs_role;
+ bool enable_shared_profiles;
bool enable_hfp_hf;
PA_LLIST_HEAD(pa_dbus_pending, pending);
@@ -797,8 +797,8 @@ static void profile_done(pa_bluetooth_ba
}
}
-static void native_backend_apply_profile_registration_change(pa_bluetooth_backend *native_backend, bool enable_hs_role) {
- if (enable_hs_role) {
+static void native_backend_apply_profile_registration_change(pa_bluetooth_backend *native_backend, bool enable_shared_profiles) {
+ if (enable_shared_profiles) {
profile_init(native_backend, PA_BLUETOOTH_PROFILE_HSP_AG);
if (native_backend->enable_hfp_hf)
profile_init(native_backend, PA_BLUETOOTH_PROFILE_HFP_HF);
@@ -809,17 +809,17 @@ static void native_backend_apply_profile
}
}
-void pa_bluetooth_native_backend_enable_hs_role(pa_bluetooth_backend *native_backend, bool enable_hs_role) {
+void pa_bluetooth_native_backend_enable_shared_profiles(pa_bluetooth_backend *native_backend, bool enable) {
- if (enable_hs_role == native_backend->enable_hs_role)
+ if (enable == native_backend->enable_shared_profiles)
return;
- native_backend_apply_profile_registration_change(native_backend, enable_hs_role);
+ native_backend_apply_profile_registration_change(native_backend, enable);
- native_backend->enable_hs_role = enable_hs_role;
+ native_backend->enable_shared_profiles = enable;
}
-pa_bluetooth_backend *pa_bluetooth_native_backend_new(pa_core *c, pa_bluetooth_discovery *y, bool enable_hs_role) {
+pa_bluetooth_backend *pa_bluetooth_native_backend_new(pa_core *c, pa_bluetooth_discovery *y, bool enable_shared_profiles) {
pa_bluetooth_backend *backend;
DBusError err;
@@ -837,10 +837,10 @@ pa_bluetooth_backend *pa_bluetooth_nativ
}
backend->discovery = y;
- backend->enable_hs_role = enable_hs_role;
+ backend->enable_shared_profiles = enable_shared_profiles;
backend->enable_hfp_hf = pa_bluetooth_discovery_get_enable_native_hfp_hf(y);
- if (backend->enable_hs_role)
+ if (backend->enable_shared_profiles)
native_backend_apply_profile_registration_change(backend, true);
profile_init(backend, PA_BLUETOOTH_PROFILE_HSP_HS);
@@ -853,7 +853,7 @@ void pa_bluetooth_native_backend_free(pa
pa_dbus_free_pending_list(&backend->pending);
- if (backend->enable_hs_role)
+ if (backend->enable_shared_profiles)
native_backend_apply_profile_registration_change(backend, false);
profile_done(backend, PA_BLUETOOTH_PROFILE_HSP_HS);
--- a/src/modules/bluetooth/bluez5-util.c
+++ b/src/modules/bluetooth/bluez5-util.c
@@ -1040,7 +1040,7 @@ void pa_bluetooth_discovery_set_ofono_ru
if (y->headset_backend != HEADSET_BACKEND_AUTO)
return;
- pa_bluetooth_native_backend_enable_hs_role(y->native_backend, !is_running);
+ pa_bluetooth_native_backend_enable_shared_profiles(y->native_backend, !is_running);
/* If ofono starts running, all devices that might be connected to the HS roles or HFP AG role
* need to be disconnected, so that the devices can be handled by ofono */
--- a/src/modules/bluetooth/bluez5-util.h
+++ b/src/modules/bluetooth/bluez5-util.h
@@ -145,15 +145,15 @@ static inline void pa_bluetooth_ofono_ba
#endif
#ifdef HAVE_BLUEZ_5_NATIVE_HEADSET
-pa_bluetooth_backend *pa_bluetooth_native_backend_new(pa_core *c, pa_bluetooth_discovery *y, bool enable_hs_role);
+pa_bluetooth_backend *pa_bluetooth_native_backend_new(pa_core *c, pa_bluetooth_discovery *y, bool enable_shared_profiles);
void pa_bluetooth_native_backend_free(pa_bluetooth_backend *b);
-void pa_bluetooth_native_backend_enable_hs_role(pa_bluetooth_backend *b, bool enable_hs_role);
+void pa_bluetooth_native_backend_enable_shared_profiles(pa_bluetooth_backend *b, bool enable);
#else
-static inline pa_bluetooth_backend *pa_bluetooth_native_backend_new(pa_core *c, pa_bluetooth_discovery *y, bool enable_hs_role) {
+static inline pa_bluetooth_backend *pa_bluetooth_native_backend_new(pa_core *c, pa_bluetooth_discovery *y, bool enable_shared_profiles) {
return NULL;
}
static inline void pa_bluetooth_native_backend_free(pa_bluetooth_backend *b) {}
-static inline void pa_bluetooth_native_backend_enable_hs_role(pa_bluetooth_backend *b, bool enable_hs_role) {}
+static inline void pa_bluetooth_native_backend_enable_shared_profiles(pa_bluetooth_backend *b, bool enable) {}
#endif
pa_bluetooth_transport *pa_bluetooth_transport_new(pa_bluetooth_device *d, const char *owner, const char *path,

View File

@ -1,143 +0,0 @@
From 45d896f8eb385a9719fdea3eacc2e42bc2281834 Mon Sep 17 00:00:00 2001
From: "Igor V. Kovalenko" <igor.v.kovalenko@gmail.com>
Date: Thu, 18 Feb 2021 21:08:21 +0300
Subject: [PATCH 11/11] bluetooth: clean up rfcomm_write usage
Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/491>
---
src/modules/bluetooth/backend-native.c | 67 ++++++++++-----------------------
1 file changed, 21 insertions(+), 46 deletions(-)
--- a/src/modules/bluetooth/backend-native.c
+++ b/src/modules/bluetooth/backend-native.c
@@ -147,25 +147,26 @@ static pa_dbus_pending* send_and_add_to_
return p;
}
-static void rfcomm_write(int fd, const char *str)
+static void rfcomm_write(int fd, const char *fmt, ...)
{
+ va_list ap;
size_t len;
char buf[512];
+ char command[512];
- pa_log_debug("RFCOMM >> %s", str);
- sprintf(buf, "\r\n%s\r\n", str);
- len = write(fd, buf, strlen(buf));
+ va_start(ap, fmt);
+ pa_vsnprintf(command, sizeof(command), fmt, ap);
+ va_end(ap);
- if (len != strlen(buf))
- pa_log_error("RFCOMM write error: %s", pa_cstrerror(errno));
-}
+ pa_log_debug("RFCOMM >> %s", command);
-static void hfp_send_features(int fd)
-{
- char buf[512];
+ len = pa_snprintf(buf, sizeof(buf), "\r\n%s\r\n", command);
+
+ /* we ignore any errors, it's not critical and real errors should
+ * be caught with the HANGUP and ERROR events handled above */
- sprintf(buf, "+BRSF: %d", hfp_features);
- rfcomm_write(fd, buf);
+ if ((size_t)write(fd, buf, len) != len)
+ pa_log_error("RFCOMM write error: %s", pa_cstrerror(errno));
}
static int sco_do_connect(pa_bluetooth_transport *t) {
@@ -427,7 +428,7 @@ static bool hfp_rfcomm_handle(int fd, pa
if (c->state == 0 && sscanf(buf, "AT+BRSF=%d", &val) == 1) {
c->capabilities = val;
pa_log_info("HFP capabilities returns 0x%x", val);
- hfp_send_features(fd);
+ rfcomm_write(fd, "+BRSF: %d", hfp_features);
c->state = 1;
return true;
} else if (c->state == 1 && pa_startswith(buf, "AT+CIND=?")) {
@@ -444,7 +445,7 @@ static bool hfp_rfcomm_handle(int fd, pa
c->state = 3;
return true;
} else if ((c->state == 2 || c->state == 3) && pa_startswith(buf, "AT+CMER=")) {
- rfcomm_write(fd, "\r\nOK\r\n");
+ rfcomm_write(fd, "OK");
c->state = 4;
transport_put(t);
return false;
@@ -518,16 +519,8 @@ static void rfcomm_io_callback(pa_mainlo
do_reply = false;
}
- if (do_reply) {
- pa_log_debug("RFCOMM >> OK");
-
- len = write(fd, "\r\nOK\r\n", 6);
-
- /* 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));
- }
+ if (do_reply)
+ rfcomm_write(fd, "OK");
}
return;
@@ -555,8 +548,6 @@ static void transport_destroy(pa_bluetoo
static void set_speaker_gain(pa_bluetooth_transport *t, uint16_t gain) {
struct transport_data *trd = t->userdata;
- char buf[512];
- ssize_t len, written;
if (t->speaker_gain == gain)
return;
@@ -567,23 +558,14 @@ static void set_speaker_gain(pa_bluetoot
* the speaker gain. In the HS role, source and sink are swapped, so
* in this case we notify the AG that the microphone gain has changed */
if (t->profile == PA_BLUETOOTH_PROFILE_HSP_HS || t->profile == PA_BLUETOOTH_PROFILE_HFP_HF) {
- len = sprintf(buf, "\r\n+VGS=%d\r\n", gain);
- pa_log_debug("RFCOMM >> +VGS=%d", gain);
+ rfcomm_write(trd->rfcomm_fd, "+VGS=%d", gain);
} else {
- len = sprintf(buf, "\r\nAT+VGM=%d\r\n", gain);
- pa_log_debug("RFCOMM >> AT+VGM=%d", gain);
+ rfcomm_write(trd->rfcomm_fd, "AT+VGM=%d", gain);
}
-
- written = write(trd->rfcomm_fd, buf, len);
-
- if (written != len)
- pa_log_error("RFCOMM write error: %s", pa_cstrerror(errno));
}
static void set_microphone_gain(pa_bluetooth_transport *t, uint16_t gain) {
struct transport_data *trd = t->userdata;
- char buf[512];
- ssize_t len, written;
if (t->microphone_gain == gain)
return;
@@ -594,17 +576,10 @@ static void set_microphone_gain(pa_bluet
* the microphone gain. In the HS role, source and sink are swapped, so
* in this case we notify the AG that the speaker gain has changed */
if (t->profile == PA_BLUETOOTH_PROFILE_HSP_HS || t->profile == PA_BLUETOOTH_PROFILE_HFP_HF) {
- len = sprintf(buf, "\r\n+VGM=%d\r\n", gain);
- pa_log_debug("RFCOMM >> +VGM=%d", gain);
+ rfcomm_write(trd->rfcomm_fd, "+VGM=%d", gain);
} else {
- len = sprintf(buf, "\r\nAT+VGS=%d\r\n", gain);
- pa_log_debug("RFCOMM >> AT+VGS=%d", gain);
+ rfcomm_write(trd->rfcomm_fd, "AT+VGS=%d", gain);
}
-
- written = write (trd->rfcomm_fd, buf, len);
-
- if (written != len)
- pa_log_error("RFCOMM write error: %s", pa_cstrerror(errno));
}
static DBusMessage *profile_new_connection(DBusConnection *conn, DBusMessage *m, void *userdata) {

View File

@ -1,19 +1,15 @@
---
src/daemon/start-pulseaudio-x11.in | 6 ++++++
1 file changed, 6 insertions(+)
--- a/src/daemon/start-pulseaudio-x11.in
+++ b/src/daemon/start-pulseaudio-x11.in
--- a/src/daemon/start-pulseaudio-x11.in 2021-07-27 20:02:27.739868200 +0000
+++ b/src/daemon/start-pulseaudio-x11.in 2021-08-02 20:53:22.460023234 +0000
@@ -17,6 +17,12 @@
set -e
+. /etc/sysconfig/sound
+
+if [ x"$PULSEAUDIO_ENABLE" = x"no" ] || [ x"$PULSEAUDIO_SYSTEM" = x"yes" ] ; then
+ exit 1
+fi
+
if [ x"$DISPLAY" != x ] ; then
@PACTL_BINARY@ load-module module-x11-publish "display=$DISPLAY xauthority=$XAUTHORITY" > /dev/null
if [ -n "$1" ] ; then
case $1 in
stop)

View File

@ -1,44 +0,0 @@
From b230da0d948573f4e17f12285373235369099dd8 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@arcor.de>
Date: Mon, 15 Mar 2021 13:01:28 +0100
Subject: [PATCH] parecord: fix "Failed to open audio file" for FLAC and OGG
This patch fixes the following error:
$ pacat --file-format=ogg -r test.ogg
Failed to open audio file.
$ parecord sep.flac
Failed to open audio file.
libsndfile errors out if a WAV or OGG file is set to have anything but
SF_ENDIAN_FILE:
https://github.com/libsndfile/libsndfile/commit/f4d1646e5cd96444a75c6327a9d49739f81d251e
Signed-off-by: Martin Wilck <mwilck@arcor.de>
---
src/utils/pacat.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/src/utils/pacat.c b/src/utils/pacat.c
index 4d2ecf717..31da073bc 100644
--- a/src/utils/pacat.c
+++ b/src/utils/pacat.c
@@ -1062,6 +1062,15 @@ int main(int argc, char *argv[]) {
}
sfi.format |= file_format;
+
+ /*
+ * Endianness has been set in pa_sndfile_write_sample_spec(), but
+ * libsndfile errors out if endianness is set to anything other than
+ * SF_ENDIAN_FILE for OGG or FLAC. Clear it.
+ */
+ if (file_format == SF_FORMAT_OGG || file_format == SF_FORMAT_FLAC)
+ sfi.format = (sfi.format & ~SF_FORMAT_ENDMASK) | SF_ENDIAN_FILE;
+
}
if (!(sndfile = sf_open_fd(mode == RECORD ? STDOUT_FILENO : STDIN_FILENO,
--
2.26.2

View File

@ -1,34 +0,0 @@
From d56d5054f8e7b39376440e80ac7348b52e015de3 Mon Sep 17 00:00:00 2001
From: Martin Wilck <mwilck@arcor.de>
Date: Mon, 19 Apr 2021 17:55:28 +0200
Subject: [PATCH] parecord: really fix recording OGG
432a91ed ("fix "Failed to open audio file" for FLAC and OGG)" claimed
to fix recording of OGG files with pacat, but it really fixed only
FLAC. This patch must be added on top to fix OGG, too.
Signed-off-by: Martin Wilck <mwilck@arcor.de>
---
src/utils/pacat.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/utils/pacat.c b/src/utils/pacat.c
index 31da073bc..39ccaffd0 100644
--- a/src/utils/pacat.c
+++ b/src/utils/pacat.c
@@ -1067,9 +1067,12 @@ int main(int argc, char *argv[]) {
* Endianness has been set in pa_sndfile_write_sample_spec(), but
* libsndfile errors out if endianness is set to anything other than
* SF_ENDIAN_FILE for OGG or FLAC. Clear it.
+ * For OGG, libsndfile accepts only subformat SF_FORMAT_VORBIS.
*/
if (file_format == SF_FORMAT_OGG || file_format == SF_FORMAT_FLAC)
sfi.format = (sfi.format & ~SF_FORMAT_ENDMASK) | SF_ENDIAN_FILE;
+ if (file_format == SF_FORMAT_OGG)
+ sfi.format = (sfi.format & ~SF_FORMAT_SUBMASK) | SF_FORMAT_VORBIS;
}
--
2.26.2

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:75d3f7742c1ae449049a4c88900e454b8b350ecaa8c544f3488a2562a9ff66f1
size 1951300

3
pulseaudio-15.0.tar.xz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a40b887a3ba98cc26976eb11bdb6613988f145b19024d1b6555c6a03c9cba1a0
size 1521760

View File

@ -1,3 +1,56 @@
-------------------------------------------------------------------
Tue Aug 3 20:50:50 UTC 2021 - Ondrej Holecek <oholecek@suse.com>
- Update to PulseAudio 15
- drop esound compat support
- drop gconf support
- convert to mason build system
- disable doxygen doc generation
- droped patches:
drop bluetooth patches integrated in release:
0001-bluetooth-use-consistent-profile-names.patch
0002-bluetooth-separate-HSP-and-HFP.patch
0003-bluetooth-add-correct-HFP-rfcomm-negotiation.patch
0004-bluetooth-make-native-the-default-backend.patch
0005-bluetooth-enable-module-bluez5-discover-argument-ena.patch
0006-bluetooth-fix-headset-auto-ofono-handover.patch
0007-bluetooth-prefer-headset-HFP-HF-connection-with-nati.patch
0008-bluetooth-complete-bluetooth-profile-separation.patch
0009-bluetooth-use-device-flag-to-prevent-assertion-failu.patch
0010-bluetooth-rename-enable_hs_role-to-enable_shared_pro.patch
0011-bluetooth-clean-up-rfcomm_write-usage.patch
drop parecord patches integrated in release
parecord-fix-Failed-to-open-audio-file-for-FLAC-and-.patch
parecord-really-fix-recording-OGG.patch
- refresh disabled-start.diff patch
- new features:
* Support for LDAC and AptX bluetooth codecs, plus "SBC XQ" (SBC with higher-quality parameters)
* Support for HFP bluetooth profiles
* Support for Bluetooth A2DP AVRCP Absolute Volume
* ALSA path configuration files can now be placed in user home directory
* module-virtual-surround-sink rewritten
* More options for module-jackdbus-detect
* Improved hardware support
* SteelSeries Arctis 9
* HP Thunderbolt Dock 120W G2
* Behringer U-Phoria UMC22
* OnePlus Type-C Bullets
* Sennheiser GSX 1000/1200 PRO
* New udev variable: PULSE_MODARGS
* max_latency_msec argument added to module-null-source
* module-filter-apply can take filter parameters from device properties
* module-match can now be loaded multiple times
* Improvements to FreeBSD support
* Windows support added to Meson
* Additional commands for pactl
* Card profiles can be set to sticky
* The startup script can now read additional configuration from the /etc/pulse/default.pa.d/ directory
** Notes for application developers
* New API for sending messages from clients to PulseAudio objects
* New mechanism for applications to disable shared memory on their connection to PulseAudio
( https://www.freedesktop.org/wiki/Software/PulseAudio/Notes/15.0/ )
-------------------------------------------------------------------
Sun Jul 18 11:37:16 UTC 2021 - Callum Farmer <gmbr3@opensuse.org>

View File

@ -24,12 +24,12 @@
%define _fillupdir /var/adm/fillup-templates
%endif
%define drvver 14.2
%define drvver 15.0
%define soname 0
%define _udevrulesdir %(pkg-config --variable=udevdir udev)/rules.d
%define _bashcompletionsdir %{_datadir}/bash-completion/completions
Name: pulseaudio
Version: 14.2
Version: 15.0
Release: 0
Summary: A Networked Sound Server
License: GPL-2.0-or-later AND LGPL-2.1-or-later
@ -53,27 +53,13 @@ Patch1: suppress-socket-error-msg.diff
Patch5: qpaeq-shebang.patch
# PATCH-FIX-OPENSUSE Workaround for old systemd on Leap 15.x
Patch6: pulseaudio-old-systemd-workaround.patch
Patch7: parecord-fix-Failed-to-open-audio-file-for-FLAC-and-.patch
Patch8: parecord-really-fix-recording-OGG.patch
# HFP support patches (bsc#1167940)
Patch101: 0001-bluetooth-use-consistent-profile-names.patch
Patch102: 0002-bluetooth-separate-HSP-and-HFP.patch
Patch103: 0003-bluetooth-add-correct-HFP-rfcomm-negotiation.patch
Patch104: 0004-bluetooth-make-native-the-default-backend.patch
Patch105: 0005-bluetooth-enable-module-bluez5-discover-argument-ena.patch
Patch106: 0006-bluetooth-fix-headset-auto-ofono-handover.patch
Patch107: 0007-bluetooth-prefer-headset-HFP-HF-connection-with-nati.patch
Patch108: 0008-bluetooth-complete-bluetooth-profile-separation.patch
Patch109: 0009-bluetooth-use-device-flag-to-prevent-assertion-failu.patch
Patch110: 0010-bluetooth-rename-enable_hs_role-to-enable_shared_pro.patch
Patch111: 0011-bluetooth-clean-up-rfcomm_write-usage.patch
BuildRequires: alsa-devel >= 1.0.19
BuildRequires: bluez-devel >= 5
BuildRequires: doxygen
BuildRequires: fdupes
BuildRequires: fftw3-devel >= 3.0
BuildRequires: gcc-c++
BuildRequires: jack-devel
BuildRequires: meson
BuildRequires: libatomic_ops-devel >= 1.2
BuildRequires: libavahi-devel
BuildRequires: libcap-devel
@ -82,7 +68,6 @@ BuildRequires: libsndfile-devel >= 1.0.18
BuildRequires: libtool
BuildRequires: pkgconfig(libudev) >= 143
BuildRequires: libwebrtc_audio_processing-devel >= 0.3
BuildRequires: lirc-devel
BuildRequires: orc >= 0.4.9
BuildRequires: pkgconfig
BuildRequires: speexdsp-devel
@ -90,12 +75,15 @@ BuildRequires: systemd-rpm-macros
BuildRequires: translation-update-upstream
BuildRequires: sysuser-tools
BuildRequires: pkgconfig(bash-completion)
BuildRequires: pkgconfig(check)
BuildRequires: pkgconfig(dbus-1) >= 1.4.12
BuildRequires: pkgconfig(gconf-2.0)
BuildRequires: pkgconfig(gio-2.0)
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(gtk+-3.0)
BuildRequires: pkgconfig(ice)
BuildRequires: pkgconfig(libsystemd)
BuildRequires: pkgconfig(lirc)
BuildRequires: pkgconfig(sbc) >= 1.0
BuildRequires: pkgconfig(sm)
BuildRequires: pkgconfig(soxr)
@ -130,21 +118,6 @@ pulseaudio is a networked sound server for Linux, other Unix like
operating systems and Microsoft Windows. It is intended to be an
improved drop-in replacement for the Enlightened Sound Daemon (ESOUND).
%package esound-compat
Summary: ESOUND compatibility for PulseAudio
Group: System/Sound Daemons
Requires: %{name} = %{version}
Provides: esound-daemon = 0.2.41
Obsoletes: esound-daemon < 0.2.41
%description esound-compat
pulseaudio is a networked sound server for Linux and other Unix like
operating systems and Microsoft Windows. It is intended to be an
improved drop-in replacement for the Enlightened Sound Daemon (ESOUND).
This package provides the compatibility layer for drop-in replacement
of ESOUND.
%package module-lirc
Summary: LIRC module for PulseAudio
Group: System/Sound Daemons
@ -229,19 +202,6 @@ improved drop-in replacement for the Enlightened Sound Daemon (ESOUND).
Contains Bluetooth audio (A2DP/HSP/HFP) support for the PulseAudio sound server.
%package module-gconf
Summary: GCONF module for PulseAudio
Group: System/Sound Daemons
Requires: %{name} = %{version}
Conflicts: %{name}-module-gsettings
%description module-gconf
pulseaudio is a networked sound server for Linux and other Unix like
operating systems and Microsoft Windows. It is intended to be an
improved drop-in replacement for the Enlightened Sound Daemon (ESOUND).
This package provides gconf storage of PulseAudio sound server settings.
%package module-gsettings
Summary: GSettings module for PulseAudio
Group: System/Sound Daemons
@ -365,52 +325,28 @@ Optional dependency offering zsh completion for various PulseAudio utilities
%if 0%{?suse_version} < 1550
%patch6 -p1
%endif
%patch7 -p1
%patch8 -p1
%patch101 -p1
%patch102 -p1
%patch103 -p1
%patch104 -p1
%patch105 -p1
%patch106 -p1
%patch107 -p1
%patch108 -p1
%patch109 -p1
%patch110 -p1
%patch111 -p1
%build
NOCONFIGURE=1 ./bootstrap.sh
echo 'HTML_TIMESTAMP=NO' >> doxygen/doxygen.conf.in
export LDFLAGS="-pie"
export CFLAGS="%{optflags} -fPIE"
%configure \
--disable-static \
--disable-rpath \
--disable-running-from-build-tree \
%ifarch armv5tel armv6hl
--disable-neon-opt \
%endif
--with-system-user=pulse \
--with-system-group=pulse \
--with-access-group=pulse-access \
--disable-hal-compat \
--disable-bluez4 \
--enable-webrtc-aec \
--enable-adrian-aec \
--enable-gconf \
--enable-gsettings \
--with-udev-rules-dir=%{_udevrulesdir} \
--with-pulsedsp-location='%{_prefix}/\\$$LIB/pulseaudio' \
--with-systemduserunitdir=%{_userunitdir} \
--enable-stream-restore-clear-old-devices \
%{nil}
%make_build
%make_build doxygen
%meson \
--auto-features=auto \
-Dhal-compat=false \
-Dgsettings=enabled \
-Ddoxygen=false \
-Dsystem-user=pulse \
-Dsystem-group=pulse \
-Daccess-group=pulse-access \
-Drunning-from-build-tree=false \
-Dpulsedsp-location='%{_prefix}/\\$$LIB/pulseaudio' \
-Dudevrulesdir="%{_udevrulesdir}" \
-Dsystemduserunitdir="%{_userunitdir}" \
-Db_pie=true \
%{nil}
%meson_build
%sysusers_generate_pre %{SOURCE10} pulseaudio system-user-pulse.conf
%install
%make_install
%meson_install
rm -rf \
"%{buildroot}%{_libdir}"/*.la \
"%{buildroot}%{_libdir}/pulse-%{drvver}/modules"/*.la \
@ -427,6 +363,9 @@ ln -s %{_sbindir}/service %{buildroot}%{_sbindir}/rc%{name}
# some HW may get undetected without this (check pulseaudio 6.0RC1 announce)
ln -s default.conf %{buildroot}%{_datadir}/pulseaudio/alsa-mixer/profile-sets/extra-hdmi.conf
# remove xwayland.sessions.d files. Do we have such directory?
rm %{buildroot}%{_sysconfdir}/xdg/Xwayland-session.d/00-pulseaudio-x11
install %{SOURCE2} %{buildroot}%{_bindir}
chmod 755 %{buildroot}%{_bindir}/setup-pulseaudio
install -d %{buildroot}%{_fillupdir}
@ -439,17 +378,19 @@ install -m 644 %{SOURCE7} %{buildroot}%{_prefix}/lib/tmpfiles.d/pulseaudio.conf
install -m 644 %{SOURCE8} %{buildroot}%{_prefix}/lib/tmpfiles.d/pulseaudio-gdm-hooks.conf
mkdir -p %{buildroot}%{_prefix}/share/factory/var/lib/gdm/.pulse
install -m 644 %{SOURCE1} %{buildroot}%{_prefix}/share/factory/var/lib/gdm/.pulse/default.pa
ln -s esdcompat %{buildroot}%{_bindir}/esd
# create .d conf dirs (since 8.0)
mkdir -p %{buildroot}%{_sysconfdir}/pulse/client.conf.d
install -m 0644 %{SOURCE9} %{buildroot}%{_sysconfdir}/pulse/client.conf.d/50-system.conf
mkdir -p %{buildroot}%{_sysconfdir}/pulse/daemon.conf.d
# create .d startup dirs (since 15.0)
mkdir -p %{buildroot}%{_sysconfdir}/pulse/default.pa.d
mkdir -p %{buildroot}%{_sysconfdir}/pulse/system.pa.d
# Install disable_flat_volumes.conf
install -m 0644 %{SOURCE6} %{buildroot}%{_sysconfdir}/pulse/daemon.conf.d/60-disable_flat_volumes.conf
# user
install -Dm0644 %{SOURCE10} %{buildroot}%{_sysusersdir}/system-user-pulse.conf
%find_lang %{name}
%fdupes doxygen/html
%pre -f pulseaudio.pre
@ -520,7 +461,6 @@ exit 0
%{_libdir}/pulse-%{drvver}/modules/libcli.so
%{_libdir}/pulse-%{drvver}/modules/liboss-util.so
%{_libdir}/pulse-%{drvver}/modules/libprotocol-cli.so
%{_libdir}/pulse-%{drvver}/modules/libprotocol-esound.so
%{_libdir}/pulse-%{drvver}/modules/libprotocol-http.so
%{_libdir}/pulse-%{drvver}/modules/libprotocol-native.so
%{_libdir}/pulse-%{drvver}/modules/libprotocol-simple.so
@ -546,11 +486,6 @@ exit 0
%{_libdir}/pulse-%{drvver}/modules/module-device-manager.so
%{_libdir}/pulse-%{drvver}/modules/module-device-restore.so
%{_libdir}/pulse-%{drvver}/modules/module-echo-cancel.so
%{_libdir}/pulse-%{drvver}/modules/module-esound-compat-spawnfd.so
%{_libdir}/pulse-%{drvver}/modules/module-esound-compat-spawnpid.so
%{_libdir}/pulse-%{drvver}/modules/module-esound-protocol-tcp.so
%{_libdir}/pulse-%{drvver}/modules/module-esound-protocol-unix.so
%{_libdir}/pulse-%{drvver}/modules/module-esound-sink.so
%{_libdir}/pulse-%{drvver}/modules/module-equalizer-sink.so
%{_libdir}/pulse-%{drvver}/modules/module-filter-apply.so
%{_libdir}/pulse-%{drvver}/modules/module-filter-heuristics.so
@ -604,6 +539,8 @@ exit 0
%{_mandir}/man5/pulse-cli-syntax.5*
%dir %{_sysconfdir}/pulse/
%dir %{_sysconfdir}/pulse/daemon.conf.d
%dir %{_sysconfdir}/pulse/default.pa.d
%dir %{_sysconfdir}/pulse/system.pa.d
%config %{_sysconfdir}/pulse/client.conf.d/50-system.conf
%config(noreplace) %{_sysconfdir}/pulse/daemon.conf.d/60-disable_flat_volumes.conf
%config(noreplace) %{_sysconfdir}/pulse/daemon.conf
@ -622,10 +559,8 @@ exit 0
%ghost %{_sysconfdir}/profile.d/pulseaudio.sh
%ghost %{_sysconfdir}/profile.d/pulseaudio.csh
%files esound-compat
%{_bindir}/esdcompat
%{_bindir}/esd
%{_mandir}/man1/esdcompat.1*
# xwayland integration
%{_userunitdir}/pulseaudio-x11.service
%files gdm-hooks
%attr(0750, gdm, gdm) %ghost %dir %{_localstatedir}/lib/gdm
@ -650,7 +585,6 @@ exit 0
%{_libdir}/pulseaudio/libpulsecommon-%{drvver}.so
%files -n libpulse-devel
%doc doxygen/html
%{_includedir}/pulse/
%{_libdir}/libpulse.so
%{_libdir}/libpulse-mainloop-glib.so
@ -675,19 +609,10 @@ exit 0
%{_libdir}/pulse-%{drvver}/modules/module-bluez5-device.so
%{_libdir}/pulse-%{drvver}/modules/module-bluez5-discover.so
%files module-gconf
%dir %{_libexecdir}/pulse
%dir %{_libdir}/pulse-%{drvver}
%dir %{_libdir}/pulse-%{drvver}/modules
%{_libdir}/pulse-%{drvver}/modules/module-gconf.so
%{_libexecdir}/pulse/gconf-helper
%files module-gsettings
%dir %{_libexecdir}/pulse
%dir %{_libdir}/pulse-%{drvver}
%dir %{_libdir}/pulse-%{drvver}/modules
%dir %{_datarootdir}/GConf
%dir %{_datarootdir}/GConf/gsettings
%{_libdir}/pulse-%{drvver}/modules/module-gsettings.so
%{_libexecdir}/pulse/gsettings-helper
%{_datadir}/GConf/gsettings/pulseaudio.convert