@@ -24,7 +24,6 @@ import android.hardware.usb.UsbDeviceConnection
2424import android.hardware.usb.UsbEndpoint
2525import android.hardware.usb.UsbInterface
2626import android.hardware.usb.UsbManager
27- import android.hardware.usb.UsbRequest
2827import android.os.Handler
2928import android.os.Looper
3029import android.os.ParcelUuid
@@ -45,7 +44,6 @@ import to.bitkit.ext.bluetoothManager
4544import to.bitkit.ext.usbManager
4645import to.bitkit.utils.Logger
4746import java.io.File
48- import java.nio.ByteBuffer
4947import java.util.UUID
5048import java.util.concurrent.ConcurrentHashMap
5149import java.util.concurrent.CountDownLatch
@@ -702,39 +700,27 @@ class TrezorTransport @Inject constructor(
702700 error = " Device not open: $path " ,
703701 )
704702
705- val buffer = ByteBuffer .allocate(USB_CHUNK_SIZE )
706- val request = UsbRequest ()
707- try {
708- if (! request.initialize(openDevice.connection, openDevice.readEndpoint)) {
709- return TrezorTransportReadResult (
710- success = false ,
711- data = byteArrayOf(),
712- error = " Failed to initialize USB read request" ,
713- )
714- }
715- if (! request.queue(buffer)) {
716- return TrezorTransportReadResult (
717- success = false ,
718- data = byteArrayOf(),
719- error = " Failed to queue USB read request" ,
720- )
721- }
722- openDevice.connection.requestWait(READ_TIMEOUT_MS .toLong())
723- ? : return TrezorTransportReadResult (
724- success = false ,
725- data = byteArrayOf(),
726- error = " USB read timed out" ,
727- )
728-
729- buffer.flip()
730- val bytesRead = buffer.remaining()
731- val data = ByteArray (bytesRead)
732- buffer.get(data)
733- Logger .debug(" USB read '$bytesRead ' bytes from '$path '" , context = TAG )
734- TrezorTransportReadResult (success = true , data = data, error = " " )
735- } finally {
736- request.close()
703+ // Synchronous transfer on purpose: the async UsbRequest API requires
704+ // cancelling and reaping a timed-out request before closing it; closing
705+ // with the URB still queued frees memory the kernel later writes into
706+ // (native SIGSEGV in libusbhost once the device finally responds).
707+ val buffer = ByteArray (USB_CHUNK_SIZE )
708+ val bytesRead = openDevice.connection.bulkTransfer(
709+ openDevice.readEndpoint,
710+ buffer,
711+ buffer.size,
712+ READ_TIMEOUT_MS ,
713+ )
714+ if (bytesRead < 0 ) {
715+ return TrezorTransportReadResult (
716+ success = false ,
717+ data = byteArrayOf(),
718+ error = " USB read timed out" ,
719+ )
737720 }
721+
722+ Logger .debug(" USB read '$bytesRead ' bytes from '$path '" , context = TAG )
723+ TrezorTransportReadResult (success = true , data = buffer.copyOf(bytesRead), error = " " )
738724 } catch (e: Exception ) {
739725 Logger .error(" USB read failed" , e, context = TAG )
740726 TrezorTransportReadResult (success = false , data = byteArrayOf(), error = e.message ? : " Unknown error" )
@@ -747,29 +733,18 @@ class TrezorTransport @Inject constructor(
747733 val openDevice = usbConnections[path]
748734 ? : return TrezorTransportWriteResult (success = false , error = " Device not open: $path " )
749735
750- val buffer = ByteBuffer .wrap(data)
751- val request = UsbRequest ()
752- try {
753- if (! request.initialize(openDevice.connection, openDevice.writeEndpoint)) {
754- return TrezorTransportWriteResult (
755- success = false ,
756- error = " Failed to initialize USB write request" ,
757- )
758- }
759- if (! request.queue(buffer)) {
760- return TrezorTransportWriteResult (
761- success = false ,
762- error = " Failed to queue USB write request" ,
763- )
764- }
765- openDevice.connection.requestWait(WRITE_TIMEOUT_MS .toLong())
766- ? : return TrezorTransportWriteResult (success = false , error = " USB write timed out" )
767-
768- Logger .debug(" USB wrote '${data.size} ' bytes to '$path '" , context = TAG )
769- TrezorTransportWriteResult (success = true , error = " " )
770- } finally {
771- request.close()
736+ val bytesWritten = openDevice.connection.bulkTransfer(
737+ openDevice.writeEndpoint,
738+ data,
739+ data.size,
740+ WRITE_TIMEOUT_MS ,
741+ )
742+ if (bytesWritten != data.size) {
743+ return TrezorTransportWriteResult (success = false , error = " USB write timed out" )
772744 }
745+
746+ Logger .debug(" USB wrote '${data.size} ' bytes to '$path '" , context = TAG )
747+ TrezorTransportWriteResult (success = true , error = " " )
773748 } catch (e: Exception ) {
774749 Logger .error(" USB write failed" , e, context = TAG )
775750 TrezorTransportWriteResult (success = false , error = e.message ? : " Unknown error" )
0 commit comments