3

I have already seen lot's of questions here about bulkTransfer, most of them have used the wrong interfaces to read and write but I'm quit sure that I have choosen the proper interfaces:

private UsbManager usbManager;
private UsbDevice usbDevice;
private UsbDeviceConnection usbDeviceConnection;
private UsbInterface usbInterface;
private UsbEndpoint readEndpoint;
private UsbEndpoint writeEndpoint;
private UsbEndpoint interruptEndpoint;
private PtpSession ptpSession;

public boolean Connect(UsbManager usbManager,UsbDevice usbDevice, PtpSession ptpSession)
{
    if(usbManager == null ||usbDevice == null||ptpSession == null)
        return false;
    else
    {
        this.usbManager = usbManager;
        this.usbDevice = usbDevice;
        this.ptpSession = ptpSession;

        for (int i = 0; i < this.usbDevice.getInterfaceCount(); i++) {
            UsbInterface uintf = this.usbDevice.getInterface(i);
            if (uintf.getInterfaceClass() == UsbConstants.USB_CLASS_STILL_IMAGE) {
                Log.d(TAG, "Imaging USB interface found");
                this.usbInterface = uintf;
                break;
            }
        }
    }

    // find the wright usb endpoints
    if(usbInterface == null)
        return false;
    else
    {
        for(int i = 0; i < usbInterface.getEndpointCount();i++)
        {
            UsbEndpoint ep = usbInterface.getEndpoint(i);
            if (ep.getDirection() == UsbConstants.USB_DIR_IN) {
                if(ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK)
                {

                    readEndpoint = ep;
                }
                else if(ep.getType() == UsbConstants.USB_ENDPOINT_XFER_INT)
                {
                    interruptEndpoint = ep;

                }
            } else if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
                writeEndpoint = ep;
            }
        }

        this.usbDeviceConnection = usbManager.openDevice(usbDevice);
        usbDeviceConnection.claimInterface(usbInterface,true);
    }

    if(readEndpoint == null || writeEndpoint == null ||interruptEndpoint == null)
        return false;
    return true;
}

This part of the Code seems to work in the way it should, then there are two other methods to read and write data:

private boolean writeData(byte[] data)
{
    int retry = 0;
    while (usbDeviceConnection.bulkTransfer(writeEndpoint, data, data.length, 5000) != data.length)
    {
        retry++;
        if (retry > 4)
        {
            return false;
        }
    }
    return true;
}

private byte[] readData()
{
    long rStart = System.currentTimeMillis();
    byte[] mReadData = new byte[30];
    while (true) {
        int bytesCount = usbDeviceConnection.bulkTransfer(readEndpoint, mReadData, mReadData.length, 5000);
        if (bytesCount >= 0) {
            return mReadData;
        }
        else if (System.currentTimeMillis() - rStart > 5000) {
            return new byte[]{};
        } else {
            Log.e(TAG, String.format("Bulk read -1 cmd"));
        }


    }
}

I can send data and get positiv feedback from the writeData Method. Then I wait for some time (100 or even 1000ms) and try to readData. And I have never gotten any data to read and get always -1 as feedback (until the Method returns a empty array after 5 seconds). I have already tried to change the size of the mReadData array to other values but nothing has worked so far (a size of 30bytes of data would be the expected value for a typical ResponseData block at the PTP Protocoll).

Overall I try to read data from my Nikon D3200 with my Smartphone (Galaxy S7 with Android 6.0.1 running) with the original USB-OTG Adapter and im quite sure that my Code is the problem but after hours of trying different things I have really no idea what the problem is.

Here is a Link to the ISO 15740 Norm that I have used: Link to ISO 15740

Maybe someone of you has an idea what's my Problem ?

Thanks in advance, Dominik

Dominik
  • 43
  • 1
  • 4

1 Answers1

1

the following code will not work

private boolean writeData(byte[] data)
{
    int retry = 0;
    while (usbDeviceConnection.bulkTransfer(writeEndpoint, data, data.length, 5000) != data.length)
    {
        retry++;
        if (retry > 4)
        {
            return false;
        }
    }
    return true;
}  

instead use the following to check if the connection status

 int ret = usbDeviceConnection.bulkTransfer(writeEndpoint, data, data.length, 5000;


     if(ret < 0)
                    {
                      Log.d("TAG", "Error happened!");
                    }
                    else if(ret == 0)
                    {
                        Log.d("TAG", "No data transferred!");
                    }
                    else
                    {
                        Log.d("TAG", "success!");
                    }

(https://www.developer.android.com/studio/debug/am-logcat.html instead of logging you can also use try {...} catch {...} blocks or logcat,...)

copied from android usb UsbDeviceConnection.bulkTransfer returns -1

then there are multiple possibilites why you write/read no data

  • programming error (maybe is a reference error because the writeData() method does not know the reference to the usbDeviceConnection object) try giving it to the method as parameter like

    private UsbDeviceConnection usbDeviceConnection;
    private boolean writeData(UsbDeviceConnection  usbDeviceConnection, byte[] data) { ... }
    

    and invoke the method with

     writeData(usbDeviceConnection, ...);
    

( http://www.programcreek.com/java-api-examples/index.php?api=android.hardware.usbUsbDeviceConnection )

the same applies for the readData() method

https://developer.android.com/reference/android/hardware/usb/UsbDeviceConnection.html

Community
  • 1
  • 1
ralf htp
  • 9,149
  • 4
  • 22
  • 34
  • Thanks for the fast response ! It can't be a reference error because the code is in the same class. I have implemented the given write method and it works just fine (output is: "success!"). I have tried getMaxPacketSize to define the size of the byte array thats sent and read, also with no sucess. To ensure that there is no permission problem I have tried usbManager.hasPermission(usbDevice) - which gives me true. – Dominik Feb 03 '17 at 16:14
  • what is the return value i of `int i = ... .getMaxPacketSize()` of both IN and OUT endpoint? – ralf htp Feb 03 '17 at 18:30
  • writeEndpoint.getMaxPacketSize() = 512 and readEndpoint.getMaxPacketSize() = 512 – Dominik Feb 03 '17 at 19:46
  • this means that you get at least the endpoint descriptor but you can not read/write the endpoint. i do not know what is the cause, maybe see the source code of *libptp* (in C) to see if there are special features in PTP protocol... – ralf htp Feb 04 '17 at 12:21
  • thats bad because I have already looked at some PTP protocols (for example I have given the link to the Norm that describes PTP). Thank you anyways, at least the code is cleaner now and maybe I can find the problem. – Dominik Feb 05 '17 at 13:54