NeuronRobotics / nrjavaserial

A Java Serial Port system. This is a fork of the RXTX project that uses in jar loading of the native code.
Other
345 stars 143 forks source link

linux64: "check_line_status_register: TIOCSERGETLSR is nonnull" always triggers so nothing is read #148

Open dosidw opened 4 years ago

dosidw commented 4 years ago

Hi

we have a legacy application that used javax.comm. I am now trying to use nrjavaserial. It works on Windows as far as tested but I have problems on 64 bit Linux.

I try to connect a barcode scanner over usb-com. 'cat' on the device works and all seems fine.

It uses SerialPortEventListener but serialEvent() is never called.

[1451411.639775] usb 1-3: new full-speed USB device number 51 using xhci_hcd
[1451411.789659] usb 1-3: New USB device found, idVendor=05f9, idProduct=4204
[1451411.789664] usb 1-3: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[1451411.789667] usb 1-3: Product: Handheld Barcode Scanner
[1451411.789670] usb 1-3: Manufacturer: Datalogic ADC, Inc.
[1451411.789672] usb 1-3: SerialNumber: S/N G17C18943
[1451411.791390] cdc_acm 1-3:1.0: ttyACM0: USB ACM device

I have other scanners and the same happens.

The select comes back but then in check_line_status_register() the if( ioctl( eis->fd, TIOCSERGETLSR, &eis->change ) ) triggers.

If I comment out that if then it works but I assume it will then send many empty messages.

EDIT: if I activate the commented line: if( eis->has_tiocsergetlsr ) in report_serial_events() it works. Is this the correct solution? Can it be a problem with permissions or stty settings that the ioctl( eis->fd, TIOCSERGETLSR, &eis->change ) stuff does not work? Or is it to be expected even on a modern Linux?

I tried many different settings per stty, but maybe I did just not find the right one? Also per Google I found out that Windows and Linux usb-com drivers assume a different initial state. Maybe the initialization sequence that is used is only OK for Windows?

Does somebody have an idea what I could try?

The init sequence is more or less:

serialPort = (SerialPort) portId.open("SerialWrite", 10000);
outputStream = serialPort.getOutputStream();
inputStream = serialPort.getInputStream();
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
if (notify) {
    serialPort.notifyOnCTS(true);
    serialPort.notifyOnDSR(true);
}
serialPort.notifyOnOutputEmpty(true);

serialPort.setFlowControlMode(SerialPort.FLOWCONTROL_NONE);
serialPort.setSerialPortParams(speed, dataBits, stopBits, paraty);
serialPort.setDTR(false);
serialPort.setRTS(false);
madhephaestus commented 4 years ago

please test 3.19.0?

dosidw commented 4 years ago

I tried 3.20.1. It does not work.

As already written, this part in SerialImp.c seems to be the problem. If I activate the if( eis->has_tiocsergetlsr ) line it works:

    /* JK00: work around for Multi IO cards without TIOCSERGETLSR */
    /* if( eis->has_tiocsergetlsr ) we have a fix for output empty */
        if( check_line_status_register( eis ) )
            return;

So the question is what "JK00: work around for Multi IO cards without TIOCSERGETLSR" means. I have no idea about this stuff, but when I look at that then maybe the commented code is actually the fix for that issue (since it seems checks if the feature is available). If we do not have TIOCSERGETLSR we should not call check_line_status_register( eis )?

So then the question is why this check was/is commented out.

madhephaestus commented 4 years ago

this code comes from before my time unfortunately...

Can you submit a PR with the change you made? I will pull it locally and make binaries for you to try. Could you test the binaries after i make them on Windows and Linux?