Merge commit 'elmarco/bluetooth-fixes'

This commit is contained in:
Lennart Poettering 2009-03-19 17:46:13 +01:00
commit 4a983124e1
3 changed files with 21 additions and 13 deletions

View file

@ -114,15 +114,14 @@ void pa_bluetooth_device_free(pa_bluetooth_device *d) {
static pa_bool_t device_is_loaded(pa_bluetooth_device *d) { static pa_bool_t device_is_loaded(pa_bluetooth_device *d) {
pa_assert(d); pa_assert(d);
return d->device_info_valid && d->audio_sink_info_valid && d->headset_info_valid; return d->device_info_valid && (d->audio_sink_info_valid || d->headset_info_valid);
} }
static pa_bool_t device_is_audio(pa_bluetooth_device *d) { static pa_bool_t device_is_audio(pa_bluetooth_device *d) {
pa_assert(d); pa_assert(d);
pa_assert(d->device_info_valid); pa_assert(d->device_info_valid);
pa_assert(d->audio_sink_info_valid); pa_assert(d->audio_sink_info_valid || d->headset_info_valid);
pa_assert(d->headset_info_valid);
return d->device_info_valid > 0 && return d->device_info_valid > 0 &&
(d->audio_sink_info_valid > 0 || d->headset_info_valid > 0); (d->audio_sink_info_valid > 0 || d->headset_info_valid > 0);
@ -653,10 +652,12 @@ static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *us
} else if (dbus_message_has_interface(m, "org.bluez.Headset")) { } else if (dbus_message_has_interface(m, "org.bluez.Headset")) {
if (parse_audio_property(y, &d->headset_connected, &arg_i) < 0) if (parse_audio_property(y, &d->headset_connected, &arg_i) < 0)
goto fail; goto fail;
d->headset_info_valid = 1;
} else if (dbus_message_has_interface(m, "org.bluez.AudioSink")) { } else if (dbus_message_has_interface(m, "org.bluez.AudioSink")) {
if (parse_audio_property(y, &d->audio_sink_connected, &arg_i) < 0) if (parse_audio_property(y, &d->audio_sink_connected, &arg_i) < 0)
goto fail; goto fail;
d->audio_sink_info_valid = 1;
} }
pa_assert_se(y->mode == MODE_DISCOVER); pa_assert_se(y->mode == MODE_DISCOVER);

View file

@ -161,6 +161,8 @@ struct userdata {
int service_write_type, service_read_type; int service_write_type, service_read_type;
}; };
#define USE_SCO_OVER_PCM(u) (u->profile == PROFILE_HSP && (u->hsp.sco_sink && u->hsp.sco_source))
static int init_bt(struct userdata *u); static int init_bt(struct userdata *u);
static int init_profile(struct userdata *u); static int init_profile(struct userdata *u);
@ -654,7 +656,7 @@ static int set_conf(struct userdata *u) {
return 0; return 0;
} }
/* from IO thread */ /* from IO thread, except in SCO over PCM */
static int start_stream_fd(struct userdata *u) { static int start_stream_fd(struct userdata *u) {
union { union {
bt_audio_msg_header_t rsp; bt_audio_msg_header_t rsp;
@ -1358,8 +1360,6 @@ static char *get_name(const char *type, pa_modargs *ma, const char *device_id, p
return pa_sprintf_malloc("bluez_%s.%s", type, n); return pa_sprintf_malloc("bluez_%s.%s", type, n);
} }
#define USE_SCO_OVER_PCM(u) (u->profile == PROFILE_HSP && (u->hsp.sco_sink && u->hsp.sco_source))
static void sco_over_pcm_state_update(struct userdata *u) { static void sco_over_pcm_state_update(struct userdata *u) {
pa_assert(u); pa_assert(u);
pa_assert(USE_SCO_OVER_PCM(u)); pa_assert(USE_SCO_OVER_PCM(u));
@ -1374,11 +1374,14 @@ static void sco_over_pcm_state_update(struct userdata *u) {
if ((init_bt(u) < 0) || (init_profile(u) < 0)) if ((init_bt(u) < 0) || (init_profile(u) < 0))
pa_log("Can't resume SCO over PCM"); pa_log("Can't resume SCO over PCM");
start_stream_fd(u);
} else { } else {
if (u->service_fd < 0) if (u->service_fd < 0)
return; return;
stop_stream_fd(u);
pa_log_debug("Closing SCO over PCM"); pa_log_debug("Closing SCO over PCM");
pa_close(u->service_fd); pa_close(u->service_fd);
u->service_fd = -1; u->service_fd = -1;
@ -1628,15 +1631,19 @@ static int start_thread(struct userdata *u) {
pa_assert(!u->rtpoll); pa_assert(!u->rtpoll);
pa_assert(!u->rtpoll_item); pa_assert(!u->rtpoll_item);
if (USE_SCO_OVER_PCM(u)) {
pa_sink_ref(u->sink);
pa_source_ref(u->source);
return 0;
}
u->rtpoll = pa_rtpoll_new(); u->rtpoll = pa_rtpoll_new();
pa_thread_mq_init(&u->thread_mq, u->core->mainloop, u->rtpoll); pa_thread_mq_init(&u->thread_mq, u->core->mainloop, u->rtpoll);
if (USE_SCO_OVER_PCM(u)) {
if (start_stream_fd(u) < 0)
return -1;
pa_sink_ref(u->sink);
pa_source_ref(u->source);
/* FIXME: monitor stream_fd error */
return 0;
}
if (!(u->thread = pa_thread_new(thread_func, u))) { if (!(u->thread = pa_thread_new(thread_func, u))) {
pa_log_error("Failed to create IO thread"); pa_log_error("Failed to create IO thread");
stop_thread(u); stop_thread(u);

View file

@ -75,7 +75,7 @@ static void load_module_for_device(struct userdata *u, pa_bluetooth_device *d, p
/* Oh, awesome, a new device has shown up and been connected! */ /* Oh, awesome, a new device has shown up and been connected! */
args = pa_sprintf_malloc("address=\"%s\" path=\"%s\"", d->address, d->path); args = pa_sprintf_malloc("address=\"%s\" path=\"%s\" profile=\"%s\"", d->address, d->path, d->headset_connected ? "hsp" : "a2dp");
if (pa_modargs_get_value(u->modargs, "sco_sink", NULL) && if (pa_modargs_get_value(u->modargs, "sco_sink", NULL) &&
pa_modargs_get_value(u->modargs, "sco_source", NULL)) { pa_modargs_get_value(u->modargs, "sco_source", NULL)) {