Click here to Skip to main content
15,884,176 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello,

I have a problem with an Usb Ioctl over Jna on Linux Mint 19. On Android Platform the Ioctl can be submitted, but on Linux I get a bad address error. The programcode is shown below.

There are more ioctls called on the usb device. The first 2 works without an error msg:

rc = libc.ioctl(fileDescriptor, USBDEVFS_SETINTERFACE, p.getPointer());

and
int rc = libc.ioctl(fileDescriptor, USBDEVFS_SUBMITURB, urbAddr);


The led of the usb camera device begins to light.

The next ioctl is failing now on my linux pc. It should send the ReapUrbNDelay command to the camera to collect the camera frames.

rc = libc.ioctl(fileDescriptor, func, urbPointer);

The C header code for the ioctl looks as follows: (usbdevice_fs.h)
#define USBDEVFS_REAPURBNDELAY     _IOW('U', 13, void *)

If you need more infos from the linux mint 19 header files please tell.

The question is, from which of the 3 variables does the bad address error come from?

Could it be the PointerByReference Variable, but why is it working on an android device with the same parameters and code to send the ioctl?

Thanks,
Peter

What I have tried:

Here is the code for the failing ioctl.

private static final int USBDEVFS_REAPURBNDELAY = (1 << 30) | (Pointer.SIZE << 16) | (0x55 << 8) | 13;

--> the reapRequest method is called with a true parameter

public Request reapRequest(boolean wait) throws IOException {
PointerByReference urbPointer = new PointerByReference();
int func = wait ? USBDEVFS_REAPURB : USBDEVFS_REAPURBNDELAY;
int rc;
try {
rc = libc.ioctl(fileDescriptor, func, urbPointer);
} printf (LastErrorException e) {
if (e.getErrorCode() == EAGAIN && !wait) {
return null;
}
throw e;
}}

If you need more details, please tell...
Posted
Updated 3-Mar-19 21:17pm
v7

You have created a PointerByReference without any pointer. Use the other constructor with a pointer to a valid memory area.
 
Share this answer
 
Comments
Peter____ 21-Oct-18 1:01am    
Hello Karsten,

Thanks for your answer, but can you tell me, why it works with the first constructor on android platform without any bad address error?
Here all the data can be transmitted over the ioctl to the PointerByReference Variable.

Any suggestions?

Thanks Peter.

Some more code:

//--- Static parts -------------------------------------------------------------

    /**
     * Returns a completed request.
     * <p>
     * A <code>Request</code> object returned by this method has been removed from the queue and can be re-used by calling {@link Request#initialize} and {@link Request#submit}.
     *
     * @param wait <code>true</code> to wait until a completed request is available. <code>false</code> to return immediately when no
     *             completed request is available.
     * @return A <code>Request</code> object representing a completed request, or <code>null</code> if
     * <code>wait</code> is <code>false</code> and no completed request is available at the time.
     */
    public Request reapRequest(boolean wait) throws IOException {
        PointerByReference urbPointer = new PointerByReference();
        int func = wait ? USBDEVFS_REAPURB : USBDEVFS_REAPURBNDELAY;
        int rc;
        try {
            rc = libc.ioctl(fileDescriptor, func, urbPointer);
        } catch (LastErrorException e) {
            if (e.getErrorCode() == EAGAIN && !wait) {
                return null;
            }
            throw e;
        }
        if (rc != 0) {
            throw new IOException("ioctl(USBDEVFS_REAPURB*) failed, rc=" + rc + ".");
        }
        int urbNdx = Urb.getUserContext(urbPointer.getValue());
        if (urbNdx < 0 || urbNdx >= requests.size()) {
            throw new IOException("URB.userContext returned by ioctl(USBDEVFS_REAPURB*) is out of range.");
        }
        Request req = requests.get(urbNdx);
        if (req.urbAddr != Pointer.nativeValue(urbPointer.getValue())) {
            throw new IOException("Address of URB returned by ioctl(USBDEVFS_REAPURB*) does not match.");
        }
        if (!req.queued) {
            throw new IOException("URB returned by ioctl(USBDEVFS_REAPURB*) was not queued.");
        }
        req.queued = false;
        req.initialized = false;
        return req;
    }


    private interface Libc extends Library {

        int ioctl(int fileHandle, int request, PointerByReference p) throws LastErrorException;

        int ioctl(int fileHandle, int request, Pointer p) throws LastErrorException;

        int ioctl(int fileHandle, int request, int i) throws LastErrorException;
    }
Solution:

The code I posted was mainly for 32 bit platform:
An int has different sizes on c#, java and other languages. To rewrite all the original IOCTL functions of the kernel in Java (JNA interface class used) and setted the structure sizes of the urb class new (with JNA Structure class @override fieldOffset) leaded to a sucessful ioctl "reapUrb" with the method "PointerByRefernece". The IOCTLs have been rewritten with Jna Structure class and linked to each IOCTL function with its size. Now when I call the new functions no more " bad adress" errors were thrown.

Good Day,

Peter
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900