mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-11-17 17:24:32 +08:00
Some fixes for audio code prototype.
This commit is contained in:
parent
e47ffdb86e
commit
f1a8e719f5
@ -1817,3 +1817,20 @@ void headset_exit(void)
|
||||
dbus_connection_unref(connection);
|
||||
connection = NULL;
|
||||
}
|
||||
|
||||
int headset_get_config(headset_t *headset, struct ipc_data_cfg *cfg)
|
||||
{
|
||||
if (headset->sco == NULL)
|
||||
return -1;
|
||||
|
||||
cfg->fd = g_io_channel_unix_get_fd(headset->sco);
|
||||
cfg->fd_opt = CFG_FD_OPT_READWRITE;
|
||||
cfg->encoding = 0;
|
||||
cfg->bitpool = 0;
|
||||
cfg->channels = 1;
|
||||
cfg->pkt_len = 48;
|
||||
cfg->sample_size = 2;
|
||||
cfg->rate = 8000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -29,6 +29,8 @@
|
||||
|
||||
#include <dbus/dbus.h>
|
||||
|
||||
#include "ipc.h"
|
||||
|
||||
#define AUDIO_HEADSET_INTERFACE "org.bluez.audio.Headset"
|
||||
|
||||
typedef struct headset headset_t;
|
||||
@ -47,4 +49,6 @@ int headset_server_init(DBusConnection *conn, gboolean disable_hfp,
|
||||
|
||||
void headset_exit(void);
|
||||
|
||||
int headset_get_config(headset_t *headset, struct ipc_data_cfg *cfg);
|
||||
|
||||
#endif /* __AUDIO_HEADSET_H_ */
|
||||
|
@ -1286,3 +1286,14 @@ void audio_exit(void)
|
||||
|
||||
connection = NULL;
|
||||
}
|
||||
|
||||
int manager_get_device(uint8_t role, struct ipc_data_cfg *cfg)
|
||||
{
|
||||
if (default_hs == NULL || default_hs->headset == NULL)
|
||||
return -1;
|
||||
|
||||
if (!headset_is_connected(default_hs->headset))
|
||||
return -1;
|
||||
|
||||
return headset_get_config(default_hs->headset, cfg);
|
||||
}
|
||||
|
@ -94,3 +94,4 @@ DBusHandlerResult err_does_not_exist(DBusConnection *conn, DBusMessage *msg);
|
||||
DBusHandlerResult err_failed(DBusConnection *conn, DBusMessage *msg,
|
||||
const char *dsc);
|
||||
|
||||
int manager_get_device(uint8_t role, struct ipc_data_cfg *cfg);
|
||||
|
@ -115,7 +115,7 @@ static int bluetooth_hw_params(snd_pcm_ioplug_t *io, snd_pcm_hw_params_t *params
|
||||
struct ipc_data_cfg cfg = data->cfg;
|
||||
uint32_t period_count = io->buffer_size / io->period_size;
|
||||
|
||||
DBG("period_count = %d", period_count);
|
||||
DBG("fd = %d, period_count = %d", cfg.fd, period_count);
|
||||
|
||||
if(setsockopt(cfg.fd, SOL_SCO,
|
||||
io->stream == SND_PCM_STREAM_PLAYBACK ? SCO_TXBUFS : SCO_RXBUFS,
|
||||
@ -315,56 +315,59 @@ static int bluetooth_hw_constraint(snd_pcm_ioplug_t *io)
|
||||
|
||||
static int bluetooth_cfg(struct bluetooth_data *data)
|
||||
{
|
||||
struct ipc_packet pkt;
|
||||
int res;
|
||||
int len = sizeof(struct ipc_packet) + sizeof(struct ipc_data_cfg);
|
||||
struct ipc_packet *pkt;
|
||||
|
||||
DBG("Sending PKT_TYPE_CFG_REQ...");
|
||||
pkt.type = PKT_TYPE_CFG_REQ;
|
||||
pkt.role = PKT_ROLE_NONE;
|
||||
res = send(data->sock, &pkt, sizeof(struct ipc_packet), 0);
|
||||
pkt = malloc(len);
|
||||
memset(pkt, 0, len);
|
||||
pkt->type = PKT_TYPE_CFG_REQ;
|
||||
pkt->role = PKT_ROLE_NONE;
|
||||
pkt->error = PKT_ERROR_NONE;
|
||||
res = send(data->sock, pkt, len, 0);
|
||||
if (res < 0)
|
||||
return errno;
|
||||
DBG("OK - %d bytes sent", res);
|
||||
|
||||
DBG("Waiting for response...");
|
||||
do {
|
||||
int len = sizeof(struct ipc_packet) + sizeof(struct ipc_data_cfg);
|
||||
struct ipc_packet *pkt_ptr;
|
||||
|
||||
pkt_ptr = malloc(sizeof(struct ipc_packet) + sizeof(struct ipc_data_cfg));
|
||||
res = recv(data->sock, pkt_ptr, len, MSG_WAITALL | (data->io.nonblock ? MSG_DONTWAIT : 0 ));
|
||||
} while ((res < 0) && (errno == EINTR));
|
||||
memset(pkt, 0, len);
|
||||
res = recv(data->sock, pkt, len, 0);
|
||||
|
||||
if (res < 0)
|
||||
return -errno;
|
||||
DBG("OK - %d bytes received", res);
|
||||
|
||||
if (pkt.type != PKT_TYPE_CFG_RSP) {
|
||||
SNDERR("Unexpected packet type received: type = %d", pkt.type);
|
||||
if (pkt->type != PKT_TYPE_CFG_RSP) {
|
||||
SNDERR("Unexpected packet type received: type = %d", pkt->type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (pkt.error != PKT_ERROR_NONE) {
|
||||
SNDERR("Error while configuring device: error = %d", pkt.error);
|
||||
return pkt.error;
|
||||
if (pkt->error != PKT_ERROR_NONE) {
|
||||
SNDERR("Error while configuring device: error = %d", pkt->error);
|
||||
return pkt->error;
|
||||
}
|
||||
|
||||
if (pkt.length != sizeof(struct ipc_data_cfg)) {
|
||||
if (pkt->length != sizeof(struct ipc_data_cfg)) {
|
||||
SNDERR("Error while configuring device: packet size doesn't match");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memcpy(&data->cfg, &pkt.data, pkt.length);
|
||||
memcpy(&data->cfg, pkt->data, sizeof(struct ipc_data_cfg));
|
||||
|
||||
DBG("Device configuration:");
|
||||
|
||||
DBG("fd=%d, fd_opt=%u, channels=%u, pkt_len=%u, sample_size=%u, rate=%u",
|
||||
data->cfg.fd, data->cfg.fd_opt, data->cfg.channels,
|
||||
data->cfg.pkt_len, data->cfg.sample_size, data->cfg.rate);
|
||||
|
||||
if (data->cfg.fd == -1) {
|
||||
SNDERR("Error while configuring device: could not acquire audio socket");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DBG("Device configuration:");
|
||||
DBG("fd=%d, fd_opt=%u, channels=%u, pkt_len=%u, sample_size=%u, rate=%u",
|
||||
data->cfg.fd, data->cfg.fd_opt, data->cfg.channels,
|
||||
data->cfg.pkt_len, data->cfg.sample_size, data->cfg.rate);
|
||||
|
||||
free(pkt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -373,6 +376,9 @@ static int bluetooth_init(struct bluetooth_data *data)
|
||||
int sk, err, id;
|
||||
struct sockaddr_un addr;
|
||||
|
||||
if (!data)
|
||||
return -EINVAL;
|
||||
|
||||
id = abs(getpid() * rand());
|
||||
|
||||
sk = socket(PF_LOCAL, SOCK_DGRAM, 0);
|
||||
@ -404,18 +410,12 @@ static int bluetooth_init(struct bluetooth_data *data)
|
||||
return -errno;
|
||||
}
|
||||
|
||||
data = malloc(sizeof(*data));
|
||||
if (!data) {
|
||||
close(sk);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(data, 0, sizeof(*data));
|
||||
|
||||
data->sock = sk;
|
||||
|
||||
if ((err = bluetooth_cfg(data)) < 0)
|
||||
if ((err = bluetooth_cfg(data)) < 0) {
|
||||
free(data);
|
||||
return err;
|
||||
}
|
||||
|
||||
data->buffer = malloc(data->cfg.pkt_len);
|
||||
|
||||
@ -427,7 +427,7 @@ static int bluetooth_init(struct bluetooth_data *data)
|
||||
SND_PCM_PLUGIN_DEFINE_FUNC(bluetooth)
|
||||
{
|
||||
// snd_config_iterator_t iter, next;
|
||||
struct bluetooth_data data;
|
||||
struct bluetooth_data *data;
|
||||
int err;
|
||||
|
||||
DBG("Bluetooth PCM plugin blablabla (%s)",
|
||||
@ -437,39 +437,41 @@ SND_PCM_PLUGIN_DEFINE_FUNC(bluetooth)
|
||||
// }
|
||||
|
||||
DBG("Initing Bluetooth...");
|
||||
err = bluetooth_init(&data);
|
||||
data = malloc(sizeof(struct bluetooth_data));
|
||||
memset(data, 0, sizeof(struct bluetooth_data));
|
||||
err = bluetooth_init(data);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
DBG("Done");
|
||||
|
||||
data.io.version = SND_PCM_IOPLUG_VERSION;
|
||||
data.io.name = "Bluetooth Audio Device";
|
||||
data.io.mmap_rw = 0; /* No direct mmap communication */
|
||||
data->io.version = SND_PCM_IOPLUG_VERSION;
|
||||
data->io.name = "Bluetooth Audio Device";
|
||||
data->io.mmap_rw = 0; /* No direct mmap communication */
|
||||
|
||||
data.io.callback = stream == SND_PCM_STREAM_PLAYBACK ?
|
||||
data->io.callback = stream == SND_PCM_STREAM_PLAYBACK ?
|
||||
&bluetooth_playback_callback : &bluetooth_capture_callback;
|
||||
data.io.poll_fd = data.cfg.fd;
|
||||
data.io.poll_events = POLLIN;
|
||||
data.io.private_data = &data;
|
||||
data->io.poll_fd = data->cfg.fd;
|
||||
data->io.poll_events = stream == SND_PCM_STREAM_PLAYBACK ?
|
||||
POLLOUT : POLLIN;
|
||||
data->io.private_data = data;
|
||||
|
||||
err = snd_pcm_ioplug_create(&data.io, name, stream, mode);
|
||||
err = snd_pcm_ioplug_create(&data->io, name, stream, mode);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
err = bluetooth_hw_constraint(&data.io);
|
||||
err = bluetooth_hw_constraint(&data->io);
|
||||
if (err < 0) {
|
||||
snd_pcm_ioplug_delete(&data.io);
|
||||
snd_pcm_ioplug_delete(&data->io);
|
||||
goto error;
|
||||
}
|
||||
|
||||
*pcmp = data.io.pcm;
|
||||
*pcmp = data->io.pcm;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
close(data.sock);
|
||||
|
||||
free(&data);
|
||||
close(data->sock);
|
||||
free(data);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
41
audio/unix.c
41
audio/unix.c
@ -39,8 +39,8 @@
|
||||
#include "logging.h"
|
||||
#include "dbus.h"
|
||||
|
||||
#include "ipc.h"
|
||||
#include "unix.h"
|
||||
#include "manager.h"
|
||||
|
||||
static int unix_sock = -1;
|
||||
|
||||
@ -48,8 +48,8 @@ static gboolean unix_event(GIOChannel *chan, GIOCondition cond, gpointer data)
|
||||
{
|
||||
struct sockaddr_un addr;
|
||||
socklen_t addrlen;
|
||||
struct ipc_packet pkt;
|
||||
struct ipc_data_cfg cfg;
|
||||
struct ipc_packet *pkt;
|
||||
struct ipc_data_cfg *cfg;
|
||||
int sk, len;
|
||||
|
||||
debug("chan %p cond %td data %p", chan, cond, data);
|
||||
@ -67,29 +67,28 @@ static gboolean unix_event(GIOChannel *chan, GIOCondition cond, gpointer data)
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addrlen = sizeof(addr);
|
||||
|
||||
len = recvfrom(sk, &pkt, sizeof(pkt), 0, (struct sockaddr *) &addr, &addrlen);
|
||||
len = sizeof(struct ipc_packet) + sizeof(struct ipc_data_cfg);
|
||||
pkt = g_malloc0(len);
|
||||
len = recvfrom(sk, pkt, len, 0, (struct sockaddr *) &addr, &addrlen);
|
||||
|
||||
debug("path %s len %d", addr.sun_path + 1, len);
|
||||
|
||||
switch (pkt.type) {
|
||||
switch (pkt->type) {
|
||||
case PKT_TYPE_CFG_REQ:
|
||||
info("Package PKT_TYPE_CFG_REQ:%u", pkt.role);
|
||||
struct ipc_data_cfg *cfg_ptr;
|
||||
info("Package PKT_TYPE_CFG_REQ:%u", pkt->role);
|
||||
|
||||
cfg.fd = -1;
|
||||
cfg.fd_opt = CFG_FD_OPT_READWRITE;
|
||||
cfg.encoding = 0;
|
||||
cfg.bitpool = 0;
|
||||
cfg.channels = 1;
|
||||
cfg.pkt_len = 48;
|
||||
cfg.sample_size = 2;
|
||||
cfg.rate = 8000;
|
||||
cfg = (struct ipc_data_cfg *) pkt->data;
|
||||
|
||||
cfg_ptr = (struct ipc_data_cfg *) &pkt.data;
|
||||
pkt.type = PKT_TYPE_CFG_RSP;
|
||||
cfg_ptr[0] = cfg;
|
||||
pkt.length = sizeof(struct ipc_data_cfg);
|
||||
len = send(sk, &pkt, sizeof(struct ipc_packet) + sizeof(struct ipc_data_cfg), 0);
|
||||
if (manager_get_device(pkt->role, cfg) < 0)
|
||||
cfg->fd = -1;
|
||||
|
||||
pkt->type = PKT_TYPE_CFG_RSP;
|
||||
pkt->length = sizeof(struct ipc_data_cfg);
|
||||
pkt->error = PKT_ERROR_NONE;
|
||||
len = sendto(sk, pkt, len, 0, (struct sockaddr *) &addr, addrlen);
|
||||
if (len < 0)
|
||||
info("Error %s(%d)", strerror(errno), errno);
|
||||
info("%d bytes sent", len);
|
||||
break;
|
||||
case PKT_TYPE_STATUS_REQ:
|
||||
info("Package PKT_TYPE_STATUS_REQ");
|
||||
@ -98,6 +97,8 @@ static gboolean unix_event(GIOChannel *chan, GIOCondition cond, gpointer data)
|
||||
info("Package PKT_TYPE_CTL_REQ");
|
||||
break;
|
||||
}
|
||||
|
||||
g_free(pkt);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user