Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fails on Apple Silicon #142

Open
bobjacobsen opened this issue Jun 28, 2023 · 6 comments
Open

Fails on Apple Silicon #142

bobjacobsen opened this issue Jun 28, 2023 · 6 comments

Comments

@bobjacobsen
Copy link

JMRI is an application that works cross-platform with PureJavaComm just fine across multiple platforms, including macOS Intel and macOS Rosetta2 on Apple Silicon.

When running on Apple Silicon, attempting to set a control line on a port gives:

     [java] purejavacomm.PureJavaIllegalStateException: ioctl(m_FD, TIOCMGET, m_ioctl) == -1
     [java] 	at purejavacomm.PureJavaSerialPort.setControlLineState(PureJavaSerialPort.java:1277)
     [java] 	at purejavacomm.PureJavaSerialPort.setRTS(PureJavaSerialPort.java:313)
     [java] 	at jmri.jmrix.AbstractSerialPortController.configureLeadsAndFlowControl(AbstractSerialPortController.java:121)
     [java] 	at jmri.jmrix.AbstractSerialPortController.configureLeadsAndFlowControl(AbstractSerialPortController.java:142)

The JMRI code line where it occurs:

        serialPort.setRTS(rts);

The port seems to have been successfully opened. At least, there was no exception at that point.

If I bypass setting the control lines, I get an I/O exception the first time I attempt to access the port's input stream:

     [java] java.io.IOException
     [java] 	at purejavacomm.PureJavaSerialPort$2.available(PureJavaSerialPort.java:721)
     [java] 	at jmri.jmrix.AbstractPortController.purgeStream(AbstractPortController.java:566)

Happens with Azul JDKs from Java 11 (earliest supported by application) through JDK 20. Observed on macOS Ventura with both M1 and M2 chips.

Working on debugging this, but would greatly appreciate any suggestions on how to go about it.

@nyholku
Copy link
Owner

nyholku commented Jun 28, 2023 via email

@bobjacobsen
Copy link
Author

Thank you for the quick reply!

This is the minimal test program I'm using:

import purejavacomm.*;
import java.io.*;

class JavaCommTest {

    static String portName = "cu.Bluetooth-Incoming-Port";
    // static String portName = "cu.usbmodem2100412E1";

    public static void main(String[] args) {
        System.out.println("starting");

        SerialPort activeSerialPort = null;

        try {
            // get and open the primary port
            CommPortIdentifier portID = CommPortIdentifier.getPortIdentifier(portName);
            try {
                activeSerialPort = (SerialPort) portID.open("JMRI", 2000);  // name of program, msec to wait
            } catch (PortInUseException p) {
                System.err.println("PortInUseException");
            }

            // These operations pass
            try {
                activeSerialPort.setSerialPortParams(9600, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
            } catch (UnsupportedCommOperationException e) {
                System.err.println("Setting serial params failed");
            }

            // These operations fail
            activeSerialPort.setRTS(true);
            activeSerialPort.setDTR(true);

        } catch (NoSuchPortException e1) {
            System.err.println("NoSuchPortException "+e1);
            e1.printStackTrace();
        } catch (RuntimeException e2) {
            System.err.println("RuntimeException "+e2);
            e2.printStackTrace();
        }

        System.out.println("ending");
    }
}

It gives:

starting
ending
RuntimeException purejavacomm.PureJavaIllegalStateException: ioctl(m_FD, TIOCMGET, m_ioctl) == -1
purejavacomm.PureJavaIllegalStateException: ioctl(m_FD, TIOCMGET, m_ioctl) == -1
	at purejavacomm.PureJavaSerialPort.setControlLineState(PureJavaSerialPort.java:1277)
	at purejavacomm.PureJavaSerialPort.setRTS(PureJavaSerialPort.java:313)
	at JavaCommTest.main(JavaCommTest.java:31)

Thanks again.

@bobjacobsen
Copy link
Author

Using com.sun.jna.Native.getLastError() I find that the errno is 14:

 14 EFAULT Bad address. The system detected an invalid address in attempting to use an argument of a call.

@nyholku
Copy link
Owner

nyholku commented Jun 28, 2023 via email

@bobjacobsen
Copy link
Author

See a possible solution descend on the JNA list. There's an odd dependence on debugging output, unfortunately.

@nyholku
Copy link
Owner

nyholku commented Jul 2, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants