Open depau opened 8 months ago
Yeah as you describe it it sounds very weird. Not sure if enlarging the buffer would be a quick fix?
Maybe there is a bug that the val = inBuffer
gets alatered somewhere further down the road?
EDIT: does not look like it.
This is also not the retry of the sense command so that maybe some buffer is not reset properly in the retry phase? (Think 18+18 = 36
)
var transferLength = command.dCbwDataTransferLength
inBuffer.limit(inBuffer.position() + transferLength)
var read = 0
if (transferLength > 0) {
if (command.direction == Direction.IN) {
do {
read += usbCommunication.bulkInTransfer(inBuffer)
if (command.bCbwDynamicSize) {
transferLength = command.dynamicSizeFromPartialResponse(inBuffer)
// This line serves what purpose? When I commented it out, the error did not occur
// inBuffer.limit(inBuffer.position() + transferLength)
}
} while (read < transferLength)
if (read != transferLength) {
throw IOException("Unexpected command size (" + read + ") on response to "
+ command)
}
} else {
written = 0
do {
written += usbCommunication.bulkOutTransfer(inBuffer)
} while (written < transferLength)
if (written != transferLength) {
throw IOException("Could not write all bytes: $command")
}
}
}
I was working on EtchDroid and I noticed this exception:
This is not a big deal for EtchDroid since I've implemented failure recovery: it will ask the user to reconnect the USB drive and keep going. However I'm puzzled by what might be going on. I'm not sure how to reproduce this consistently since a command failure needs to happen before the sense data is requested. Maybe we could record a USB communication log, then mock the Android USB API similarly to what libfprint does to implement device tests? Anyway I'm digressing, I'll open another issue to track that.
Anyway, the culprit seems to be in
ScsiBlockDevice.kt:222
:and in
ScsiBlockDevice.kt:269
:AFAIU
command.dCbwDataTransferLength
should end up being the argument to theScsiRequestSense
ctor,inBuffer.array().size.toByte()
which should be 18. That means the only way the result of the expression can be 36 is ifinBuffer.position()
is somehow== inBuffer.capacity()
, which doesn't make a lot of sense since according to the docs a freshByteBuffer
should have the position set to zero.Do you have any ideas?