1

I'd like to port a Linux C program to Java. This program controls a camera which is connected to the PC with a USB cable. The C code uses Linux SCSI Generic (sg).

Sample code from the C program:

#include <linux/../scsi/sg.h>

...

static int scsi_write(int sg_fd, uint8_t *cmd, uint32_t cmdLen,
               uint8_t *buf, uint32_t bufLen) {

    sg_io_hdr_t io;
    int r;

    memset(&io, 0, sizeof(io));

    io.interface_id = 'S';
    io.cmd_len = cmdLen;

    ...        
    r = ioctl(sg_fd, SG_IO, &io);
    ...
}

Is there a way to port this program to Java? I was searching for a cross-platform SCSI library written for Java, but found none. I was also searching for a JNI over SCSI/sg, also no luck.

asalamon74
  • 6,120
  • 9
  • 46
  • 60
  • Are you looking to implement it on Linux, or specifically cross-platform? – Mark Snidovich Dec 21 '10 at 09:14
  • 2
    Why would you want to port that to Java? I don't see any gain in porting that kind of hardware-dependent code to Java. Maybe you'd want to wrap the HW-access in a C library and invoke that from Java via JNI. That way you could (for example) write the GUI in Java and still use your working and tested C code for the HW access. – Joachim Sauer Dec 21 '10 at 09:24
  • Cross-platform would be better of course. – asalamon74 Dec 21 '10 at 09:33
  • @Joachim: He wants to access a USB device using Java. Why is that more "hardware-depentent" than anything else commonly done with Java, like accessing the keyboard, mouse, network, display, printers etc? – jarnbjo Dec 21 '10 at 09:35
  • 1
    why porting: If it's not possible I won't port it. I just wanted to know if it's possible. Maybe someone else already tried to port a similar code and can give me a few hints. – asalamon74 Dec 21 '10 at 09:38
  • @jarnbjo: because keyboards, mice, network cards, displays and printers have all got abstractions in the Java platform (and in most OS), that allow some kind of hardware-independent interaction with those. Using SCSI-level APIs is by definition hardware-dependent. – Joachim Sauer Dec 21 '10 at 13:11

3 Answers3

3

While Java supports a lot of the POSIX API, the ioctl system call is not part of what it does. What you'll need to do is to use JNI to allow Java to call a function such as the scsi_write you wrote in the question. The extra cost of using more shims is minimal given that you're talking about interfacing to external hardware anyway. The cmd and buf arguments map naturally to Java byte arrays (and since Java's arrays know their length, you won't model the cmdLen and bufLen arguments at the Java level at all).

Donal Fellows
  • 133,037
  • 18
  • 149
  • 215
  • And no, stuff using `ioctl` is only very rarely portable. It's a syscall for passing information directly to the driver or device, and that's never going to be a highly portable thing. – Donal Fellows Dec 21 '10 at 09:22
2

You may have more luck with a Java based USB library, like an implementation of JSR080 (javax.usb). You can find the reference implementation here, but only the Linux implementation is kind of production ready.

Lucas
  • 661
  • 1
  • 10
  • 22
jarnbjo
  • 33,923
  • 7
  • 70
  • 94
0

Please try IOCTL, you may want to have a look at sg3_utils source code to learn how to send SCSI PDU by ioctl, it's C code, but PDU and ioctl are the same. Then you know you can control the camera.

Diors
  • 1