summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2007-12-06 14:42:41 +0000
committerLuiz Augusto von Dentz <luiz.dentz@openbossa.org>2007-12-06 14:42:41 +0000
commit721d249e314b0591274436594be56805bf5a2822 (patch)
treeafbb5fd8c08e55068a28df8ac9caaacb12070421
parent79e5dd0c9e917822d0a97a1f803fc7571b253643 (diff)
Fixes for hsp.
-rw-r--r--audio/pcm_bluetooth.c59
-rw-r--r--audio/unix.c123
2 files changed, 121 insertions, 61 deletions
diff --git a/audio/pcm_bluetooth.c b/audio/pcm_bluetooth.c
index 6f67ca57..b0e3838b 100644
--- a/audio/pcm_bluetooth.c
+++ b/audio/pcm_bluetooth.c
@@ -422,6 +422,49 @@ static int bluetooth_prepare(snd_pcm_ioplug_t *io)
return write(data->pipefd[1], &c, 1);
}
+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;
+ 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;
+ strncpy(setconf_req->device, data->alsa_config.device, 18);
+ setconf_req->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);
+
+ err = audioservice_send(data->server.fd, &setconf_req->h);
+ if (err < 0)
+ return err;
+
+ err = audioservice_expect(data->server.fd, &rsp_hdr->msg_h,
+ BT_SETCONFIGURATION_RSP);
+ 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;
+
+ return 0;
+}
+
static uint8_t default_bitpool(uint8_t freq, uint8_t mode)
{
switch (freq) {
@@ -565,6 +608,8 @@ static int bluetooth_a2dp_hw_params(snd_pcm_ioplug_t *io,
memset(setconf_req, 0, BT_AUDIO_IPC_PACKET_SIZE);
setconf_req->h.msg_type = BT_SETCONFIGURATION_REQ;
+ strncpy(setconf_req->device, data->alsa_config.device, 18);
+ setconf_req->transport = BT_CAPABILITIES_TRANSPORT_A2DP;
setconf_req->sbc_capabilities = active_capabilities;
setconf_req->access_mode = (io->stream == SND_PCM_STREAM_PLAYBACK ?
BT_CAPABILITIES_ACCESS_MODE_WRITE :
@@ -762,7 +807,7 @@ static snd_pcm_sframes_t bluetooth_hsp_read(snd_pcm_ioplug_t *io,
/* Increment hardware transmition pointer */
data->hw_ptr = (data->hw_ptr + data->link_mtu / frame_size) %
- io->buffer_size;
+ io->buffer_size;
proceed:
buff = (unsigned char *) areas->addr +
@@ -1020,6 +1065,7 @@ static snd_pcm_ioplug_callback_t bluetooth_hsp_playback = {
.stop = bluetooth_playback_stop,
.pointer = bluetooth_pointer,
.close = bluetooth_close,
+ .hw_params = bluetooth_hsp_hw_params,
.prepare = bluetooth_prepare,
.transfer = bluetooth_hsp_write,
.poll_descriptors = bluetooth_playback_poll_descriptors,
@@ -1032,6 +1078,7 @@ static snd_pcm_ioplug_callback_t bluetooth_hsp_capture = {
.stop = bluetooth_stop,
.pointer = bluetooth_pointer,
.close = bluetooth_close,
+ .hw_params = bluetooth_hsp_hw_params,
.prepare = bluetooth_prepare,
.transfer = bluetooth_hsp_read,
.poll_descriptors = bluetooth_poll_descriptors,
@@ -1467,11 +1514,7 @@ static int bluetooth_init(struct bluetooth_data *data, snd_pcm_stream_t stream,
getcaps_req->transport = alsa_conf->transport;
else
getcaps_req->transport = BT_CAPABILITIES_TRANSPORT_ANY;
-/*
- getcaps_req->access_mode = (stream == SND_PCM_STREAM_PLAYBACK ?
- BT_CAPABILITIES_ACCESS_MODE_WRITE :
- BT_CAPABILITIES_ACCESS_MODE_READ);
-*/
+
err = audioservice_send(data->server.fd, &getcaps_req->h);
if (err < 0)
goto failed;
@@ -1488,9 +1531,7 @@ static int bluetooth_init(struct bluetooth_data *data, snd_pcm_stream_t stream,
}
data->transport = getcaps_rsp->transport;
-/*
- data->link_mtu = getcaps_rsp->link_mtu;
-*/
+
if (getcaps_rsp->transport == BT_CAPABILITIES_TRANSPORT_A2DP)
data->a2dp.sbc_capabilities = getcaps_rsp->sbc_capabilities;
diff --git a/audio/unix.c b/audio/unix.c
index 8267e895..442dca79 100644
--- a/audio/unix.c
+++ b/audio/unix.c
@@ -216,55 +216,34 @@ static void stream_state_changed(struct avdtp_stream *stream,
break;
}
}
-/*
+
static void headset_discovery_complete(struct device *dev, void *user_data)
{
struct unix_client *client = user_data;
char buf[BT_AUDIO_IPC_PACKET_SIZE];
struct bt_getcapabilities_rsp *rsp = (void *) buf;
- struct headset_data *hs = &client->d.hs;
client->req_id = 0;
- if (!dev) {
- unix_ipc_error(client, BT_GETCAPABILITIES_RSP, EIO);
- client->dev = NULL;
- return;
- }
-
- switch (client->access_mode) {
- case BT_CAPABILITIES_ACCESS_MODE_READ:
- hs->lock = HEADSET_LOCK_READ;
- break;
- case BT_CAPABILITIES_ACCESS_MODE_WRITE:
- hs->lock = HEADSET_LOCK_WRITE;
- break;
- case BT_CAPABILITIES_ACCESS_MODE_READWRITE:
- hs->lock = HEADSET_LOCK_READ | HEADSET_LOCK_WRITE;
- break;
- default:
- hs->lock = 0;
- break;
- }
-
- if (!headset_lock(dev, hs->lock)) {
- error("Unable to lock headset");
- unix_ipc_error(client, BT_GETCAPABILITIES_RSP, EIO);
- client->dev = NULL;
- return;
- }
+ if (!dev)
+ goto failed;
memset(buf, 0, sizeof(buf));
- rsp->h.msg_type = BT_GETCAPABILITIES_RSP;
+ rsp->rsp_h.msg_h.msg_type = BT_GETCAPABILITIES_RSP;
rsp->transport = BT_CAPABILITIES_TRANSPORT_SCO;
rsp->sampling_rate = 8000;
- client->data_fd = headset_get_sco_fd(dev);
+ unix_ipc_sendmsg(client, &rsp->rsp_h.msg_h);
- unix_ipc_sendmsg(client, &rsp->h);
+ return;
+
+failed:
+ error("discovery failed");
+ unix_ipc_error(client, BT_SETCONFIGURATION_RSP, EIO);
+ client->dev = NULL;
}
-*/
+
static void headset_setup_complete(struct device *dev, void *user_data)
{
struct unix_client *client = user_data;
@@ -274,11 +253,8 @@ static void headset_setup_complete(struct device *dev, void *user_data)
client->req_id = 0;
- if (!dev) {
- unix_ipc_error(client, BT_GETCAPABILITIES_RSP, EIO);
- client->dev = NULL;
- return;
- }
+ if (!dev)
+ goto failed;
switch (client->access_mode) {
case BT_CAPABILITIES_ACCESS_MODE_READ:
@@ -297,9 +273,7 @@ static void headset_setup_complete(struct device *dev, void *user_data)
if (!headset_lock(dev, hs->lock)) {
error("Unable to lock headset");
- unix_ipc_error(client, BT_GETCAPABILITIES_RSP, EIO);
- client->dev = NULL;
- return;
+ goto failed;
}
memset(buf, 0, sizeof(buf));
@@ -307,10 +281,55 @@ static void headset_setup_complete(struct device *dev, void *user_data)
rsp->rsp_h.msg_h.msg_type = BT_SETCONFIGURATION_RSP;
rsp->transport = BT_CAPABILITIES_TRANSPORT_SCO;
rsp->access_mode = client->access_mode;
+ rsp->link_mtu = 48;
client->data_fd = headset_get_sco_fd(dev);
unix_ipc_sendmsg(client, &rsp->rsp_h.msg_h);
+
+ return;
+
+failed:
+ error("config failed");
+ unix_ipc_error(client, BT_SETCONFIGURATION_RSP, EIO);
+ client->dev = NULL;
+}
+
+static void headset_resume_complete(struct device *dev, void *user_data)
+{
+ struct unix_client *client = user_data;
+ char buf[BT_AUDIO_IPC_PACKET_SIZE];
+ struct bt_streamstart_rsp *rsp = (void *) buf;
+ struct bt_streamfd_ind *ind = (void *) buf;
+
+ client->req_id = 0;
+
+ if (!dev)
+ goto failed;
+
+ memset(buf, 0, sizeof(buf));
+
+ rsp->rsp_h.msg_h.msg_type = BT_STREAMSTART_RSP;
+
+ unix_ipc_sendmsg(client, &rsp->rsp_h.msg_h);
+
+ memset(buf, 0, sizeof(buf));
+ ind->h.msg_type = BT_STREAMFD_IND;
+ unix_ipc_sendmsg(client, &ind->h);
+
+ client->data_fd = headset_get_sco_fd(dev);
+
+ if (unix_sendmsg_fd(client->sock, client->data_fd) < 0) {
+ error("unix_sendmsg_fd: %s(%d)", strerror(errno), errno);
+ goto failed;
+ }
+
+ return;
+
+failed:
+ error("resume failed");
+ unix_ipc_error(client, BT_STREAMSTART_RSP, EIO);
+ client->dev = NULL;
}
static void a2dp_discovery_complete(struct avdtp *session, GSList *seps,
@@ -421,7 +440,7 @@ static void a2dp_config_complete(struct avdtp *session, struct a2dp_sep *sep,
return;
failed:
- error("setup failed");
+ error("config failed");
if (a2dp->sep) {
a2dp_sep_unlock(a2dp->sep, a2dp->session);
@@ -511,7 +530,6 @@ failed:
static void start_discovery(struct device *dev, struct unix_client *client)
{
struct a2dp_data *a2dp;
- unsigned int id;
int err = 0;
client->type = select_service(dev, client->interface);
@@ -535,8 +553,7 @@ static void start_discovery(struct device *dev, struct unix_client *client)
break;
case TYPE_HEADSET:
- id = headset_request_stream(dev, headset_setup_complete, client);
- client->cancel = headset_cancel_stream;
+ headset_discovery_complete(dev, client);
break;
default:
@@ -544,6 +561,8 @@ static void start_discovery(struct device *dev, struct unix_client *client)
goto failed;
}
+ client->dev = dev;
+
return;
failed:
@@ -625,11 +644,16 @@ static void start_resume(struct device *dev, struct unix_client *client)
id = a2dp_source_resume(a2dp->session, a2dp->sep,
a2dp_resume_complete, client);
client->cancel = a2dp_source_cancel;
+
+ if (id == 0) {
+ error("resume failed");
+ goto failed;
+ }
+
break;
case TYPE_HEADSET:
- id = headset_request_stream(dev, headset_setup_complete, client);
- client->cancel = headset_cancel_stream;
+ headset_resume_complete(dev, client);
break;
default:
@@ -637,11 +661,6 @@ static void start_resume(struct device *dev, struct unix_client *client)
goto failed;
}
- if (id == 0) {
- error("resume failed");
- goto failed;
- }
-
return;
failed: