diff --git a/README.md b/README.md index ec1e33e..8b805e9 100644 --- a/README.md +++ b/README.md @@ -69,13 +69,27 @@ UsbMassStorageDevice device = UsbMassStorageDevice.getMassStorageDevice(config); Once we have instance we need to initialize device, which will open device and claim its interface: ```java -// see previous step +// see previous step we have instance of UsbMassStorageDevice called device device.init(); ``` +After device is initialized we can work with it get partitions, get blockDevice: +When we are done with specific device we need to close it: + +```java +device.close(); +``` + +When we are done with library we need to call this, to dispose of LibUsb instance (instance is created automatically, but needs to be disposed manually): + +```java +UsbMassStorageLibrary. +``` + + ### Status Just started on this project in April 2024, and it will take me some time to get it to working state. diff --git a/libaums/src/main/java/com/atech/library/usb/libaums/UsbDeviceCommunication.java b/libaums/src/main/java/com/atech/library/usb/libaums/UsbDeviceCommunication.java index 8c46bc3..58a6fd5 100644 --- a/libaums/src/main/java/com/atech/library/usb/libaums/UsbDeviceCommunication.java +++ b/libaums/src/main/java/com/atech/library/usb/libaums/UsbDeviceCommunication.java @@ -57,7 +57,7 @@ public int bulkOutTransfer(byte[] data, int length) { buffer.put(data, 0, length); //put(byte[] src, int offset, int length) IntBuffer transferred = BufferUtils.allocateIntBuffer(); - int result = LibUsb.bulkTransfer(handle, deviceSettings.getOutEndpoint(), buffer, + int result = LibUsb.bulkTransfer(handle, deviceSettings.getOutEndpointAddress(), buffer, transferred, TIMEOUT); if (result != LibUsb.SUCCESS) { @@ -84,7 +84,7 @@ public int bulkInTransfer(byte[] data, int length) { ByteBuffer buffer = BufferUtils.allocateByteBuffer(length).order( ByteOrder.LITTLE_ENDIAN); IntBuffer transferred = BufferUtils.allocateIntBuffer(); - int result = LibUsb.bulkTransfer(handle, deviceSettings.getInEndpoint(), buffer, + int result = LibUsb.bulkTransfer(handle, deviceSettings.getInEndpointAddress(), buffer, transferred, TIMEOUT); if (result != LibUsb.SUCCESS) { diff --git a/libaums/src/main/java/com/atech/library/usb/libaums/UsbManagement.java b/libaums/src/main/java/com/atech/library/usb/libaums/UsbManagement.java index 396a2b3..ad1f7ab 100644 --- a/libaums/src/main/java/com/atech/library/usb/libaums/UsbManagement.java +++ b/libaums/src/main/java/com/atech/library/usb/libaums/UsbManagement.java @@ -5,6 +5,7 @@ import com.atech.library.usb.libaums.usb4java.Usb4JavaManager; import com.google.gson.Gson; import com.google.gson.GsonBuilder; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import org.usb4java.*; @@ -56,6 +57,7 @@ public void openDevice(UsbMassStorageDeviceConfig usbDeviceSettings) { } + @SneakyThrows public static void main(String[] args) { //Usb4JavaManager usbManagement = new Usb4JavaManager(); diff --git a/libaums/src/main/java/com/atech/library/usb/libaums/UsbMassStorageLibrary.java b/libaums/src/main/java/com/atech/library/usb/libaums/UsbMassStorageLibrary.java index 7b7b0bd..4f1016c 100644 --- a/libaums/src/main/java/com/atech/library/usb/libaums/UsbMassStorageLibrary.java +++ b/libaums/src/main/java/com/atech/library/usb/libaums/UsbMassStorageLibrary.java @@ -38,8 +38,9 @@ public static void disposeLibrary() { if (libraryInitialized) { // Deinitialize the libusb context LibUsb.exit(context); + libraryInitialized = false; + context = null; } } - } diff --git a/libaums/src/main/java/com/atech/library/usb/libaums/usb4java/Usb4JavaUsbDeviceCommunication.java b/libaums/src/main/java/com/atech/library/usb/libaums/usb4java/Usb4JavaUsbDeviceCommunication.java index 1c46eb0..8fd382f 100644 --- a/libaums/src/main/java/com/atech/library/usb/libaums/usb4java/Usb4JavaUsbDeviceCommunication.java +++ b/libaums/src/main/java/com/atech/library/usb/libaums/usb4java/Usb4JavaUsbDeviceCommunication.java @@ -17,6 +17,7 @@ @Slf4j public class Usb4JavaUsbDeviceCommunication implements UsbCommunication { + private static final int TRANSFER_TIMEOUT = 21000; DeviceHandle deviceHandle; UsbMassStorageDeviceConfig deviceConfig; @@ -25,14 +26,14 @@ public Usb4JavaUsbDeviceCommunication(UsbMassStorageDeviceConfig usbMassStorageD } public void openDevice() throws LibAumsException { - log.info("openDevice {}:{}") + log.info("openDevice {}", deviceConfig.getReadableDeviceId()); Context context = UsbMassStorageLibrary.initLibrary(); // Open device DeviceHandle handle = LibUsb.openDeviceWithVidPid(context, deviceConfig.getVendorId(), deviceConfig.getProductId()); if (handle == null) { - System.err.println("Test device not found."); + log.error("Device {} not found, or could not be opened.", deviceConfig.getReadableDeviceId()); System.exit(1); } @@ -44,23 +45,59 @@ public void openDevice() throws LibAumsException { { throw new LibUsbException("Unable to claim interface", result); } + + log.info("Device {} opened and interafce {} claimed.", deviceConfig.getReadableDeviceId(), deviceConfig.getInterfaceNumber()); } @Override - public int bulkOutTransfer(byte[] buffer, int length) { + public int bulkOutTransfer(byte[] data, int length) throws LibAumsException { // TODO implement Usb4JavaUsbDeviceCommunication - // return deviceConnection.bulkTransfer(outEndpoint, buffer, length, TRANSFER_TIMEOUT); + log.info("BulkOutTransfer (data={},length={})", data, length); + + ByteBuffer buffer = BufferUtils.allocateByteBuffer(data.length); + buffer.put(data); + IntBuffer transferred = BufferUtils.allocateIntBuffer(); + int result = LibUsb.bulkTransfer(deviceHandle, deviceConfig.getOutEndpointAddress(), buffer, + transferred, TRANSFER_TIMEOUT); + if (result != LibUsb.SUCCESS) { + throw new LibUsbException("Unable to send data", result); + } + log.info(transferred.get() + " bytes sent to device"); + // return deviceConnection.bulkTransfer(outEndpoint, buffer, length, TRANSFER_TIMEOUT); - return 0; + return LibUsb.SUCCESS; } @Override - public int bulkOutTransfer(byte[] buffer, int offset, int length) { + public int bulkOutTransfer(byte[] data, int offset, int length) throws LibAumsException{ // TODO implement Usb4JavaUsbDeviceCommunication + if (offset==0) { + return bulkOutTransfer(data, length); + } + + log.info("BulkOutTransfer (data={},length={},offset={})", data, length, offset); + + int remaining = length-offset; + byte[] newData = new byte[length-offset]; + System.arraycopy(data, offset, newData, 0, remaining); + + ByteBuffer buffer = BufferUtils.allocateByteBuffer(newData.length); + buffer.put(newData); + IntBuffer transferred = BufferUtils.allocateIntBuffer(); + int result = LibUsb.bulkTransfer(deviceHandle, deviceConfig.getOutEndpointAddress(), buffer, + transferred, TRANSFER_TIMEOUT); + if (result != LibUsb.SUCCESS) + { + throw LibAumsException.createWithLibUsbException("Unable to send data", result); + } + log.info(transferred.get() + " bytes sent to device"); + + return LibUsb.SUCCESS; + // if (offset == 0) // return deviceConnection.bulkTransfer(outEndpoint, buffer, length, TRANSFER_TIMEOUT); // @@ -69,23 +106,56 @@ public int bulkOutTransfer(byte[] buffer, int offset, int length) { // return deviceConnection.bulkTransfer(outEndpoint, tmpBuffer, length, // TRANSFER_TIMEOUT); - return 0; + } @Override - public int bulkInTransfer(byte[] buffer, int length) { + public int bulkInTransfer(byte[] data, int length) throws LibAumsException { - LibUsb.bulkTransfer(deviceHandle, ) + log.info("BulkInTransfer (data={},length={})", data, length); - // TODO implement Usb4JavaUsbDeviceCommunication - // return deviceConnection.bulkTransfer(inEndpoint, buffer, length, TRANSFER_TIMEOUT); + // TODO bulkInTransfer, Libusb does things different than android + + ByteBuffer buffer = BufferUtils.allocateByteBuffer(length).order( + ByteOrder.LITTLE_ENDIAN); + IntBuffer transferred = BufferUtils.allocateIntBuffer(); + int result = LibUsb.bulkTransfer(deviceHandle, deviceConfig.getInEndpointAddress(), buffer, + transferred, TRANSFER_TIMEOUT); + if (result != LibUsb.SUCCESS) { + throw LibAumsException.createWithLibUsbException("Unable to read data", result); + } + log.info(transferred.get() + " bytes read from device"); + System.arraycopy(buffer.array(), 0, data, 0, length); - return 0; + // return LibUsb.bulkTransfer( +// deviceHandle, deviceConfig.getInEndpointAddress(), buffer, length, TRANSFER_TIMEOUT); + + + return LibUsb.SUCCESS; } @Override - public int bulkInTransfer(byte[] buffer, int offset, int length) { - // TODO implement Usb4JavaUsbDeviceCommunication + public int bulkInTransfer(byte[] data, int offset, int length) throws LibAumsException{ + // TODO implement Usb4JavaUsbDeviceCommunication not Sure if this will work ok + + if (offset==0) { + return bulkInTransfer(data, length); + } + + log.info("BulkInTransfer (data={},length={},offset={})", data, length, offset); + + ByteBuffer buffer = BufferUtils.allocateByteBuffer(length).order( + ByteOrder.LITTLE_ENDIAN); + IntBuffer transferred = BufferUtils.allocateIntBuffer(); + int result = LibUsb.bulkTransfer(deviceHandle, deviceConfig.getInEndpointAddress(), buffer, + transferred, TRANSFER_TIMEOUT); + if (result != LibUsb.SUCCESS) { + throw LibAumsException.createWithLibUsbException("Unable to read data", result); + } + log.info(transferred.get() + " bytes read from device"); + System.arraycopy(buffer.array(), 0, data, offset, length); + + return LibUsb.SUCCESS; // if (offset == 0) // return deviceConnection.bulkTransfer(inEndpoint, buffer, length, TRANSFER_TIMEOUT); @@ -95,10 +165,6 @@ public int bulkInTransfer(byte[] buffer, int offset, int length) { // TRANSFER_TIMEOUT); // System.arraycopy(tmpBuffer, 0, buffer, offset, length); // return result; - - // read() - - return 0; } @@ -110,7 +176,7 @@ public int bulkInTransfer(byte[] buffer, int offset, int length) { * @param data * The data to send to the device. */ - public static void write(DeviceHandle handle, byte[] data) + public static void write(DeviceHandle handle, byte[] data) throws LibAumsException { // ByteBuffer buffer = BufferUtils.allocateByteBuffer(data.length); // buffer.put(data); @@ -133,7 +199,7 @@ public static void write(DeviceHandle handle, byte[] data) * The number of bytes to read from the device. * @return The read data. */ - public static ByteBuffer read(DeviceHandle handle, int size) + public static ByteBuffer read(DeviceHandle handle, int size) throws LibAumsException { // ByteBuffer buffer = BufferUtils.allocateByteBuffer(size).order( // ByteOrder.LITTLE_ENDIAN); @@ -153,7 +219,7 @@ public static ByteBuffer read(DeviceHandle handle, int size) public void closeDevice() throws LibAumsException { - // Release the ADB interface + // Release interface int result = LibUsb.releaseInterface(deviceHandle, deviceConfig.getInterfaceNumber()); if (result != LibUsb.SUCCESS) { throw LibAumsException.createWithLibUsbException("Unable to release interface", result); diff --git a/libaums/src/main/java/com/github/mjdev/libaums/UsbCommunication.java b/libaums/src/main/java/com/github/mjdev/libaums/UsbCommunication.java index 0213dbd..56096db 100644 --- a/libaums/src/main/java/com/github/mjdev/libaums/UsbCommunication.java +++ b/libaums/src/main/java/com/github/mjdev/libaums/UsbCommunication.java @@ -17,6 +17,8 @@ package com.github.mjdev.libaums; +import com.atech.library.usb.libaums.data.LibAumsException; + /** * This Interface describes a low level device to perform USB transfers. At the * moment only bulk IN and OUT transfer are supported. Every class that follows @@ -41,7 +43,7 @@ public interface UsbCommunication { * @return Bytes transmitted if successful, or -1. * @see #bulkInTransfer(byte[], int, int) */ - public int bulkOutTransfer(byte[] buffer, int length); + public int bulkOutTransfer(byte[] buffer, int length) throws LibAumsException; /** * Performs a bulk out transfer beginning at the given offset in the @@ -57,7 +59,7 @@ public interface UsbCommunication { * @return Bytes transmitted if successful, or -1. * @see #bulkInTransfer(byte[], int) */ - public int bulkOutTransfer(byte[] buffer, int offset, int length); + public int bulkOutTransfer(byte[] buffer, int offset, int length) throws LibAumsException; /** * Performs a bulk in transfer beginning at offset zero in the @@ -73,7 +75,7 @@ public interface UsbCommunication { * @return Bytes read if successful, or -1. * @see #bulkInTransfer(byte[], int, int) */ - public int bulkInTransfer(byte[] buffer, int length); + public int bulkInTransfer(byte[] buffer, int length) throws LibAumsException; /** * Performs a bulk in transfer beginning at the given offset in the @@ -89,5 +91,5 @@ public interface UsbCommunication { * @return Bytes read if successful, or -1. * @see #bulkInTransfer(byte[], int) */ - public int bulkInTransfer(byte[] buffer, int offset, int length); + public int bulkInTransfer(byte[] buffer, int offset, int length) throws LibAumsException; } diff --git a/libaums/src/main/java/com/github/mjdev/libaums/UsbMassStorageDevice.java b/libaums/src/main/java/com/github/mjdev/libaums/UsbMassStorageDevice.java index 4152491..71c0393 100644 --- a/libaums/src/main/java/com/github/mjdev/libaums/UsbMassStorageDevice.java +++ b/libaums/src/main/java/com/github/mjdev/libaums/UsbMassStorageDevice.java @@ -267,7 +267,6 @@ public static List getListOfAttachedUsbMassStorageDe continue; } - // TODO UsbMassStorageDeviceConfig filling - missing endpoints outList.add(UsbMassStorageDeviceConfig.builder() .vendorId(device.getUsbDeviceDescriptor().idVendor()) .productId(device.getUsbDeviceDescriptor().idProduct()) @@ -275,9 +274,7 @@ public static List getListOfAttachedUsbMassStorageDe .inEndpointAddress(inEndpoint.bEndpointAddress()) .outEndpointAddress(outEndpoint.bEndpointAddress()) .build()); - } - } return outList; diff --git a/libaums/src/main/java/com/github/mjdev/libaums/fs/UsbFileInputStream.java b/libaums/src/main/java/com/github/mjdev/libaums/fs/UsbFileInputStream.java index 8296003..fe955b5 100644 --- a/libaums/src/main/java/com/github/mjdev/libaums/fs/UsbFileInputStream.java +++ b/libaums/src/main/java/com/github/mjdev/libaums/fs/UsbFileInputStream.java @@ -17,6 +17,7 @@ package com.github.mjdev.libaums.fs; +import com.atech.library.usb.libaums.data.LibAumsException; import lombok.extern.slf4j.Slf4j; import java.io.IOException; @@ -29,7 +30,6 @@ @Slf4j public class UsbFileInputStream extends InputStream { - private static final String TAG = UsbFileInputStream.class.getSimpleName(); private UsbFile file; private int currentByteOffset = 0; @@ -52,16 +52,21 @@ public int available() throws IOException { @Override public int read() throws IOException { - if(currentByteOffset >= file.getLength()) { - return -1; - } + try { + if(currentByteOffset >= file.getLength()) { + return -1; + } + + ByteBuffer buffer = ByteBuffer.allocate(512); + buffer.limit(1); + file.read(currentByteOffset, buffer); + currentByteOffset++; + buffer.flip(); + return buffer.get(); - ByteBuffer buffer = ByteBuffer.allocate(512); - buffer.limit(1); - file.read(currentByteOffset, buffer); - currentByteOffset++; - buffer.flip(); - return buffer.get(); + } catch (LibAumsException e) { + throw (IOException)e.getCause(); + } } @Override @@ -72,40 +77,49 @@ public void close() throws IOException { @Override public int read(byte[] buffer) throws IOException { - if(currentByteOffset >= file.getLength()) { - return -1; - } + try { + if(currentByteOffset >= file.getLength()) { + return -1; + } - long length = file.getLength(); - long toRead = Math.min(buffer.length, length - currentByteOffset); + long length = file.getLength(); + long toRead = Math.min(buffer.length, length - currentByteOffset); - ByteBuffer byteBuffer = ByteBuffer.wrap(buffer); - byteBuffer.limit((int) toRead); + ByteBuffer byteBuffer = ByteBuffer.wrap(buffer); + byteBuffer.limit((int) toRead); - file.read(currentByteOffset, byteBuffer); - currentByteOffset += toRead; + file.read(currentByteOffset, byteBuffer); + currentByteOffset += toRead; + + return (int) toRead; + } catch (LibAumsException e) { + throw (IOException)e.getCause(); + } - return (int) toRead; } @Override public int read(byte[] buffer, int byteOffset, int byteCount) throws IOException { + try { + if(currentByteOffset >= file.getLength()) { + return -1; + } - if(currentByteOffset >= file.getLength()) { - return -1; - } + long length = file.getLength(); + long toRead = Math.min(byteCount, length - currentByteOffset); - long length = file.getLength(); - long toRead = Math.min(byteCount, length - currentByteOffset); + ByteBuffer byteBuffer = ByteBuffer.wrap(buffer); + byteBuffer.position(byteOffset); + byteBuffer.limit((int) toRead + byteOffset); - ByteBuffer byteBuffer = ByteBuffer.wrap(buffer); - byteBuffer.position(byteOffset); - byteBuffer.limit((int) toRead + byteOffset); + file.read(currentByteOffset, byteBuffer); + currentByteOffset += toRead; - file.read(currentByteOffset, byteBuffer); - currentByteOffset += toRead; + return (int) toRead; + } catch (LibAumsException e) { + throw (IOException)e.getCause(); + } - return (int) toRead; } @Override diff --git a/libaums/src/main/java/com/github/mjdev/libaums/fs/UsbFileOutputStream.java b/libaums/src/main/java/com/github/mjdev/libaums/fs/UsbFileOutputStream.java index c3f1ce0..100aa28 100644 --- a/libaums/src/main/java/com/github/mjdev/libaums/fs/UsbFileOutputStream.java +++ b/libaums/src/main/java/com/github/mjdev/libaums/fs/UsbFileOutputStream.java @@ -18,6 +18,8 @@ package com.github.mjdev.libaums.fs; +import com.atech.library.usb.libaums.data.LibAumsException; + import javax.annotation.Nonnull; import java.io.IOException; import java.io.OutputStream; @@ -42,10 +44,15 @@ public UsbFileOutputStream(@Nonnull UsbFile file) { @Override public void write(int oneByte) throws IOException { - ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[] {(byte) oneByte}); - file.write(currentByteOffset, byteBuffer); + try { + ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[] {(byte) oneByte}); + file.write(currentByteOffset, byteBuffer); + + currentByteOffset++; + } catch (LibAumsException e) { + throw (IOException)e.getCause(); + } - currentByteOffset++; } @Override @@ -55,26 +62,40 @@ public void close() throws IOException { @Override public void flush() throws IOException { - file.flush(); + try { + file.flush(); + } catch (LibAumsException e) { + throw (IOException)e.getCause(); + } } @Override public void write(byte[] buffer) throws IOException { - ByteBuffer byteBuffer = ByteBuffer.wrap(buffer); - file.write(currentByteOffset, byteBuffer); + try { + ByteBuffer byteBuffer = ByteBuffer.wrap(buffer); + file.write(currentByteOffset, byteBuffer); + + currentByteOffset += buffer.length; + } catch (LibAumsException e) { + throw (IOException)e.getCause(); + } - currentByteOffset += buffer.length; } @Override public void write(byte[] buffer, int offset, int count) throws IOException { - ByteBuffer byteBuffer = ByteBuffer.wrap(buffer); + try { + ByteBuffer byteBuffer = ByteBuffer.wrap(buffer); - byteBuffer.position(offset); - byteBuffer.limit(count + offset); + byteBuffer.position(offset); + byteBuffer.limit(count + offset); - file.write(currentByteOffset, byteBuffer); + file.write(currentByteOffset, byteBuffer); + + currentByteOffset += count; + } catch (LibAumsException e) { + throw (IOException)e.getCause(); + } - currentByteOffset += count; } } diff --git a/libaums/src/test/java/com/atech/library/usb/libaums/UsbMassStorageLibraryTest.java b/libaums/src/test/java/com/atech/library/usb/libaums/UsbMassStorageLibraryTest.java new file mode 100644 index 0000000..af620e4 --- /dev/null +++ b/libaums/src/test/java/com/atech/library/usb/libaums/UsbMassStorageLibraryTest.java @@ -0,0 +1,25 @@ +package com.atech.library.usb.libaums; + +import com.atech.library.usb.libaums.usb.device.ATUsbDevice; +import com.atech.library.usb.libaums.usb4java.Usb4JavaManager; +import org.junit.Assert; +import org.junit.Test; + +import java.util.List; + +import static org.junit.Assert.*; + +/** + * Created by andy on 12.04.2024. + */ +public class UsbMassStorageLibraryTest { + + @Test + public void getDeviceList() throws Exception{ + List deviceList = Usb4JavaManager.getDeviceList(); + Assert.assertNotNull(deviceList); + UsbMassStorageLibrary.disposeLibrary(); + } + + +} \ No newline at end of file diff --git a/libaums/src/test/java/com/github/mjdev/libaums/ExampleUnitTest.java b/libaums/src/test/java/com/github/mjdev/libaums/ExampleUnitTest.java deleted file mode 100644 index d9bc606..0000000 --- a/libaums/src/test/java/com/github/mjdev/libaums/ExampleUnitTest.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.github.mjdev.libaums; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * To work on unit tests, switch the Test Artifact in the Build Variants view. - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() throws Exception { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file