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>
This commit is contained in:
Igor V. Kovalenko 2021-01-29 21:32:09 +03:00 committed by Igor Kovalenko
parent 815dd2d627
commit 698fb3bc26
6 changed files with 65 additions and 37 deletions

View file

@ -262,8 +262,9 @@ static int sco_process_render(struct userdata *u) {
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);
@ -329,8 +330,9 @@ static int sco_process_push(struct userdata *u) {
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_change(struct userdata *u) {
/* 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_source *s) {
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
@ -1023,6 +1026,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:
@ -1052,6 +1056,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);
@ -1178,7 +1183,7 @@ static void sink_set_volume_cb(pa_sink *s) {
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
@ -1212,6 +1217,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:
@ -1243,6 +1249,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);
@ -1254,6 +1261,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;
@ -1306,7 +1314,7 @@ static int setup_transport(struct userdata *u) {
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;
@ -1325,6 +1333,7 @@ static pa_direction_t get_profile_direction(pa_bluetooth_profile_t p) {
[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
@ -1660,7 +1669,7 @@ static int start_thread(struct userdata *u) {
/* 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);
@ -1676,7 +1685,7 @@ static int start_thread(struct userdata *u) {
/* 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);
@ -1945,7 +1954,7 @@ static pa_card_profile *create_card_profile(struct userdata *u, pa_bluetooth_pro
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;
@ -1957,8 +1966,21 @@ static pa_card_profile *create_card_profile(struct userdata *u, pa_bluetooth_pro
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;
@ -1971,7 +1993,7 @@ static pa_card_profile *create_card_profile(struct userdata *u, pa_bluetooth_pro
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;
@ -2048,7 +2070,9 @@ static int uuid_to_profile(const char *uuid, pa_bluetooth_profile_t *_r) {
*_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;
@ -2269,7 +2293,7 @@ static pa_hook_result_t transport_speaker_gain_changed_cb(pa_bluetooth_discovery
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);
@ -2297,7 +2321,7 @@ static pa_hook_result_t transport_microphone_gain_changed_cb(pa_bluetooth_discov
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);