ofono/hsphfpd: force write_mtu=24 for mSBC codec

Kernel should provide the correct mtu/packet size to use for SCO socket
I/O, but it does not currently appear to (as of linux 5.9), see
https://lore.kernel.org/linux-bluetooth/20201210003528.3pmaxvubiwegxmhl@pali/T/

When using mSBC, instead of using the (incorrect) kernel-provided value,
hardcode mtu to 24, corresponding to ALT1 mode.  BT-UART adapters should
not require specific mtu, and it appears most BT-USB adapters only
support ALT1, see
https://lore.kernel.org/linux-bluetooth/20201210012003.133000-1-tpiepho@gmail.com/

This code needs to be revised when the issue is sorted out on the kernel
side.

Add setting bluez5.msbc-force-mtu for easier debugging in special cases.

Leave read_mtu as the detected value --- it does not seem to affect
whether BT-USB can record, but Raspberry Pi BT-UART fails to record if a
different value is used.
This commit is contained in:
Pauli Virtanen 2020-12-20 20:36:50 +02:00
parent 62954e14c3
commit 4144427655
2 changed files with 38 additions and 0 deletions

View file

@ -54,6 +54,7 @@ struct spa_bt_backend {
unsigned int filters_added:1;
unsigned int msbc_supported:1;
int msbc_force_mtu;
};
enum hsphfpd_volume_control {
@ -713,6 +714,20 @@ static DBusHandlerResult hsphfpd_new_audio_connection(DBusConnection *conn, DBus
if (transport->codec == HFP_AUDIO_CODEC_CVSD) {
transport->read_mtu = 48;
transport->write_mtu = 48;
} else if (transport->codec == HFP_AUDIO_CODEC_MSBC && backend->msbc_force_mtu != 0) {
transport->read_mtu = mtu;
/* Force low write packet size, as kernel (at least <= 5.9) does not
* provide correct values for userspace. The value 24 should be
* right for bluetooth ALT1 mode. See
* https://lore.kernel.org/linux-bluetooth/20201210003528.3pmaxvubiwegxmhl@pali/T/
*
* XXX: revise when hsphfpd/kernel reports correct numbers
*/
transport->write_mtu = (backend->msbc_force_mtu > 0) ? backend->msbc_force_mtu : 24;
spa_log_warn(backend->log, "hsphfpd: forcing write_mtu = %d for mSBC; "
"set bluez5.msbc-force-mtu=0 to use autodetected (%d)",
(int) transport->write_mtu, (int) mtu);
} else {
transport->read_mtu = mtu;
transport->write_mtu = mtu;
@ -1487,6 +1502,10 @@ struct spa_bt_backend *backend_hsphfpd_new(struct spa_bt_monitor *monitor,
backend->msbc_supported = strcmp(str, "true") == 0 || atoi(str) == 1;
else
backend->msbc_supported = false;
if (info && (str = spa_dict_lookup(info, "bluez5.msbc-force-mtu")))
backend->msbc_force_mtu = atoi(str);
else
backend->msbc_force_mtu = -1;
spa_list_init(&backend->endpoint_list);

View file

@ -51,6 +51,7 @@ struct spa_bt_backend {
unsigned int filters_added:1;
unsigned int msbc_supported:1;
int msbc_force_mtu;
};
#define OFONO_SERVICE "org.ofono"
@ -101,6 +102,20 @@ static void ofono_transport_get_mtu(struct spa_bt_backend *backend, struct spa_b
t->read_mtu = sco_opt.mtu;
t->write_mtu = sco_opt.mtu;
}
if (backend->msbc_force_mtu != 0 && t->codec == HFP_AUDIO_CODEC_MSBC) {
/* Force low write packet size, as kernel (at least <= 5.9) does not
* provide correct values for userspace. The value 24 should be
* right for bluetooth ALT1 mode. See
* https://lore.kernel.org/linux-bluetooth/20201210003528.3pmaxvubiwegxmhl@pali/T/
*
* XXX: revise when kernel reports correct numbers
*/
t->write_mtu = (backend->msbc_force_mtu > 0) ? backend->msbc_force_mtu : 24;
spa_log_warn(backend->log, NAME": forcing write_mtu = %d for mSBC; "
"set bluez5.msbc-force-mtu=0 to autodetect",
(int) t->write_mtu);
}
}
}
@ -704,6 +719,10 @@ struct spa_bt_backend *backend_ofono_new(struct spa_bt_monitor *monitor,
backend->msbc_supported = strcmp(str, "true") == 0 || atoi(str) == 1;
else
backend->msbc_supported = false;
if (info && (str = spa_dict_lookup(info, "bluez5.msbc-mtu-workaround")))
backend->msbc_force_mtu = atoi(str);
else
backend->msbc_force_mtu = -1;
if (!dbus_connection_register_object_path(backend->conn,
OFONO_AUDIO_CLIENT,