mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	Merge commit 'elmarco/bluetooth-fixes'
This commit is contained in:
		
						commit
						4a983124e1
					
				
					 3 changed files with 21 additions and 13 deletions
				
			
		| 
						 | 
					@ -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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue