mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-12-02 00:24:25 +08:00
Fix alsa plugin to reflect the ipc changes.
This commit is contained in:
parent
9937db5c59
commit
1c01d240ba
@ -141,49 +141,61 @@ static int bluetooth_get_integer_info(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key,
|
||||
}
|
||||
|
||||
static int bluetooth_send_ctl(struct bluetooth_data *data,
|
||||
uint8_t mode, uint8_t key, struct bt_control_rsp *ctl_rsp)
|
||||
uint8_t mode, uint8_t key, struct bt_control_rsp *rsp)
|
||||
{
|
||||
int ret;
|
||||
struct bt_control_req *ctl_req = (void *) ctl_rsp;
|
||||
const char *type;
|
||||
struct bt_control_req *req = (void *) rsp;
|
||||
bt_audio_error_t *err = (void *) rsp;
|
||||
const char *type, *name;
|
||||
|
||||
memset(ctl_req, 0, BT_AUDIO_IPC_PACKET_SIZE);
|
||||
ctl_req->h.msg_type = BT_CONTROL_REQ;
|
||||
ctl_req->mode = mode;
|
||||
ctl_req->key = key;
|
||||
memset(req, 0, BT_SUGGESTED_BUFFER_SIZE);
|
||||
req->h.type = BT_REQUEST;
|
||||
req->h.name = BT_CONTROL;
|
||||
req->h.length = sizeof(*req);
|
||||
|
||||
ret = send(data->sock, ctl_req, BT_AUDIO_IPC_PACKET_SIZE, MSG_NOSIGNAL);
|
||||
req->mode = mode;
|
||||
req->key = key;
|
||||
|
||||
ret = send(data->sock, req, BT_SUGGESTED_BUFFER_SIZE, MSG_NOSIGNAL);
|
||||
if (ret <= 0) {
|
||||
SYSERR("Unable to request new volume value to server");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
ret = recv(data->sock, ctl_rsp, BT_AUDIO_IPC_PACKET_SIZE, 0);
|
||||
ret = recv(data->sock, rsp, BT_SUGGESTED_BUFFER_SIZE, 0);
|
||||
if (ret <= 0) {
|
||||
SNDERR("Unable to receive new volume value from server");
|
||||
return -errno;
|
||||
}
|
||||
|
||||
type = bt_audio_strmsg(ctl_rsp->rsp_h.msg_h.msg_type);
|
||||
if (rsp->h.type == BT_ERROR) {
|
||||
SNDERR("BT_CONTROL failed : %s (%d)",
|
||||
strerror(err->posix_errno),
|
||||
err->posix_errno);
|
||||
return -err->posix_errno;
|
||||
}
|
||||
|
||||
type = bt_audio_strtype(rsp->h.type);
|
||||
if (!type) {
|
||||
SNDERR("Bogus message type %d "
|
||||
"received from audio service",
|
||||
ctl_rsp->rsp_h.msg_h.msg_type);
|
||||
rsp->h.type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctl_rsp->rsp_h.msg_h.msg_type != BT_CONTROL_RSP) {
|
||||
name = bt_audio_strname(rsp->h.name);
|
||||
if (!name) {
|
||||
SNDERR("Bogus message name %d "
|
||||
"received from audio service",
|
||||
rsp->h.name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (rsp->h.name != BT_CONTROL) {
|
||||
SNDERR("Unexpected message %s received", type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctl_rsp->rsp_h.posix_errno != 0) {
|
||||
SNDERR("BT_CONTROL failed : %s (%d)",
|
||||
strerror(ctl_rsp->rsp_h.posix_errno),
|
||||
ctl_rsp->rsp_h.posix_errno);
|
||||
return -ctl_rsp->rsp_h.posix_errno;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -192,7 +204,7 @@ static int bluetooth_read_integer(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key,
|
||||
{
|
||||
struct bluetooth_data *data = ext->private_data;
|
||||
int ret;
|
||||
char buf[BT_AUDIO_IPC_PACKET_SIZE];
|
||||
char buf[BT_SUGGESTED_BUFFER_SIZE];
|
||||
struct bt_control_rsp *rsp = (void *) buf;
|
||||
|
||||
DBG("ext %p key %ld", ext, key);
|
||||
@ -213,7 +225,7 @@ static int bluetooth_write_integer(snd_ctl_ext_t *ext, snd_ctl_ext_key_t key,
|
||||
long *value)
|
||||
{
|
||||
struct bluetooth_data *data = ext->private_data;
|
||||
char buf[BT_AUDIO_IPC_PACKET_SIZE];
|
||||
char buf[BT_SUGGESTED_BUFFER_SIZE];
|
||||
struct bt_control_rsp *rsp = (void *) buf;
|
||||
long current;
|
||||
int ret, keyvalue;
|
||||
@ -245,26 +257,34 @@ static int bluetooth_read_event(snd_ctl_ext_t *ext, snd_ctl_elem_id_t *id,
|
||||
unsigned int *event_mask)
|
||||
{
|
||||
struct bluetooth_data *data = ext->private_data;
|
||||
char buf[BT_AUDIO_IPC_PACKET_SIZE];
|
||||
char buf[BT_SUGGESTED_BUFFER_SIZE];
|
||||
struct bt_control_ind *ind = (void *) buf;
|
||||
int ret;
|
||||
const char *type;
|
||||
const char *type, *name;
|
||||
|
||||
DBG("ext %p id %p", ext, id);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
|
||||
ret = recv(data->sock, ind, BT_AUDIO_IPC_PACKET_SIZE, MSG_DONTWAIT);
|
||||
type = bt_audio_strmsg(ind->h.msg_type);
|
||||
ret = recv(data->sock, ind, BT_SUGGESTED_BUFFER_SIZE, MSG_DONTWAIT);
|
||||
type = bt_audio_strtype(ind->h.type);
|
||||
if (!type) {
|
||||
SNDERR("Bogus message type %d "
|
||||
"received from audio service",
|
||||
ind->h.msg_type);
|
||||
ind->h.type);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if (ind->h.msg_type != BT_CONTROL_IND) {
|
||||
SNDERR("Unexpected message %s received", type);
|
||||
name = bt_audio_strname(ind->h.name);
|
||||
if (!name) {
|
||||
SNDERR("Bogus message name %d "
|
||||
"received from audio service",
|
||||
ind->h.name);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if (ind->h.name != BT_CONTROL) {
|
||||
SNDERR("Unexpected message %s received", name);
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
|
@ -332,10 +332,10 @@ static int bluetooth_prepare(snd_pcm_ioplug_t *io)
|
||||
{
|
||||
struct bluetooth_data *data = io->private_data;
|
||||
char c = 'w';
|
||||
char buf[BT_AUDIO_IPC_PACKET_SIZE];
|
||||
struct bt_streamstart_req *start_req = (void*) buf;
|
||||
bt_audio_rsp_msg_header_t *rsp_hdr = (void*) buf;
|
||||
struct bt_streamfd_ind *streamfd_ind = (void*) buf;
|
||||
char buf[BT_SUGGESTED_BUFFER_SIZE];
|
||||
struct bt_start_stream_req *req = (void*) buf;
|
||||
bt_audio_msg_header_t *rsp = (void*) buf;
|
||||
struct bt_new_stream_ind *ind = (void*) buf;
|
||||
uint32_t period_count = io->buffer_size / io->period_size;
|
||||
int opt_name, err;
|
||||
struct timeval t = { 0, period_count };
|
||||
@ -363,27 +363,22 @@ static int bluetooth_prepare(snd_pcm_ioplug_t *io)
|
||||
data->hw_ptr = io->period_size;
|
||||
|
||||
/* send start */
|
||||
memset(start_req, 0, BT_AUDIO_IPC_PACKET_SIZE);
|
||||
start_req->h.msg_type = BT_STREAMSTART_REQ;
|
||||
memset(req, 0, BT_SUGGESTED_BUFFER_SIZE);
|
||||
req->h.type = BT_REQUEST;
|
||||
req->h.name = BT_START_STREAM;
|
||||
req->h.length = sizeof(*req);
|
||||
|
||||
err = audioservice_send(data->server.fd, &start_req->h);
|
||||
err = audioservice_send(data->server.fd, &req->h);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = audioservice_expect(data->server.fd, &rsp_hdr->msg_h,
|
||||
BT_STREAMSTART_RSP);
|
||||
err = audioservice_expect(data->server.fd, rsp,
|
||||
BT_START_STREAM);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (rsp_hdr->posix_errno != 0) {
|
||||
SNDERR("BT_START failed : %s(%d)",
|
||||
strerror(rsp_hdr->posix_errno),
|
||||
rsp_hdr->posix_errno);
|
||||
return -rsp_hdr->posix_errno;
|
||||
}
|
||||
|
||||
err = audioservice_expect(data->server.fd, &streamfd_ind->h,
|
||||
BT_STREAMFD_IND);
|
||||
err = audioservice_expect(data->server.fd, &ind->h,
|
||||
BT_NEW_STREAM);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
@ -432,19 +427,21 @@ static int bluetooth_hsp_hw_params(snd_pcm_ioplug_t *io,
|
||||
snd_pcm_hw_params_t *params)
|
||||
{
|
||||
struct bluetooth_data *data = io->private_data;
|
||||
char buf[BT_AUDIO_IPC_PACKET_SIZE];
|
||||
bt_audio_rsp_msg_header_t *rsp_hdr = (void*) buf;
|
||||
struct bt_setconfiguration_req *setconf_req = (void*) buf;
|
||||
struct bt_setconfiguration_rsp *setconf_rsp = (void*) buf;
|
||||
char buf[BT_SUGGESTED_BUFFER_SIZE];
|
||||
bt_audio_msg_header_t *rsp = (void*) buf;
|
||||
struct bt_set_configuration_req *setconf_req = (void*) buf;
|
||||
struct bt_set_configuration_rsp *setconf_rsp = (void*) buf;
|
||||
int err;
|
||||
|
||||
DBG("Preparing with io->period_size=%lu io->buffer_size=%lu",
|
||||
io->period_size, io->buffer_size);
|
||||
|
||||
memset(setconf_req, 0, BT_AUDIO_IPC_PACKET_SIZE);
|
||||
setconf_req->h.msg_type = BT_SETCONFIGURATION_REQ;
|
||||
memset(setconf_req, 0, BT_SUGGESTED_BUFFER_SIZE);
|
||||
setconf_req->h.type = BT_REQUEST;
|
||||
setconf_req->h.name = BT_SET_CONFIGURATION;
|
||||
|
||||
strncpy(setconf_req->device, data->alsa_config.device, 18);
|
||||
setconf_req->transport = BT_CAPABILITIES_TRANSPORT_SCO;
|
||||
setconf_req->codec.transport = BT_CAPABILITIES_TRANSPORT_SCO;
|
||||
setconf_req->access_mode = (io->stream == SND_PCM_STREAM_PLAYBACK ?
|
||||
BT_CAPABILITIES_ACCESS_MODE_WRITE :
|
||||
BT_CAPABILITIES_ACCESS_MODE_READ);
|
||||
@ -453,18 +450,11 @@ static int bluetooth_hsp_hw_params(snd_pcm_ioplug_t *io,
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = audioservice_expect(data->server.fd, &rsp_hdr->msg_h,
|
||||
BT_SETCONFIGURATION_RSP);
|
||||
err = audioservice_expect(data->server.fd, rsp,
|
||||
BT_SET_CONFIGURATION);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (rsp_hdr->posix_errno != 0) {
|
||||
SNDERR("BT_SETCONFIGURATION failed : %s(%d)",
|
||||
strerror(rsp_hdr->posix_errno),
|
||||
rsp_hdr->posix_errno);
|
||||
return -rsp_hdr->posix_errno;
|
||||
}
|
||||
|
||||
data->transport = setconf_rsp->transport;
|
||||
data->link_mtu = setconf_rsp->link_mtu;
|
||||
|
||||
@ -675,11 +665,12 @@ static int bluetooth_a2dp_hw_params(snd_pcm_ioplug_t *io,
|
||||
{
|
||||
struct bluetooth_data *data = io->private_data;
|
||||
struct bluetooth_a2dp *a2dp = &data->a2dp;
|
||||
char buf[BT_AUDIO_IPC_PACKET_SIZE];
|
||||
bt_audio_rsp_msg_header_t *rsp_hdr = (void*) buf;
|
||||
struct bt_setconfiguration_req *setconf_req = (void*) buf;
|
||||
struct bt_setconfiguration_rsp *setconf_rsp = (void*) buf;
|
||||
char buf[BT_SUGGESTED_BUFFER_SIZE];
|
||||
bt_audio_msg_header_t *rsp = (void*) buf;
|
||||
struct bt_set_configuration_req *setconf_req = (void*) buf;
|
||||
struct bt_set_configuration_rsp *setconf_rsp = (void*) buf;
|
||||
int err;
|
||||
sbc_capabilities_t *sbc;
|
||||
|
||||
DBG("Preparing with io->period_size=%lu io->buffer_size=%lu",
|
||||
io->period_size, io->buffer_size);
|
||||
@ -688,11 +679,17 @@ static int bluetooth_a2dp_hw_params(snd_pcm_ioplug_t *io,
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
memset(setconf_req, 0, BT_AUDIO_IPC_PACKET_SIZE);
|
||||
setconf_req->h.msg_type = BT_SETCONFIGURATION_REQ;
|
||||
memset(setconf_req, 0, BT_SUGGESTED_BUFFER_SIZE);
|
||||
setconf_req->h.type = BT_REQUEST;
|
||||
setconf_req->h.name = BT_SET_CONFIGURATION;
|
||||
|
||||
strncpy(setconf_req->device, data->alsa_config.device, 18);
|
||||
setconf_req->transport = BT_CAPABILITIES_TRANSPORT_A2DP;
|
||||
setconf_req->sbc_capabilities = a2dp->sbc_capabilities;
|
||||
|
||||
sbc = (void *) &setconf_req->codec;
|
||||
*sbc = a2dp->sbc_capabilities;
|
||||
|
||||
setconf_req->codec.transport = BT_CAPABILITIES_TRANSPORT_A2DP;
|
||||
setconf_req->codec.length = sizeof(sbc_capabilities_t);
|
||||
setconf_req->access_mode = (io->stream == SND_PCM_STREAM_PLAYBACK ?
|
||||
BT_CAPABILITIES_ACCESS_MODE_WRITE :
|
||||
BT_CAPABILITIES_ACCESS_MODE_READ);
|
||||
@ -701,18 +698,11 @@ static int bluetooth_a2dp_hw_params(snd_pcm_ioplug_t *io,
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = audioservice_expect(data->server.fd, &rsp_hdr->msg_h,
|
||||
BT_SETCONFIGURATION_RSP);
|
||||
err = audioservice_expect(data->server.fd, rsp,
|
||||
BT_SET_CONFIGURATION);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (rsp_hdr->posix_errno != 0) {
|
||||
SNDERR("BT_SETCONFIGURATION failed : %s(%d)",
|
||||
strerror(rsp_hdr->posix_errno),
|
||||
rsp_hdr->posix_errno);
|
||||
return -rsp_hdr->posix_errno;
|
||||
}
|
||||
|
||||
data->transport = setconf_rsp->transport;
|
||||
data->link_mtu = setconf_rsp->link_mtu;
|
||||
|
||||
@ -1497,7 +1487,7 @@ static int audioservice_send(int sk, const bt_audio_msg_header_t *msg)
|
||||
int err;
|
||||
|
||||
DBG("sending %s", bt_audio_strmsg(msg->msg_type));
|
||||
if (send(sk, msg, BT_AUDIO_IPC_PACKET_SIZE, 0) > 0)
|
||||
if (send(sk, msg, BT_SUGGESTED_BUFFER_SIZE, 0) > 0)
|
||||
err = 0;
|
||||
else {
|
||||
err = -errno;
|
||||
@ -1511,19 +1501,20 @@ static int audioservice_send(int sk, const bt_audio_msg_header_t *msg)
|
||||
static int audioservice_recv(int sk, bt_audio_msg_header_t *inmsg)
|
||||
{
|
||||
int err;
|
||||
const char *type;
|
||||
const char *type, *name;
|
||||
|
||||
DBG("trying to receive msg from audio service...");
|
||||
if (recv(sk, inmsg, BT_AUDIO_IPC_PACKET_SIZE, 0) > 0) {
|
||||
type = bt_audio_strmsg(inmsg->msg_type);
|
||||
if (type) {
|
||||
DBG("Received %s", type);
|
||||
if (recv(sk, inmsg, BT_SUGGESTED_BUFFER_SIZE, 0) > 0) {
|
||||
type = bt_audio_strtype(inmsg->type);
|
||||
name = bt_audio_strname(inmsg->name);
|
||||
if (type && name) {
|
||||
DBG("Received %s - %s", type, name);
|
||||
err = 0;
|
||||
} else {
|
||||
err = -EINVAL;
|
||||
SNDERR("Bogus message type %d "
|
||||
SNDERR("Bogus message type %d - name %d"
|
||||
"received from audio service",
|
||||
inmsg->msg_type);
|
||||
inmsg->type, inmsg->name);
|
||||
}
|
||||
} else {
|
||||
err = -errno;
|
||||
@ -1534,31 +1525,71 @@ static int audioservice_recv(int sk, bt_audio_msg_header_t *inmsg)
|
||||
return err;
|
||||
}
|
||||
|
||||
static int audioservice_expect(int sk, bt_audio_msg_header_t *rsp_hdr,
|
||||
int expected_type)
|
||||
static int audioservice_expect(int sk, bt_audio_msg_header_t *rsp,
|
||||
int expected_name)
|
||||
{
|
||||
int err = audioservice_recv(sk, rsp_hdr);
|
||||
if (err == 0) {
|
||||
if (rsp_hdr->msg_type != expected_type) {
|
||||
err = -EINVAL;
|
||||
SNDERR("Bogus message %s received while "
|
||||
"%s was expected",
|
||||
bt_audio_strmsg(rsp_hdr->msg_type),
|
||||
bt_audio_strmsg(expected_type));
|
||||
}
|
||||
bt_audio_error_t *error;
|
||||
int err = audioservice_recv(sk, rsp);
|
||||
|
||||
if (err != 0)
|
||||
return err;
|
||||
|
||||
if (rsp->name != expected_name) {
|
||||
err = -EINVAL;
|
||||
SNDERR("Bogus message %s received while %s was expected",
|
||||
bt_audio_strname(rsp->name),
|
||||
bt_audio_strname(expected_name));
|
||||
}
|
||||
|
||||
if (rsp->type == BT_ERROR) {
|
||||
error = (void *) rsp;
|
||||
SNDERR("%s failed : %s(%d)",
|
||||
bt_audio_strname(rsp->name),
|
||||
strerror(error->posix_errno),
|
||||
error->posix_errno);
|
||||
return -error->posix_errno;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int bluetooth_parse_capabilities(struct bluetooth_data *data,
|
||||
struct bt_get_capabilities_rsp *rsp)
|
||||
{
|
||||
int bytes_left = rsp->h.length - sizeof(*rsp);
|
||||
codec_capabilities_t *codec = (void *) rsp->data;
|
||||
|
||||
data->transport = codec->transport;
|
||||
|
||||
if (codec->transport != BT_CAPABILITIES_TRANSPORT_A2DP)
|
||||
return 0;
|
||||
|
||||
while (bytes_left > 0) {
|
||||
if (codec->type == BT_A2DP_CODEC_SBC)
|
||||
break;
|
||||
|
||||
bytes_left -= codec->length;
|
||||
codec = (void *) codec + codec->length;
|
||||
}
|
||||
|
||||
if (bytes_left <= 0 ||
|
||||
codec->length != sizeof(data->a2dp.sbc_capabilities))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(&data->a2dp.sbc_capabilities, codec, codec->length);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bluetooth_init(struct bluetooth_data *data, snd_pcm_stream_t stream,
|
||||
snd_config_t *conf)
|
||||
{
|
||||
int sk, err;
|
||||
struct bluetooth_alsa_config *alsa_conf = &data->alsa_config;
|
||||
char buf[BT_AUDIO_IPC_PACKET_SIZE];
|
||||
bt_audio_rsp_msg_header_t *rsp_hdr = (void*) buf;
|
||||
struct bt_getcapabilities_req *getcaps_req = (void*) buf;
|
||||
struct bt_getcapabilities_rsp *getcaps_rsp = (void*) buf;
|
||||
char buf[BT_SUGGESTED_BUFFER_SIZE];
|
||||
bt_audio_msg_header_t *rsp = (void*) buf;
|
||||
struct bt_get_capabilities_req *getcaps_req = (void*) buf;
|
||||
struct bt_get_capabilities_rsp *getcaps_rsp = (void*) buf;
|
||||
|
||||
memset(data, 0, sizeof(struct bluetooth_data));
|
||||
|
||||
@ -1594,8 +1625,11 @@ static int bluetooth_init(struct bluetooth_data *data, snd_pcm_stream_t stream,
|
||||
goto failed;
|
||||
}
|
||||
|
||||
memset(getcaps_req, 0, BT_AUDIO_IPC_PACKET_SIZE);
|
||||
getcaps_req->h.msg_type = BT_GETCAPABILITIES_REQ;
|
||||
memset(getcaps_req, 0, BT_SUGGESTED_BUFFER_SIZE);
|
||||
getcaps_req->h.type = BT_REQUEST;
|
||||
getcaps_req->h.name = BT_GET_CAPABILITIES;
|
||||
getcaps_req->h.length = sizeof(*getcaps_req);
|
||||
|
||||
getcaps_req->flags = 0;
|
||||
if (alsa_conf->autoconnect)
|
||||
getcaps_req->flags |= BT_FLAG_AUTOCONNECT;
|
||||
@ -1609,21 +1643,11 @@ static int bluetooth_init(struct bluetooth_data *data, snd_pcm_stream_t stream,
|
||||
if (err < 0)
|
||||
goto failed;
|
||||
|
||||
err = audioservice_expect(data->server.fd, &rsp_hdr->msg_h, BT_GETCAPABILITIES_RSP);
|
||||
err = audioservice_expect(data->server.fd, rsp, BT_GET_CAPABILITIES);
|
||||
if (err < 0)
|
||||
goto failed;
|
||||
|
||||
if (rsp_hdr->posix_errno != 0) {
|
||||
SNDERR("BT_GETCAPABILITIES failed : %s(%d)",
|
||||
strerror(rsp_hdr->posix_errno),
|
||||
rsp_hdr->posix_errno);
|
||||
return -rsp_hdr->posix_errno;
|
||||
}
|
||||
|
||||
data->transport = getcaps_rsp->transport;
|
||||
|
||||
if (getcaps_rsp->transport == BT_CAPABILITIES_TRANSPORT_A2DP)
|
||||
data->a2dp.sbc_capabilities = getcaps_rsp->sbc_capabilities;
|
||||
bluetooth_parse_capabilities(data, getcaps_rsp);
|
||||
|
||||
return 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user