diff --git a/src/modules/bluetooth/backend-native.c b/src/modules/bluetooth/backend-native.c index 9994fa571..f601c0d78 100644 --- a/src/modules/bluetooth/backend-native.c +++ b/src/modules/bluetooth/backend-native.c @@ -365,6 +365,10 @@ static ssize_t sco_transport_write(pa_bluetooth_transport *t, int fd, const void pa_assert(t); + /* since SCO setup is symmetric, fix write MTU to be size of last read packet */ + if (t->last_read_size) + write_mtu = PA_MIN(t->last_read_size, write_mtu); + /* if encoder buffer has less data than required to make complete packet */ if (size < write_mtu) return 0; @@ -386,6 +390,11 @@ static ssize_t sco_transport_write(pa_bluetooth_transport *t, int fd, const void pa_log_debug("Got EAGAIN on write() after POLLOUT, probably there is a temporary connection loss."); /* Drain write buffer */ written = size; + } else if (errno == EINVAL && t->last_read_size == 0) { + /* Likely write_link_mtu is still wrong, retry after next successful read */ + pa_log_debug("got write EINVAL, next successful read should fix MTU"); + /* Drain write buffer */ + written = size; } else { pa_log_error("Failed to write data to socket: %s", pa_cstrerror(errno)); /* Report error from write call */ diff --git a/src/modules/bluetooth/backend-ofono.c b/src/modules/bluetooth/backend-ofono.c index d8c3b83e6..8a4c2c913 100644 --- a/src/modules/bluetooth/backend-ofono.c +++ b/src/modules/bluetooth/backend-ofono.c @@ -90,6 +90,10 @@ static ssize_t sco_transport_write(pa_bluetooth_transport *t, int fd, const void pa_assert(t); + /* since SCO setup is symmetric, fix write MTU to be size of last read packet */ + if (t->last_read_size) + write_mtu = PA_MIN(t->last_read_size, write_mtu); + /* if encoder buffer has less data than required to make complete packet */ if (size < write_mtu) return 0; @@ -111,6 +115,11 @@ static ssize_t sco_transport_write(pa_bluetooth_transport *t, int fd, const void pa_log_debug("Got EAGAIN on write() after POLLOUT, probably there is a temporary connection loss."); /* Drain write buffer */ written = size; + } else if (errno == EINVAL && t->last_read_size == 0) { + /* Likely write_link_mtu is still wrong, retry after next successful read */ + pa_log_debug("got write EINVAL, next successful read should fix MTU"); + /* Drain write buffer */ + written = size; } else { pa_log_error("Failed to write data to socket: %s", pa_cstrerror(errno)); /* Report error from write call */ diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h index 59e0a1cde..8eb91c1c5 100644 --- a/src/modules/bluetooth/bluez5-util.h +++ b/src/modules/bluetooth/bluez5-util.h @@ -103,6 +103,7 @@ struct pa_bluetooth_transport { const pa_a2dp_codec *bt_codec; int stream_write_type; + size_t last_read_size; pa_volume_t source_volume; pa_volume_t sink_volume; diff --git a/src/modules/bluetooth/module-bluez5-device.c b/src/modules/bluetooth/module-bluez5-device.c index e0430dea8..94da20688 100644 --- a/src/modules/bluetooth/module-bluez5-device.c +++ b/src/modules/bluetooth/module-bluez5-device.c @@ -413,6 +413,9 @@ static ssize_t bt_transport_read(pa_bluetooth_transport *t, int fd, void *buffer pa_assert((size_t) received <= size); + /* allow write side to find out size of last read packet */ + t->last_read_size = received; + if (p_timestamp) { /* TODO: get timestamp from rtp */