示例#1
0
static void a2dp_timer(snd_async_handler_t *async)
{
	snd_timer_t *handle = snd_async_handler_get_timer(async);
	snd_timer_read_t tr;
	int i, ticks = 0;

	while (snd_timer_read(handle, &tr, sizeof(tr)) == sizeof(tr))
		ticks += tr.ticks;

	a2dp_lock();

	for (i = 0; i < MAX_CONNECTIONS; i++) {
		snd_pcm_a2dp_t *a2dp = connections[i];

		if (a2dp && a2dp->refcnt <= 0) {
			a2dp->timeout = ((a2dp->timeout * 1000) - ticks) / 1000;
			if (a2dp->timeout <= 0) {
				connections[i] = NULL;
				a2dp_free(a2dp);
			}
		}
	}

	a2dp_unlock();
}
示例#2
0
static int a2dp_close(snd_pcm_ioplug_t * io)
{
	snd_pcm_a2dp_t *a2dp = io->private_data;
	a2dp_disconnect(a2dp);
	a2dp_free(a2dp);
	return 0;
}
示例#3
0
static void a2dp_exit(void)
{
	int err, i;

	err = snd_timer_stop(timer);

	err = snd_timer_close(timer);

	a2dp_lock();

	for (i = 0; i < MAX_CONNECTIONS; i++) {
		snd_pcm_a2dp_t *a2dp = connections[i];

		if (a2dp) {
			connections[i] = NULL;
			a2dp_free(a2dp);
		}
	}

	a2dp_unlock();

}
示例#4
0
int a2dp_init(int rate, int channels, a2dpData* dataPtr)
{
	struct bluetooth_data* data;
	pthread_attr_t attr;
	int err;

	DBG("a2dp_init rate: %d channels: %d", rate, channels);
	*dataPtr = NULL;
	data = malloc(sizeof(struct bluetooth_data));
	if (!data)
		return -1;

	memset(data, 0, sizeof(struct bluetooth_data));
	data->server.fd = -1;
	data->stream.fd = -1;
	data->state = A2DP_STATE_NONE;
	data->command = A2DP_CMD_NONE;

	strncpy(data->address, "00:00:00:00:00:00", 18);
	data->rate = rate;
	data->channels = channels;

	sbc_init(&data->sbc, 0);

	pthread_mutex_init(&data->mutex, NULL);
	pthread_cond_init(&data->thread_start, NULL);
	pthread_cond_init(&data->thread_wait, NULL);
	pthread_cond_init(&data->client_wait, NULL);

	pthread_mutex_lock(&data->mutex);
	data->started = 0;

	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

	err = pthread_create(&data->thread, &attr, a2dp_thread, data);
	if (err) {
		/* If the thread create fails we must not wait */
		pthread_mutex_unlock(&data->mutex);
		err = -err;
		goto error;
	}

	/* Make sure the state machine is ready and waiting */
	while (!data->started) {
		pthread_cond_wait(&data->thread_start, &data->mutex);
	}

	/* Poke the state machine to get it going */
	pthread_cond_signal(&data->thread_wait);

	pthread_mutex_unlock(&data->mutex);
	pthread_attr_destroy(&attr);

	*dataPtr = data;
	return 0;
error:
	bluetooth_close(data);
	sbc_finish(&data->sbc);
	pthread_attr_destroy(&attr);
	a2dp_free(data);

	return err;
}
示例#5
0
static void* a2dp_thread(void *d)
{
	struct bluetooth_data* data = (struct bluetooth_data*)d;
	a2dp_command_t command = A2DP_CMD_NONE;
	int err = 0;

	DBG("a2dp_thread started");
	prctl(PR_SET_NAME, (int)"a2dp_thread", 0, 0, 0);

	pthread_mutex_lock(&data->mutex);

	data->started = 1;
	pthread_cond_signal(&data->thread_start);

	while (1)
	{
		while (1) {
			pthread_cond_wait(&data->thread_wait, &data->mutex);

			/* Initialization needed */
			if (data->state == A2DP_STATE_NONE &&
				data->command != A2DP_CMD_QUIT) {
				err = bluetooth_init(data);
			}

			/* New state command signaled */
			if (command != data->command) {
				command = data->command;
				break;
			}
		}

		switch (command) {
			case A2DP_CMD_CONFIGURE:
				if (data->state != A2DP_STATE_INITIALIZED)
					break;
				err = bluetooth_configure(data);
				break;

			case A2DP_CMD_START:
				if (data->state != A2DP_STATE_CONFIGURED)
					break;
				err = bluetooth_start(data);
				break;

			case A2DP_CMD_STOP:
				if (data->state != A2DP_STATE_STARTED)
					break;
				err = bluetooth_stop(data);
				break;

			case A2DP_CMD_QUIT:
				bluetooth_close(data);
				sbc_finish(&data->sbc);
				a2dp_free(data);
				goto done;

			case A2DP_CMD_INIT:
				/* already called bluetooth_init() */
			default:
				break;
		}
		// reset last command in case of error to allow
		// re-execution of the same command
		if (err < 0) {
			command = A2DP_CMD_NONE;
		}
	}

done:
	pthread_mutex_unlock(&data->mutex);
	DBG("a2dp_thread finished");
	return NULL;
}