Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bulk reset #240

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions libaums/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
cmake_minimum_required(VERSION 3.4.1)

add_library( errno-lib

# Sets the library as a shared library.
SHARED
src/c/errno.c )

# Provides a relative path to your source file(s).
src/c/errno.c )
add_library( usb-lib
SHARED
src/c/usb.c )
9 changes: 9 additions & 0 deletions libaums/src/c/usb.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include <jni.h>
#include <sys/ioctl.h>
#include <linux/usbdevice_fs.h>

JNIEXPORT jboolean JNICALL
Java_com_github_mjdev_libaums_usb_AndroidUsbCommunication_resetUsbDeviceNative(JNIEnv *env, jobject thiz, jint fd) {
int ret = ioctl(fd, USBDEVFS_RESET);
return (ret == 0) ? JNI_TRUE : JNI_FALSE;
}
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ private constructor(private val usbManager: UsbManager,
throw IOException("could not claim interface!")
}

val communication = UsbCommunicationFactory.createUsbCommunication(deviceConnection, outEndpoint, inEndpoint)
val communication = UsbCommunicationFactory.createUsbCommunication(deviceConnection, usbInterface, outEndpoint, inEndpoint)
val maxLun = ByteArray(1)
deviceConnection.controlTransfer(161, 254, 0, usbInterface.id, maxLun, 1, 5000)
Log.i(TAG, "MAX LUN " + maxLun[0].toInt())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class ScsiBlockDevice(private val usbCommunication: UsbCommunication, private va
private val readCommand = ScsiRead10(lun=lun)
private val csw = CommandStatusWrapper()

private var cbwTagCounter = 0

/**
* The size of the block device, in blocks of [blockSize] bytes,
*
Expand Down Expand Up @@ -135,9 +137,32 @@ class ScsiBlockDevice(private val usbCommunication: UsbCommunication, private va
*/
@Throws(IOException::class)
private fun transferCommand(command: CommandBlockWrapper, inBuffer: ByteBuffer): Boolean {
for(i in 0..3) {
try {
return transferOneCommand(command, inBuffer)
} catch(e: IOException) {
if (i == 3) {
throw e
}

Log.e(TAG, "error transferring command, sending bulk only reset")
usbCommunication.resetRecovery()
Thread.sleep(1500);
}
}

throw IllegalStateException("This should never happen.. ")
}


@Throws(IOException::class)
private fun transferOneCommand(command: CommandBlockWrapper, inBuffer: ByteBuffer): Boolean {
val outArray = outBuffer.array()
Arrays.fill(outArray, 0.toByte())

command.dCbwTag = cbwTagCounter
cbwTagCounter++

outBuffer.clear()
command.serialize(outBuffer)
outBuffer.clear()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.github.mjdev.libaums.usb

import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbEndpoint
import android.hardware.usb.UsbInterface
import android.util.Log
import com.github.mjdev.libaums.usb.UsbCommunication.Companion.TRANSFER_TIMEOUT
import java.io.IOException


internal abstract class AndroidUsbCommunication(private val deviceConnection: UsbDeviceConnection, private val usbInterface: UsbInterface, private val outEndpoint: UsbEndpoint, private val inEndpoint: UsbEndpoint) : UsbCommunication {

private var isNativeInited: Boolean = false

init {
try {
System.loadLibrary("usb-lib")
isNativeInited = true
} catch (e: UnsatisfiedLinkError) {
isNativeInited = false
Log.e(TAG, "could not load usb-lib", e)
}

}

override fun controlTransfer(requestType: Int, request: Int, value: Int, index: Int, buffer: ByteArray, length: Int): Int {
return deviceConnection.controlTransfer(requestType, request, value, index, buffer, length, TRANSFER_TIMEOUT)
}

override fun resetRecovery() {
bulkOnlyMassStorageReset()
Thread.sleep(10000)
clearFeatureHalt(inEndpoint)
Thread.sleep(10000)
clearFeatureHalt(outEndpoint)
Thread.sleep(10000)

if (isNativeInited) {
Log.w(TAG, "Native reset")
if (!resetUsbDeviceNative(deviceConnection.fileDescriptor)) {
throw IOException("native reset unsuccessful!")
}
}
Thread.sleep(10000)
}

override fun bulkOnlyMassStorageReset() {
Log.w(TAG, "sending bulk only mass storage request")
val bArr = ByteArray(2)
// REQUEST_BULK_ONLY_MASS_STORAGE_RESET = 255
// REQUEST_TYPE_BULK_ONLY_MASS_STORAGE_RESET = 33
val transferred: Int = controlTransfer(33, 255, 0, usbInterface.id, bArr, 0)
if (transferred == -1) {
throw IOException("bulk only mass storage reset failed!")
}
}

override fun clearFeatureHalt(endpoint: UsbEndpoint) {
Log.w(TAG, "sending clear feature halt")
val bArr = ByteArray(2)
val address: Int = endpoint.address
// REQUEST_CLEAR_FEATURE = 1
// REQUEST_TYPE_CLEAR_FEATURE = 2
val transferred: Int = controlTransfer(2, 1, 0, address, bArr, 0)
if (transferred == -1) {
throw IOException("bulk only mass storage reset failed!")
}
}

private external fun resetUsbDeviceNative(fd: Int): Boolean

companion object {
private val TAG = AndroidUsbCommunication::class.java.simpleName
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.github.mjdev.libaums.usb

import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbEndpoint
import android.hardware.usb.UsbInterface

import java.io.IOException
import java.nio.ByteBuffer
Expand All @@ -14,7 +15,7 @@ import java.nio.ByteBuffer
*
* @author mjahnen
*/
internal class HoneyCombMr1Communication(private val deviceConnection: UsbDeviceConnection, private val outEndpoint: UsbEndpoint, private val inEndpoint: UsbEndpoint) : UsbCommunication {
internal class HoneyCombMr1Communication(private val deviceConnection: UsbDeviceConnection, private val usbInterface: UsbInterface, private val outEndpoint: UsbEndpoint, private val inEndpoint: UsbEndpoint) : AndroidUsbCommunication(deviceConnection, usbInterface, outEndpoint, inEndpoint) {

@Throws(IOException::class)
override fun bulkOutTransfer(src: ByteBuffer): Int {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package com.github.mjdev.libaums.usb
import android.annotation.TargetApi
import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbEndpoint
import android.hardware.usb.UsbInterface
import android.os.Build
import android.system.ErrnoException

Expand All @@ -23,7 +24,7 @@ import java.nio.ByteBuffer
* @author mjahnen
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
internal class JellyBeanMr2Communication(private val deviceConnection: UsbDeviceConnection, private val outEndpoint: UsbEndpoint, private val inEndpoint: UsbEndpoint) : UsbCommunication {
internal class JellyBeanMr2Communication(private val deviceConnection: UsbDeviceConnection, private val usbInterface: UsbInterface, private val outEndpoint: UsbEndpoint, private val inEndpoint: UsbEndpoint) : AndroidUsbCommunication(deviceConnection, usbInterface, outEndpoint, inEndpoint) {

@Throws(IOException::class)
override fun bulkOutTransfer(src: ByteBuffer): Int {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package com.github.mjdev.libaums.usb

import android.hardware.usb.UsbEndpoint
import java.io.IOException
import java.nio.ByteBuffer

Expand Down Expand Up @@ -52,6 +53,15 @@ interface UsbCommunication {
@Throws(IOException::class)
fun bulkInTransfer(dest: ByteBuffer): Int

fun controlTransfer(requestType: Int, request: Int, value: Int, index: Int, buffer: ByteArray, length: Int): Int
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


@Throws(IOException::class)
fun resetRecovery()
@Throws(IOException::class)
fun bulkOnlyMassStorageReset()
@Throws(IOException::class)
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fun clearFeatureHalt(endpoint: UsbEndpoint)

companion object {
const val TRANSFER_TIMEOUT = 5000
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.github.mjdev.libaums.usb

import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbEndpoint
import android.hardware.usb.UsbInterface
import android.os.Build
import android.util.Log

Expand All @@ -21,16 +22,16 @@ object UsbCommunicationFactory {
DEVICE_CONNECTION_SYNC
}

fun createUsbCommunication(deviceConnection: UsbDeviceConnection, outEndpoint: UsbEndpoint, inEndpoint: UsbEndpoint): UsbCommunication {
fun createUsbCommunication(deviceConnection: UsbDeviceConnection, usbInterface: UsbInterface, outEndpoint: UsbEndpoint, inEndpoint: UsbEndpoint): UsbCommunication {
return if (underlyingUsbCommunication == UnderlyingUsbCommunication.DEVICE_CONNECTION_SYNC) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
JellyBeanMr2Communication(deviceConnection, outEndpoint, inEndpoint)
JellyBeanMr2Communication(deviceConnection, usbInterface, outEndpoint, inEndpoint)
} else {
Log.i(TAG, "using workaround usb communication")
HoneyCombMr1Communication(deviceConnection, outEndpoint, inEndpoint)
HoneyCombMr1Communication(deviceConnection, usbInterface, outEndpoint, inEndpoint)
}
} else {
UsbRequestCommunication(deviceConnection, outEndpoint, inEndpoint)
UsbRequestCommunication(deviceConnection, usbInterface, outEndpoint, inEndpoint)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.github.mjdev.libaums.usb

import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbEndpoint
import android.hardware.usb.UsbInterface
import android.hardware.usb.UsbRequest

import java.io.IOException
Expand All @@ -11,7 +12,7 @@ import java.nio.ByteBuffer
* Created by magnusja on 21/12/16.
*/

internal class UsbRequestCommunication(private val deviceConnection: UsbDeviceConnection, outEndpoint: UsbEndpoint, inEndpoint: UsbEndpoint) : UsbCommunication {
internal class UsbRequestCommunication(private val deviceConnection: UsbDeviceConnection, private val usbInterface: UsbInterface, outEndpoint: UsbEndpoint, inEndpoint: UsbEndpoint) : AndroidUsbCommunication(deviceConnection, usbInterface, outEndpoint, inEndpoint) {
private val outRequest = UsbRequest().apply { initialize(deviceConnection, outEndpoint) }
private val inRequest = UsbRequest().apply { initialize(deviceConnection, inEndpoint) }
private val workaroundBuffer = ByteBuffer.allocate(1024 * 32 * 4)
Expand Down