diff --git a/src/modules/bluetooth/backend-native.c b/src/modules/bluetooth/backend-native.c index 569cc6d36..50a58c6d3 100644 --- a/src/modules/bluetooth/backend-native.c +++ b/src/modules/bluetooth/backend-native.c @@ -917,7 +917,7 @@ static void rfcomm_io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_i * RING: Sent by AG to HS to notify of an incoming call. It can safely be ignored because * it does not expect a reply. */ if (sscanf(buf, "AT+VGS=%d", &gain) == 1 || sscanf(buf, "\r\n+VGM%*[=:]%d\r\n", &gain) == 1) { - if (!t->set_sink_volume) { + if (!t->set_sink_volume && !(t->device->quirk & PA_BLUETOOTH_QUIRK_NO_VOLUME_CTL)) { pa_log_debug("HS/HF peer supports speaker gain control"); t->set_sink_volume = set_sink_volume; } @@ -927,7 +927,7 @@ static void rfcomm_io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_i do_reply = true; } else if (sscanf(buf, "AT+VGM=%d", &gain) == 1 || sscanf(buf, "\r\n+VGS%*[=:]%d\r\n", &gain) == 1) { - if (!t->set_source_volume) { + if (!t->set_source_volume && !(t->device->quirk & PA_BLUETOOTH_QUIRK_NO_VOLUME_CTL)) { pa_log_debug("HS/HF peer supports microphone gain control"); t->set_source_volume = set_source_volume; } diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h index fff3d573c..d8468629d 100644 --- a/src/modules/bluetooth/bluez5-util.h +++ b/src/modules/bluetooth/bluez5-util.h @@ -155,6 +155,7 @@ struct pa_bluetooth_device { char *alias; char *address; uint32_t class_of_device; + uint32_t quirk; pa_hashmap *uuids; /* char* -> char* (hashmap-as-a-set) */ /* pa_a2dp_codec_id* -> pa_hashmap ( char* (remote endpoint) -> struct a2dp_codec_capabilities* ) */ pa_hashmap *a2dp_sink_endpoints; @@ -180,6 +181,10 @@ struct pa_bluetooth_adapter { bool battery_provider_registered; }; +typedef enum pa_bluetooth_quirk_def { + PA_BLUETOOTH_QUIRK_NO_VOLUME_CTL = (1 << 0), +} pa_bluetooth_quirk_def_t; + #ifdef HAVE_BLUEZ_5_OFONO_HEADSET pa_bluetooth_backend *pa_bluetooth_ofono_backend_new(pa_core *c, pa_bluetooth_discovery *y); void pa_bluetooth_ofono_backend_free(pa_bluetooth_backend *b); diff --git a/src/modules/bluetooth/module-bluez5-device.c b/src/modules/bluetooth/module-bluez5-device.c index dc6809ce5..2f3d1d811 100644 --- a/src/modules/bluetooth/module-bluez5-device.c +++ b/src/modules/bluetooth/module-bluez5-device.c @@ -183,6 +183,16 @@ typedef enum pa_bluetooth_form_factor { PA_BLUETOOTH_FORM_FACTOR_PHONE, } pa_bluetooth_form_factor_t; +struct pa_bluetooth_quirk_table { + char *alias; + pa_bluetooth_quirk_def_t q; +}; + +static struct pa_bluetooth_quirk_table quirk_tbl[] = { + {.alias = "联想 thinkplus XT99", .q = PA_BLUETOOTH_QUIRK_NO_VOLUME_CTL}, + {} +}; + /* Run from main thread */ static pa_bluetooth_form_factor_t form_factor_from_class(uint32_t class_of_device) { unsigned major, minor; @@ -2787,6 +2797,18 @@ static pa_hook_result_t a2dp_source_output_fixate_hook_callback(pa_core *c, pa_s return PA_HOOK_OK; } +static void apply_quirk (pa_bluetooth_device *d) { + int i = 0; + + d->quirk = 0; + + while (quirk_tbl[i].alias) { + if (pa_streq(d->alias, quirk_tbl[i].alias)) + d->quirk = quirk_tbl[i].q; + i++; + } +} + int pa__init(pa_module* m) { struct userdata *u; const char *path; @@ -2824,6 +2846,8 @@ int pa__init(pa_module* m) { goto fail_free_modargs; } + apply_quirk(u->device); + autodetect_mtu = false; if (pa_modargs_get_value_boolean(ma, "autodetect_mtu", &autodetect_mtu) < 0) { pa_log("Invalid boolean value for autodetect_mtu parameter");