JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configEventFlags(JNIEnv *env, jobject obj, jlong serialPortFD) { if (serialPortFD <= 0) return JNI_FALSE; // Get event flags from Java class int baudRate = (*env)->GetIntField(env, obj, baudRateField); unsigned int baudRateCode = getBaudRateCode(baudRate); int eventsToMonitor = (*env)->GetIntField(env, obj, eventFlagsField); // Change read timeouts if we are monitoring data received jboolean retVal; if ((eventsToMonitor & com_fazecast_jSerialComm_SerialPort_LISTENING_EVENT_DATA_RECEIVED) > 0) { struct termios options = { 0 }; ioctl(serialPortFD, TCGETS, &options); int flags = fcntl(serialPortFD, F_GETFL); if (flags == -1) return JNI_FALSE; flags &= ~O_NONBLOCK; options.c_cc[VMIN] = 0; options.c_cc[VTIME] = 10; retVal = ((fcntl(serialPortFD, F_SETFL, flags) == -1) || (ioctl(serialPortFD, TCSETS, &options) == -1)) ? JNI_FALSE : JNI_TRUE; if (baudRateCode == 0) // Set custom baud rate setBaudRate(serialPortFD, baudRate); } else retVal = Java_com_fazecast_jSerialComm_SerialPort_configTimeouts(env, obj, serialPortFD); // Apply changes return retVal; }
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configFlowControl(JNIEnv *env, jobject obj, jlong serialPortFD) { if (serialPortFD <= 0) return JNI_FALSE; struct termios options = { 0 }; // Get port parameters from Java class int baudRate = (*env)->GetIntField(env, obj, baudRateField); unsigned int baudRateCode = getBaudRateCode(baudRate); int flowControl = (*env)->GetIntField(env, obj, flowControlField); tcflag_t CTSRTSEnabled = (((flowControl & com_fazecast_jSerialComm_SerialPort_FLOW_CONTROL_CTS_ENABLED) > 0) || ((flowControl & com_fazecast_jSerialComm_SerialPort_FLOW_CONTROL_RTS_ENABLED) > 0)) ? CRTSCTS : 0; tcflag_t XonXoffInEnabled = ((flowControl & com_fazecast_jSerialComm_SerialPort_FLOW_CONTROL_XONXOFF_IN_ENABLED) > 0) ? IXOFF : 0; tcflag_t XonXoffOutEnabled = ((flowControl & com_fazecast_jSerialComm_SerialPort_FLOW_CONTROL_XONXOFF_OUT_ENABLED) > 0) ? IXON : 0; // Retrieve existing port configuration if (isatty(serialPortFD)) ioctl(serialPortFD, TCGETS, &options); else return JNI_FALSE; // Set updated port parameters options.c_cflag |= CTSRTSEnabled; options.c_iflag |= XonXoffInEnabled | XonXoffOutEnabled; // Apply changes int retVal = -1; if (isatty(serialPortFD)) retVal = ioctl(serialPortFD, TCSETS, &options); else return JNI_FALSE; if (baudRateCode == 0) // Set custom baud rate setBaudRate(serialPortFD, baudRate); return ((retVal == 0) ? JNI_TRUE : JNI_FALSE); }
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configTimeouts(JNIEnv *env, jobject obj, jlong serialPortFD) { // Get port timeouts from Java class if (serialPortFD <= 0) return JNI_FALSE; int baudRate = (*env)->GetIntField(env, obj, baudRateField); unsigned int baudRateCode = getBaudRateCode(baudRate); int timeoutMode = (*env)->GetIntField(env, obj, timeoutModeField); int readTimeout = (*env)->GetIntField(env, obj, readTimeoutField); // Retrieve existing port configuration struct termios options = { 0 }; tcgetattr(serialPortFD, &options); int flags = fcntl(serialPortFD, F_GETFL); // Set updated port timeouts if (((timeoutMode & com_fazecast_jSerialComm_SerialPort_TIMEOUT_READ_SEMI_BLOCKING) > 0) && (readTimeout > 0)) // Read Semi-blocking with timeout { flags &= ~O_NONBLOCK; options.c_cc[VMIN] = 0; options.c_cc[VTIME] = readTimeout / 100; } else if ((timeoutMode & com_fazecast_jSerialComm_SerialPort_TIMEOUT_READ_SEMI_BLOCKING) > 0) // Read Semi-blocking without timeout { flags &= ~O_NONBLOCK; options.c_cc[VMIN] = 1; options.c_cc[VTIME] = 0; } else if (((timeoutMode & com_fazecast_jSerialComm_SerialPort_TIMEOUT_READ_BLOCKING) > 0) && (readTimeout > 0)) // Read Blocking with timeout { flags &= ~O_NONBLOCK; options.c_cc[VMIN] = 0; options.c_cc[VTIME] = readTimeout / 100; } else if ((timeoutMode & com_fazecast_jSerialComm_SerialPort_TIMEOUT_READ_BLOCKING) > 0) // Read Blocking without timeout { flags &= ~O_NONBLOCK; options.c_cc[VMIN] = 1; options.c_cc[VTIME] = 0; } else if ((timeoutMode & com_fazecast_jSerialComm_SerialPort_TIMEOUT_SCANNER) > 0) // Scanner Mode { flags &= ~O_NONBLOCK; options.c_cc[VMIN] = 1; options.c_cc[VTIME] = 1; } else // Non-blocking { flags |= O_NONBLOCK; options.c_cc[VMIN] = 0; options.c_cc[VTIME] = 0; } // Apply changes fcntl(serialPortFD, F_SETFL, flags); int retVal = tcsetattr(serialPortFD, TCSANOW, &options); if (baudRateCode == 0) // Set custom baud rate setBaudRate(serialPortFD, baudRate); return ((retVal == 0) ? JNI_TRUE : JNI_FALSE); }
JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(JNIEnv *env, jobject obj, jlong serialPortFD) { if (serialPortFD <= 0) return JNI_FALSE; struct termios options = { 0 }; // Get port parameters from Java class int baudRate = (*env)->GetIntField(env, obj, baudRateField); int byteSizeInt = (*env)->GetIntField(env, obj, dataBitsField); int stopBitsInt = (*env)->GetIntField(env, obj, stopBitsField); int parityInt = (*env)->GetIntField(env, obj, parityField); tcflag_t byteSize = (byteSizeInt == 5) ? CS5 : (byteSizeInt == 6) ? CS6 : (byteSizeInt == 7) ? CS7 : CS8; tcflag_t stopBits = ((stopBitsInt == com_fazecast_jSerialComm_SerialPort_ONE_STOP_BIT) || (stopBitsInt == com_fazecast_jSerialComm_SerialPort_ONE_POINT_FIVE_STOP_BITS)) ? 0 : CSTOPB; tcflag_t parity = (parityInt == com_fazecast_jSerialComm_SerialPort_NO_PARITY) ? 0 : (parityInt == com_fazecast_jSerialComm_SerialPort_ODD_PARITY) ? (PARENB | PARODD) : (parityInt == com_fazecast_jSerialComm_SerialPort_EVEN_PARITY) ? PARENB : (parityInt == com_fazecast_jSerialComm_SerialPort_MARK_PARITY) ? (PARENB | CMSPAR | PARODD) : (PARENB | CMSPAR); // Clear any serial port flags if (isatty(serialPortFD)) fcntl(serialPortFD, F_SETFL, 0); // Set raw-mode to allow the use of ioctl() if (isatty(serialPortFD)) ioctl(serialPortFD, TCGETS, &options); else return JNI_FALSE; cfmakeraw(&options); // Set updated port parameters options.c_cflag = (byteSize | stopBits | parity | CLOCAL | CREAD); if (parityInt == com_fazecast_jSerialComm_SerialPort_SPACE_PARITY) options.c_cflag &= ~PARODD; options.c_iflag &= ~(INPCK | IGNPAR | PARMRK | ISTRIP); if (byteSizeInt < 8) options.c_iflag |= ISTRIP; if (parityInt != 0) options.c_iflag |= (INPCK | IGNPAR); // Set baud rate unsigned int baudRateCode = getBaudRateCode(baudRate); if (baudRateCode != 0) { cfsetispeed(&options, baudRateCode); cfsetospeed(&options, baudRateCode); } // Apply changes int retVal = -1; if (isatty(serialPortFD)) retVal = ioctl(serialPortFD, TCSETS, &options); else return JNI_FALSE; if (baudRateCode == 0) // Set custom baud rate setBaudRate(serialPortFD, baudRate); return ((retVal == 0) ? JNI_TRUE : JNI_FALSE); }