bluez5: add support for hardware quirk/feature database

Implement hardware quirk/feature database with pattern matching.
This commit is contained in:
Pauli Virtanen 2021-01-24 15:15:27 +02:00
parent 88077a29db
commit b57ae8c2a6
9 changed files with 396 additions and 15 deletions

View file

@ -7,10 +7,11 @@
properties = {
# These features do not work on all headsets, so they are enabled
# by default based on the hardware database. They can also be
# forced on/off by the following options:
# forced on/off for all devices by the following options:
#bluez5.force-sbc-xq = true
#bluez5.force-msbc = true
#bluez5.enable-sbc-xq = true
#bluez5.enable-msbc = true
#bluez5.enable-hw-volume = true
# See bluez-hardware.conf for the hardware database.
@ -62,10 +63,7 @@ rules = [
#]
bluez5.auto-connect = [ hfp_hf hsp_hs a2dp_sink ]
# Overload mSBC support for native backend and a specific device.
#bluez5.msbc-support = false
# Hardware volume control (default: [ hfp_ag hsp_ag a2dp_source ])
# Hardware volume control (default: all)
#bluez5.hw-volume = [
# hfp_hf
# hsp_hs

View file

@ -49,6 +49,7 @@
#define NAME "bluez5-monitor"
#define SESSION_CONF "bluez-monitor.conf"
#define FEATURES_CONF "bluez-hardware.conf"
struct device;
@ -715,7 +716,9 @@ int sm_bluez5_monitor_start(struct sm_media_session *session)
{
int res;
struct impl *impl;
const char *str;
const char *key, *str;
struct pw_properties *hw_features = NULL;
void *state = NULL;
impl = calloc(1, sizeof(struct impl));
if (impl == NULL) {
@ -731,9 +734,16 @@ int sm_bluez5_monitor_start(struct sm_media_session *session)
res = -errno;
goto out_free;
}
if ((hw_features = pw_properties_new(NULL, NULL)) == NULL) {
res = -errno;
goto out_free;
}
if ((res = sm_media_session_load_conf(impl->session,
SESSION_CONF, impl->conf)) < 0)
pw_log_info("can't load "SESSION_CONF" config: %s", spa_strerror(res));
if ((res = sm_media_session_load_conf(impl->session,
FEATURES_CONF, hw_features)) < 0)
pw_log_info("can't load "FEATURES_CONF" config: %s", spa_strerror(res));
if ((impl->props = pw_properties_new(NULL, NULL)) == NULL) {
res = -errno;
@ -744,14 +754,23 @@ int sm_bluez5_monitor_start(struct sm_media_session *session)
pw_properties_set(impl->props, "api.bluez5.connection-info", "true");
while ((key = pw_properties_iterate(hw_features, &state)) != NULL) {
if (strncmp(key, "bluez5.features.", strlen("bluez5.features.")) != 0)
continue;
if ((str = pw_properties_get(hw_features, key)) != NULL)
pw_properties_set(impl->props, key, str);
}
pw_properties_free(hw_features);
sm_media_session_add_listener(session, &impl->session_listener,
&session_events, impl);
return 0;
out_free:
pw_properties_free(impl->conf);
pw_properties_free(impl->props);
pw_properties_free(hw_features);
free(impl);
out:
return res;