bluetooth: apply write MTU detection based on read packet size

HFP Audio Connection SCO configuration is negotiated symmetrically in both
directions, and USB HCI SCO packet framing is also symmetric in both directions.
This means that packet size will be the same for reads and writes over HFP SCO
socket.

HFP profile specification states that valid speech data shall exist on the
Synchronous Connection in both directions after the Audio Connection is
established.

This guarantees that an incoming packet will arrive shortly after SCO connection
is established. Use it's size to fix write MTU in case kernel value is wrong.

Discussion here https://lore.kernel.org/patchwork/patch/1303411/

Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/507>
This commit is contained in:
Igor V. Kovalenko 2021-02-17 16:31:13 +03:00 committed by PulseAudio Marge Bot
parent 4444ecad6f
commit 62776cc815
4 changed files with 22 additions and 0 deletions

View file

@ -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 */