mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
bluez5: backend-ofono: set media_codec on created transports
Set media_codec on created transports. Also avoid using the HFP codec id in spa_bt_transport::codec
This commit is contained in:
parent
13256e9083
commit
61b0ea4589
1 changed files with 45 additions and 21 deletions
|
|
@ -23,6 +23,7 @@
|
||||||
#include <spa-private/dbus-helpers.h>
|
#include <spa-private/dbus-helpers.h>
|
||||||
|
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
#include "media-codecs.h"
|
||||||
|
|
||||||
#define INITIAL_INTERVAL_NSEC (500 * SPA_NSEC_PER_MSEC)
|
#define INITIAL_INTERVAL_NSEC (500 * SPA_NSEC_PER_MSEC)
|
||||||
#define ACTION_INTERVAL_NSEC (3000 * SPA_NSEC_PER_MSEC)
|
#define ACTION_INTERVAL_NSEC (3000 * SPA_NSEC_PER_MSEC)
|
||||||
|
|
@ -53,6 +54,7 @@ struct impl {
|
||||||
|
|
||||||
struct transport_data {
|
struct transport_data {
|
||||||
struct spa_source sco;
|
struct spa_source sco;
|
||||||
|
unsigned int codec_id;
|
||||||
unsigned int broken:1;
|
unsigned int broken:1;
|
||||||
unsigned int activated:1;
|
unsigned int activated:1;
|
||||||
};
|
};
|
||||||
|
|
@ -112,17 +114,26 @@ static struct spa_bt_transport *_transport_create(struct impl *backend,
|
||||||
const char *path,
|
const char *path,
|
||||||
struct spa_bt_device *device,
|
struct spa_bt_device *device,
|
||||||
enum spa_bt_profile profile,
|
enum spa_bt_profile profile,
|
||||||
int codec,
|
int codec_id,
|
||||||
struct spa_callbacks *impl)
|
struct spa_callbacks *impl)
|
||||||
{
|
{
|
||||||
struct spa_bt_transport *t = NULL;
|
struct spa_bt_transport *t = NULL;
|
||||||
char *t_path = strdup(path);
|
const struct media_codec *codec;
|
||||||
|
struct transport_data *td;
|
||||||
|
char *t_path;
|
||||||
|
|
||||||
|
codec = spa_bt_get_hfp_codec(backend->monitor, codec_id);
|
||||||
|
if (!codec) {
|
||||||
|
spa_log_warn(backend->log, "can't create transport: no HFP codec %d", codec_id);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_path = strdup(path);
|
||||||
t = spa_bt_transport_create(backend->monitor, t_path, sizeof(struct transport_data));
|
t = spa_bt_transport_create(backend->monitor, t_path, sizeof(struct transport_data));
|
||||||
if (t == NULL) {
|
if (t == NULL) {
|
||||||
spa_log_warn(backend->log, "can't create transport: %m");
|
spa_log_warn(backend->log, "can't create transport: %m");
|
||||||
free(t_path);
|
free(t_path);
|
||||||
goto finish;
|
return NULL;
|
||||||
}
|
}
|
||||||
spa_bt_transport_set_implementation(t, impl, t);
|
spa_bt_transport_set_implementation(t, impl, t);
|
||||||
|
|
||||||
|
|
@ -130,11 +141,14 @@ static struct spa_bt_transport *_transport_create(struct impl *backend,
|
||||||
spa_list_append(&t->device->transport_list, &t->device_link);
|
spa_list_append(&t->device->transport_list, &t->device_link);
|
||||||
t->backend = &backend->this;
|
t->backend = &backend->this;
|
||||||
t->profile = profile;
|
t->profile = profile;
|
||||||
t->codec = codec;
|
t->media_codec = codec;
|
||||||
|
t->codec = codec_id;
|
||||||
t->n_channels = 1;
|
t->n_channels = 1;
|
||||||
t->channels[0] = SPA_AUDIO_CHANNEL_MONO;
|
t->channels[0] = SPA_AUDIO_CHANNEL_MONO;
|
||||||
|
|
||||||
finish:
|
td = t->user_data;
|
||||||
|
td->codec_id = codec_id;
|
||||||
|
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -186,7 +200,7 @@ static int ofono_audio_acquire(void *data, bool optional)
|
||||||
struct spa_bt_transport *transport = data;
|
struct spa_bt_transport *transport = data;
|
||||||
struct transport_data *td = transport->user_data;
|
struct transport_data *td = transport->user_data;
|
||||||
struct impl *backend = SPA_CONTAINER_OF(transport->backend, struct impl, this);
|
struct impl *backend = SPA_CONTAINER_OF(transport->backend, struct impl, this);
|
||||||
uint8_t codec;
|
uint8_t codec_id;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
if (transport->fd >= 0)
|
if (transport->fd >= 0)
|
||||||
|
|
@ -198,17 +212,17 @@ static int ofono_audio_acquire(void *data, bool optional)
|
||||||
|
|
||||||
spa_bt_device_update_last_bluez_action_time(transport->device);
|
spa_bt_device_update_last_bluez_action_time(transport->device);
|
||||||
|
|
||||||
ret = _audio_acquire(backend, transport->path, &codec);
|
ret = _audio_acquire(backend, transport->path, &codec_id);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
transport->fd = ret;
|
transport->fd = ret;
|
||||||
|
|
||||||
if (transport->codec != codec) {
|
if (transport->media_codec->codec_id != codec_id) {
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
|
|
||||||
spa_log_info(backend->log, "transport %p: acquired codec (%d) differs from transport one (%d)",
|
spa_log_info(backend->log, "transport %p: acquired codec (%d) differs from transport one (%d)",
|
||||||
transport, codec, transport->codec);
|
transport, codec_id, transport->media_codec->codec_id);
|
||||||
|
|
||||||
/* shutdown to make sure connection is dropped immediately */
|
/* shutdown to make sure connection is dropped immediately */
|
||||||
shutdown(transport->fd, SHUT_RDWR);
|
shutdown(transport->fd, SHUT_RDWR);
|
||||||
|
|
@ -216,7 +230,7 @@ static int ofono_audio_acquire(void *data, bool optional)
|
||||||
transport->fd = -1;
|
transport->fd = -1;
|
||||||
|
|
||||||
/* schedule immediate profile update, from main loop */
|
/* schedule immediate profile update, from main loop */
|
||||||
transport->codec = codec;
|
td->codec_id = codec_id;
|
||||||
td->broken = true;
|
td->broken = true;
|
||||||
ts.tv_sec = 0;
|
ts.tv_sec = 0;
|
||||||
ts.tv_nsec = 1;
|
ts.tv_nsec = 1;
|
||||||
|
|
@ -229,8 +243,8 @@ static int ofono_audio_acquire(void *data, bool optional)
|
||||||
|
|
||||||
td->broken = false;
|
td->broken = false;
|
||||||
|
|
||||||
spa_log_debug(backend->log, "transport %p: Acquire %s, fd %d codec %d", transport,
|
spa_log_debug(backend->log, "transport %p: Acquire %s, fd %d codec %s", transport,
|
||||||
transport->path, transport->fd, transport->codec);
|
transport->path, transport->fd, transport->media_codec->description);
|
||||||
|
|
||||||
ofono_transport_get_mtu(backend, transport);
|
ofono_transport_get_mtu(backend, transport);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
@ -332,7 +346,7 @@ static bool activate_transport(struct spa_bt_transport *t, const void *data)
|
||||||
struct spa_bt_transport *t_copy;
|
struct spa_bt_transport *t_copy;
|
||||||
|
|
||||||
t_copy = _transport_create(backend, t->path, t->device,
|
t_copy = _transport_create(backend, t->path, t->device,
|
||||||
t->profile, t->codec, (struct spa_callbacks *)&ofono_transport_impl);
|
t->profile, td->codec_id, (struct spa_callbacks *)&ofono_transport_impl);
|
||||||
spa_bt_transport_free(t);
|
spa_bt_transport_free(t);
|
||||||
|
|
||||||
if (t_copy)
|
if (t_copy)
|
||||||
|
|
@ -364,7 +378,7 @@ static DBusHandlerResult ofono_audio_card_found(struct impl *backend, char *path
|
||||||
struct spa_bt_transport *t;
|
struct spa_bt_transport *t;
|
||||||
struct transport_data *td;
|
struct transport_data *td;
|
||||||
enum spa_bt_profile profile = SPA_BT_PROFILE_HFP_AG;
|
enum spa_bt_profile profile = SPA_BT_PROFILE_HFP_AG;
|
||||||
uint8_t codec = backend->msbc_supported ?
|
uint8_t codec_id = backend->msbc_supported ?
|
||||||
HFP_AUDIO_CODEC_MSBC : HFP_AUDIO_CODEC_CVSD;
|
HFP_AUDIO_CODEC_MSBC : HFP_AUDIO_CODEC_CVSD;
|
||||||
|
|
||||||
spa_assert(backend);
|
spa_assert(backend);
|
||||||
|
|
@ -417,7 +431,7 @@ static DBusHandlerResult ofono_audio_card_found(struct impl *backend, char *path
|
||||||
}
|
}
|
||||||
spa_bt_device_add_profile(d, profile);
|
spa_bt_device_add_profile(d, profile);
|
||||||
|
|
||||||
t = _transport_create(backend, path, d, profile, codec, (struct spa_callbacks *)&ofono_transport_impl);
|
t = _transport_create(backend, path, d, profile, codec_id, (struct spa_callbacks *)&ofono_transport_impl);
|
||||||
if (t == NULL) {
|
if (t == NULL) {
|
||||||
spa_log_error(backend->log, "failed to create transport: %s", spa_strerror(-errno));
|
spa_log_error(backend->log, "failed to create transport: %s", spa_strerror(-errno));
|
||||||
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||||
|
|
@ -444,7 +458,7 @@ static DBusHandlerResult ofono_audio_card_found(struct impl *backend, char *path
|
||||||
spa_bt_device_connect_profile(t->device, t->profile);
|
spa_bt_device_connect_profile(t->device, t->profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
spa_log_debug(backend->log, "Transport %s available, codec %d", t->path, t->codec);
|
spa_log_debug(backend->log, "Transport %s available, codec %s", t->path, t->media_codec->description);
|
||||||
|
|
||||||
return DBUS_HANDLER_RESULT_HANDLED;
|
return DBUS_HANDLER_RESULT_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
@ -513,7 +527,7 @@ static DBusHandlerResult ofono_new_audio_connection(DBusConnection *conn, DBusMe
|
||||||
struct impl *backend = userdata;
|
struct impl *backend = userdata;
|
||||||
const char *path;
|
const char *path;
|
||||||
int fd;
|
int fd;
|
||||||
uint8_t codec;
|
uint8_t codec_id;
|
||||||
struct spa_bt_transport *t;
|
struct spa_bt_transport *t;
|
||||||
struct transport_data *td;
|
struct transport_data *td;
|
||||||
spa_autoptr(DBusMessage) r = NULL;
|
spa_autoptr(DBusMessage) r = NULL;
|
||||||
|
|
@ -521,7 +535,7 @@ static DBusHandlerResult ofono_new_audio_connection(DBusConnection *conn, DBusMe
|
||||||
if (dbus_message_get_args(m, NULL,
|
if (dbus_message_get_args(m, NULL,
|
||||||
DBUS_TYPE_OBJECT_PATH, &path,
|
DBUS_TYPE_OBJECT_PATH, &path,
|
||||||
DBUS_TYPE_UNIX_FD, &fd,
|
DBUS_TYPE_UNIX_FD, &fd,
|
||||||
DBUS_TYPE_BYTE, &codec,
|
DBUS_TYPE_BYTE, &codec_id,
|
||||||
DBUS_TYPE_INVALID) == FALSE) {
|
DBUS_TYPE_INVALID) == FALSE) {
|
||||||
r = dbus_message_new_error(m, OFONO_ERROR_INVALID_ARGUMENTS, "Invalid arguments in method call");
|
r = dbus_message_new_error(m, OFONO_ERROR_INVALID_ARGUMENTS, "Invalid arguments in method call");
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
@ -530,6 +544,15 @@ static DBusHandlerResult ofono_new_audio_connection(DBusConnection *conn, DBusMe
|
||||||
t = spa_bt_transport_find(backend->monitor, path);
|
t = spa_bt_transport_find(backend->monitor, path);
|
||||||
if (t && (t->profile & SPA_BT_PROFILE_HEADSET_AUDIO_GATEWAY)) {
|
if (t && (t->profile & SPA_BT_PROFILE_HEADSET_AUDIO_GATEWAY)) {
|
||||||
int err;
|
int err;
|
||||||
|
const struct media_codec *codec;
|
||||||
|
|
||||||
|
codec = spa_bt_get_hfp_codec(backend->monitor, codec_id);
|
||||||
|
if (!codec) {
|
||||||
|
spa_log_error(backend->log, "transport %p: Couldn't find HFP codec %d", t, codec_id);
|
||||||
|
shutdown(fd, SHUT_RDWR);
|
||||||
|
close(fd);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
err = enable_sco_socket(fd);
|
err = enable_sco_socket(fd);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|
@ -541,10 +564,11 @@ static DBusHandlerResult ofono_new_audio_connection(DBusConnection *conn, DBusMe
|
||||||
}
|
}
|
||||||
|
|
||||||
t->fd = fd;
|
t->fd = fd;
|
||||||
t->codec = codec;
|
t->codec = codec_id;
|
||||||
|
t->media_codec = codec;
|
||||||
|
|
||||||
spa_log_debug(backend->log, "transport %p: NewConnection %s, fd %d codec %d",
|
spa_log_debug(backend->log, "transport %p: NewConnection %s, fd %d codec %s",
|
||||||
t, t->path, t->fd, t->codec);
|
t, t->path, t->fd, t->media_codec->description);
|
||||||
|
|
||||||
td = t->user_data;
|
td = t->user_data;
|
||||||
td->sco.func = sco_event;
|
td->sco.func = sco_event;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue