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:
parent
7b55b57381
commit
0478a78359
@ -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);
|
@ -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 =
|
@ -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;
|
@ -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");
|
@ -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
|
||||
};
|
||||
|
@ -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;
|
@ -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;
|
||||
|
@ -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);
|
@ -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;
|
||||
|
@ -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,
|
@ -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) {
|
@ -1,9 +1,5 @@
|
||||
---
|
||||
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
|
||||
@ -14,6 +10,6 @@
|
||||
+ 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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
3
pulseaudio-15.0.tar.xz
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a40b887a3ba98cc26976eb11bdb6613988f145b19024d1b6555c6a03c9cba1a0
|
||||
size 1521760
|
@ -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>
|
||||
|
||||
|
143
pulseaudio.spec
143
pulseaudio.spec
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user