mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-12-16 08:56:45 -05:00
bluez5: allow disabling sink or source endpoints
Add option bluez5.roles that selects which endpoints (A2DP, BAP, HFP, HSP) will be enabled. This extends and deprecates bluez5.headset-roles.
This commit is contained in:
parent
a49d2d41af
commit
fa3ee2e20b
2 changed files with 49 additions and 3 deletions
|
|
@ -40,6 +40,7 @@ static struct spa_log_topic log_topic = SPA_LOG_TOPIC(0, "spa.bluez5.native");
|
||||||
#undef SPA_LOG_TOPIC_DEFAULT
|
#undef SPA_LOG_TOPIC_DEFAULT
|
||||||
#define SPA_LOG_TOPIC_DEFAULT &log_topic
|
#define SPA_LOG_TOPIC_DEFAULT &log_topic
|
||||||
|
|
||||||
|
#define PROP_KEY_ROLES "bluez5.roles"
|
||||||
#define PROP_KEY_HEADSET_ROLES "bluez5.headset-roles"
|
#define PROP_KEY_HEADSET_ROLES "bluez5.headset-roles"
|
||||||
|
|
||||||
#define HFP_CODEC_SWITCH_INITIAL_TIMEOUT_MSEC 5000
|
#define HFP_CODEC_SWITCH_INITIAL_TIMEOUT_MSEC 5000
|
||||||
|
|
@ -2706,8 +2707,11 @@ static int parse_headset_roles(struct impl *backend, const struct spa_dict *info
|
||||||
const char *str;
|
const char *str;
|
||||||
int profiles = SPA_BT_PROFILE_NULL;
|
int profiles = SPA_BT_PROFILE_NULL;
|
||||||
|
|
||||||
if (info == NULL ||
|
if (!info)
|
||||||
(str = spa_dict_lookup(info, PROP_KEY_HEADSET_ROLES)) == NULL)
|
goto fallback;
|
||||||
|
|
||||||
|
if ((str = spa_dict_lookup(info, PROP_KEY_ROLES)) == NULL &&
|
||||||
|
(str = spa_dict_lookup(info, PROP_KEY_HEADSET_ROLES)) == NULL)
|
||||||
goto fallback;
|
goto fallback;
|
||||||
|
|
||||||
profiles = spa_bt_profiles_from_json_array(str);
|
profiles = spa_bt_profiles_from_json_array(str);
|
||||||
|
|
|
||||||
|
|
@ -103,6 +103,8 @@ struct spa_bt_monitor {
|
||||||
|
|
||||||
struct spa_dict enabled_codecs;
|
struct spa_dict enabled_codecs;
|
||||||
|
|
||||||
|
enum spa_bt_profile enabled_profiles;
|
||||||
|
|
||||||
unsigned int connection_info_supported:1;
|
unsigned int connection_info_supported:1;
|
||||||
unsigned int dummy_avrcp_player:1;
|
unsigned int dummy_avrcp_player:1;
|
||||||
|
|
||||||
|
|
@ -508,6 +510,19 @@ static bool codec_has_direction(const struct media_codec *codec, enum spa_bt_med
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum spa_bt_profile get_codec_profile(const struct media_codec *codec,
|
||||||
|
enum spa_bt_media_direction direction)
|
||||||
|
{
|
||||||
|
switch (direction) {
|
||||||
|
case SPA_BT_MEDIA_SOURCE:
|
||||||
|
return codec->bap ? SPA_BT_PROFILE_BAP_SOURCE : SPA_BT_PROFILE_A2DP_SOURCE;
|
||||||
|
case SPA_BT_MEDIA_SINK:
|
||||||
|
return codec->bap ? SPA_BT_PROFILE_BAP_SINK : SPA_BT_PROFILE_A2DP_SINK;
|
||||||
|
default:
|
||||||
|
spa_assert_not_reached();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool endpoint_should_be_registered(struct spa_bt_monitor *monitor,
|
static bool endpoint_should_be_registered(struct spa_bt_monitor *monitor,
|
||||||
const struct media_codec *codec,
|
const struct media_codec *codec,
|
||||||
enum spa_bt_media_direction direction)
|
enum spa_bt_media_direction direction)
|
||||||
|
|
@ -517,7 +532,8 @@ static bool endpoint_should_be_registered(struct spa_bt_monitor *monitor,
|
||||||
*/
|
*/
|
||||||
return is_media_codec_enabled(monitor, codec) &&
|
return is_media_codec_enabled(monitor, codec) &&
|
||||||
codec_has_direction(codec, direction) &&
|
codec_has_direction(codec, direction) &&
|
||||||
codec->fill_caps;
|
codec->fill_caps &&
|
||||||
|
(get_codec_profile(codec, direction) & monitor->enabled_profiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DBusHandlerResult endpoint_select_configuration(DBusConnection *conn, DBusMessage *m, void *userdata)
|
static DBusHandlerResult endpoint_select_configuration(DBusConnection *conn, DBusMessage *m, void *userdata)
|
||||||
|
|
@ -5000,6 +5016,30 @@ int spa_bt_profiles_from_json_array(const char *str)
|
||||||
return profiles;
|
return profiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int parse_roles(struct spa_bt_monitor *monitor, const struct spa_dict *info)
|
||||||
|
{
|
||||||
|
const char *str;
|
||||||
|
int res = 0;
|
||||||
|
int profiles = SPA_BT_PROFILE_MEDIA_SINK | SPA_BT_PROFILE_MEDIA_SOURCE;
|
||||||
|
|
||||||
|
/* HSP/HFP backends parse this property separately */
|
||||||
|
if (info && (str = spa_dict_lookup(info, "bluez5.roles"))) {
|
||||||
|
res = spa_bt_profiles_from_json_array(str);
|
||||||
|
if (res < 0) {
|
||||||
|
spa_log_warn(monitor->log, "malformed bluez5.roles setting ignored");
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
profiles &= res;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = 0;
|
||||||
|
|
||||||
|
done:
|
||||||
|
monitor->enabled_profiles = profiles;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static int parse_codec_array(struct spa_bt_monitor *this, const struct spa_dict *info)
|
static int parse_codec_array(struct spa_bt_monitor *this, const struct spa_dict *info)
|
||||||
{
|
{
|
||||||
const struct media_codec * const * const media_codecs = this->media_codecs;
|
const struct media_codec * const * const media_codecs = this->media_codecs;
|
||||||
|
|
@ -5185,6 +5225,8 @@ impl_init(const struct spa_handle_factory *factory,
|
||||||
if ((res = parse_codec_array(this, info)) < 0)
|
if ((res = parse_codec_array(this, info)) < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
parse_roles(this, info);
|
||||||
|
|
||||||
this->default_audio_info.rate = A2DP_CODEC_DEFAULT_RATE;
|
this->default_audio_info.rate = A2DP_CODEC_DEFAULT_RATE;
|
||||||
this->default_audio_info.channels = A2DP_CODEC_DEFAULT_CHANNELS;
|
this->default_audio_info.channels = A2DP_CODEC_DEFAULT_CHANNELS;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue