diff options
| author | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2007-06-06 17:58:19 +0000 | 
|---|---|---|
| committer | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2007-06-06 17:58:19 +0000 | 
| commit | f1a8e719f5687bb32f2f5ed59f26a3203ad43efb (patch) | |
| tree | 8771c939ccaa33d02a98ef2689217a1fad5a20d9 | |
| parent | e47ffdb86e691d7418c0e5a2bebbdd7c512aa50f (diff) | |
Some fixes for audio code prototype.
| -rw-r--r-- | audio/headset.c | 17 | ||||
| -rw-r--r-- | audio/headset.h | 4 | ||||
| -rw-r--r-- | audio/manager.c | 11 | ||||
| -rw-r--r-- | audio/manager.h | 1 | ||||
| -rw-r--r-- | audio/pcm_bluetooth.c | 98 | ||||
| -rw-r--r-- | audio/unix.c | 45 | 
6 files changed, 106 insertions, 70 deletions
| diff --git a/audio/headset.c b/audio/headset.c index 2fb139ad..109e7c5d 100644 --- a/audio/headset.c +++ b/audio/headset.c @@ -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; +} diff --git a/audio/headset.h b/audio/headset.h index 0325e755..6780e7a9 100644 --- a/audio/headset.h +++ b/audio/headset.h @@ -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_ */ diff --git a/audio/manager.c b/audio/manager.c index 1b727f7a..df0f550f 100644 --- a/audio/manager.c +++ b/audio/manager.c @@ -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); +} diff --git a/audio/manager.h b/audio/manager.h index 45d93d7f..1927a110 100644 --- a/audio/manager.h +++ b/audio/manager.h @@ -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); diff --git a/audio/pcm_bluetooth.c b/audio/pcm_bluetooth.c index 29583940..c8988edc 100644 --- a/audio/pcm_bluetooth.c +++ b/audio/pcm_bluetooth.c @@ -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); - -	if (data->cfg.fd == -1) { -		SNDERR("Error while configuring device: could not acquire audio socket"); -		return -EINVAL; -	} +	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; +	} + +	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;  } diff --git a/audio/unix.c b/audio/unix.c index 8cd1affc..f2bf2271 100644 --- a/audio/unix.c +++ b/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; - -		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_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); +		info("Package PKT_TYPE_CFG_REQ:%u", pkt->role); + +		cfg = (struct ipc_data_cfg *) pkt->data; + +		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;  } | 
