From 80cbf0362fa909acace0b74a4a4da533e59eabb8 Mon Sep 17 00:00:00 2001 From: hedgecrw85 Date: Tue, 25 Feb 2020 12:24:13 -0600 Subject: [PATCH] Remove Android-specific code and move to Posix codebase --- src/main/c/Android/jni/Android.mk | 13 - .../c/Android/jni/AndroidHelperFunctions.c | 322 -------- .../c/Android/jni/AndroidHelperFunctions.h | 45 -- src/main/c/Android/jni/SerialPort_Android.c | 741 ------------------ src/main/c/Posix/PosixHelperFunctions.c | 2 +- src/main/c/Posix/PosixHelperFunctions.h | 4 + src/main/c/Posix/SerialPort_Posix.c | 2 +- .../com_fazecast_jSerialComm_SerialPort.h | 0 src/main/c/Posix/jni/Android.mk | 14 + .../c/{Android => Posix}/jni/Application.mk | 0 10 files changed, 20 insertions(+), 1123 deletions(-) delete mode 100644 src/main/c/Android/jni/Android.mk delete mode 100644 src/main/c/Android/jni/AndroidHelperFunctions.c delete mode 100644 src/main/c/Android/jni/AndroidHelperFunctions.h delete mode 100644 src/main/c/Android/jni/SerialPort_Android.c rename src/main/c/{Android/jni => Posix}/com_fazecast_jSerialComm_SerialPort.h (100%) create mode 100644 src/main/c/Posix/jni/Android.mk rename src/main/c/{Android => Posix}/jni/Application.mk (100%) diff --git a/src/main/c/Android/jni/Android.mk b/src/main/c/Android/jni/Android.mk deleted file mode 100644 index afc3114..0000000 --- a/src/main/c/Android/jni/Android.mk +++ /dev/null @@ -1,13 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_MODULE := jSerialComm -LOCAL_SRC_FILES := SerialPort_Android.c AndroidHelperFunctions.c -LOCAL_LDLIBS := -llog - -include $(BUILD_SHARED_LIBRARY) - -all: - cp -rf libs/* ../../resources/Android - rm -rf libs/* libs obj diff --git a/src/main/c/Android/jni/AndroidHelperFunctions.c b/src/main/c/Android/jni/AndroidHelperFunctions.c deleted file mode 100644 index 6684f1d..0000000 --- a/src/main/c/Android/jni/AndroidHelperFunctions.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * AndroidHelperFunctions.c - * - * Created on: Mar 10, 2015 - * Last Updated on: Mar 25, 2016 - * Author: Will Hedgecock - * - * Copyright (C) 2012-2018 Fazecast, Inc. - * - * This file is part of jSerialComm. - * - * jSerialComm is free software: you can redistribute it and/or modify - * it under the terms of either the Apache Software License, version 2, or - * the GNU Lesser General Public License as published by the Free Software - * Foundation, version 3 or above. - * - * jSerialComm is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of both the GNU Lesser General Public - * License and the Apache Software License along with jSerialComm. If not, - * see and . - */ - -#ifdef __linux__ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef BOTHER -#include -#endif -#include "AndroidHelperFunctions.h" - -void push_back(struct charTupleVector* vector, const char* firstString, const char* secondString, const char* thirdString) -{ - // Allocate memory for new string storage - vector->length++; - char** newMemory = (char**)realloc(vector->first, vector->length*sizeof(char*)); - if (newMemory) - vector->first = newMemory; - newMemory = (char**)realloc(vector->second, vector->length*sizeof(char*)); - if (newMemory) - vector->second = newMemory; - newMemory = (char**)realloc(vector->third, vector->length*sizeof(char*)); - if (newMemory) - vector->third = newMemory; - - // Store new strings - vector->first[vector->length-1] = (char*)malloc(strlen(firstString)+1); - vector->second[vector->length-1] = (char*)malloc(strlen(secondString)+1); - vector->third[vector->length-1] = (char*)malloc(strlen(thirdString)+1); - strcpy(vector->first[vector->length-1], firstString); - strcpy(vector->second[vector->length-1], secondString); - strcpy(vector->third[vector->length-1], thirdString); -} - -char keyExists(struct charTupleVector* vector, const char* key) -{ - size_t i; - for (i = 0; i < vector->length; ++i) - if (strcmp(key, vector->first[i]) == 0) - return 1; - return 0; -} - -void getFriendlyName(const char* productFile, char* friendlyName) -{ - int friendlyNameLength = 0; - friendlyName[0] = '\0'; - - FILE *input = fopen(productFile, "rb"); - if (input) - { - char ch = getc(input); - while ((ch != '\n') && ((int)ch != EOF)) - { - friendlyName[friendlyNameLength++] = ch; - ch = getc(input); - } - friendlyName[friendlyNameLength] = '\0'; - fclose(input); - } -} - -void getDriverName(const char* directoryToSearch, char* friendlyName) -{ - friendlyName[0] = '\0'; - - // Open the directory - DIR *directoryIterator = opendir(directoryToSearch); - if (!directoryIterator) - return; - - // Read all sub-directories in the current directory - struct dirent *directoryEntry = readdir(directoryIterator); - while (directoryEntry) - { - // Check if entry is a valid sub-directory - if (directoryEntry->d_name[0] != '.') - { - // Get the readable part of the driver name - strcpy(friendlyName, "USB-to-Serial Port ("); - char *startingPoint = strchr(directoryEntry->d_name, ':'); - if (startingPoint != NULL) - strcat(friendlyName, startingPoint+1); - else - strcat(friendlyName, directoryEntry->d_name); - strcat(friendlyName, ")"); - break; - } - directoryEntry = readdir(directoryIterator); - } - - // Close the directory - closedir(directoryIterator); -} - -void recursiveSearchForComPorts(charTupleVector* comPorts, const char* fullPathToSearch) -{ - // Open the directory - DIR *directoryIterator = opendir(fullPathToSearch); - if (!directoryIterator) - return; - - // Read all sub-directories in the current directory - struct dirent *directoryEntry = readdir(directoryIterator); - while (directoryEntry) - { - // Check if entry is a sub-directory - if (directoryEntry->d_type == DT_DIR) - { - // Only process non-dot, non-virtual directories - if ((directoryEntry->d_name[0] != '.') && (strcmp(directoryEntry->d_name, "virtual") != 0)) - { - // See if the directory names a potential serial port - if ((strlen(directoryEntry->d_name) > 3) && (directoryEntry->d_name[0] == 't') && (directoryEntry->d_name[1] == 't') && (directoryEntry->d_name[2] == 'y')) - { - // Determine system name of port - char* systemName = (char*)malloc(256); - strcpy(systemName, "/dev/"); - strcat(systemName, directoryEntry->d_name); - - // See if device has a registered friendly name - char* friendlyName = (char*)malloc(256); - char* productFile = (char*)malloc(strlen(fullPathToSearch) + strlen(directoryEntry->d_name) + 30); - strcpy(productFile, fullPathToSearch); - strcat(productFile, directoryEntry->d_name); - strcat(productFile, "/device/../product"); - getFriendlyName(productFile, friendlyName); - if (friendlyName[0] == '\0') - { - // Get friendly name based on the driver loaded - strcpy(productFile, fullPathToSearch); - strcat(productFile, directoryEntry->d_name); - strcat(productFile, "/driver/module/drivers"); - getDriverName(productFile, friendlyName); - if (friendlyName[0] != '\0') - push_back(comPorts, systemName, friendlyName, friendlyName); - } - else - push_back(comPorts, systemName, friendlyName, friendlyName); - - // Clean up memory - free(productFile); - free(systemName); - free(friendlyName); - } - else - { - // Search for more serial ports within the directory - charTupleVector newComPorts = { (char**)malloc(1), (char**)malloc(1), (char**)malloc(1), 0 }; - char* nextDirectory = (char*)malloc(strlen(fullPathToSearch) + strlen(directoryEntry->d_name) + 5); - strcpy(nextDirectory, fullPathToSearch); - strcat(nextDirectory, directoryEntry->d_name); - strcat(nextDirectory, "/"); - recursiveSearchForComPorts(&newComPorts, nextDirectory); - free(nextDirectory); - int i; - for (i = 0; i < newComPorts.length; ++i) - { - push_back(comPorts, newComPorts.first[i], newComPorts.second[i], newComPorts.third[i]); - free(newComPorts.first[i]); - free(newComPorts.second[i]); - free(newComPorts.third[i]); - } - free(newComPorts.first); - free(newComPorts.second); - free(newComPorts.third); - } - } - } - directoryEntry = readdir(directoryIterator); - } - - // Close the directory - closedir(directoryIterator); -} - -unsigned int getBaudRateCode(int baudRate) -{ - switch (baudRate) - { - case 50: - return B50; - case 75: - return B75; - case 110: - return B110; - case 134: - return B134; - case 150: - return B150; - case 200: - return B200; - case 300: - return B300; - case 600: - return B600; - case 1200: - return B1200; - case 1800: - return B1800; - case 2400: - return B2400; - case 4800: - return B4800; - case 9600: - return B9600; - case 19200: - return B19200; - case 38400: - return B38400; - case 57600: - return B57600; - case 115200: - return B115200; - case 230400: - return B230400; - case 460800: - return B460800; - case 500000: - return B500000; - case 576000: - return B576000; - case 921600: - return B921600; - default: - return 0; - } - - return 0; -} - -void setBaudRate(int portFD, int baudRate) -{ -#ifdef BOTHER - struct termios2 options = { 0 }; - - if (isatty(portFD)) - ioctl(portFD, TCGETS2, &options); - else - return; -// { -// struct usbdevfs_ioctl requestWrapper; -// requestWrapper.ifno = 1;// TODO -// requestWrapper.ioctl_code = TCGETS2; -// requestWrapper.data = &options; -// ioctl(portFD, USBDEVFS_IOCTL, &requestWrapper); -// } - options.c_cflag &= ~CBAUD; - options.c_cflag |= BOTHER; - options.c_ispeed = baudRate; - options.c_ospeed = baudRate; - if (isatty(portFD)) - ioctl(portFD, TCSETS2, &options); - else - return; -// { -// struct usbdevfs_ioctl requestWrapper; -// requestWrapper.ifno = 1;// TODO -// requestWrapper.ioctl_code = TCSETS2; -// requestWrapper.data = &options; -// ioctl(portFD, USBDEVFS_IOCTL, &requestWrapper); -// } -#else - struct termios options = { 0 }; - if (isatty(portFD)) - ioctl(portFD, TCGETS, &options); - else - return; -// { -// struct usbdevfs_ioctl requestWrapper; -// requestWrapper.ifno = 1;// TODO -// requestWrapper.ioctl_code = TCGETS; -// requestWrapper.data = &options; -// ioctl(portFD, USBDEVFS_IOCTL, &requestWrapper); -// } - options.c_cflag = (options.c_cflag & ~CBAUD) | (B38400 & CBAUD); - if (isatty(portFD)) - ioctl(portFD, TCSETS, &options); - else - return; -// { -// struct usbdevfs_ioctl requestWrapper; -// requestWrapper.ifno = 1;// TODO -// requestWrapper.ioctl_code = TCSETS; -// requestWrapper.data = &options; -// ioctl(portFD, USBDEVFS_IOCTL, &requestWrapper); -// } -#endif -} - -#endif diff --git a/src/main/c/Android/jni/AndroidHelperFunctions.h b/src/main/c/Android/jni/AndroidHelperFunctions.h deleted file mode 100644 index f78102e..0000000 --- a/src/main/c/Android/jni/AndroidHelperFunctions.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * AndroidHelperFunctions.h - * - * Created on: Mar 10, 2015 - * Last Updated on: Mar 25, 2016 - * Author: Will Hedgecock - * - * Copyright (C) 2012-2018 Fazecast, Inc. - * - * This file is part of jSerialComm. - * - * jSerialComm is free software: you can redistribute it and/or modify - * it under the terms of either the Apache Software License, version 2, or - * the GNU Lesser General Public License as published by the Free Software - * Foundation, version 3 or above. - * - * jSerialComm is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of both the GNU Lesser General Public - * License and the Apache Software License along with jSerialComm. If not, - * see and . - */ - -#ifndef __ANDROID_HELPER_FUNCTIONS_HEADER_H__ -#define __ANDROID_HELPER_FUNCTIONS_HEADER_H__ - -typedef struct charTupleVector -{ - char **first, **second, **third; - size_t length; -} charTupleVector; -void push_back(struct charTupleVector* vector, const char* firstString, const char* secondString, const char* thirdString); -char keyExists(struct charTupleVector* vector, const char* key); - -void getDriverName(const char* directoryToSearch, char* friendlyName); -void recursiveSearchForComPorts(charTupleVector* comPorts, const char* fullPathToSearch); -void getFriendlyName(const char* productFile, char* friendlyName); -unsigned int getBaudRateCode(int baudRate); -void setBaudRate(int portFD, int baudRate); - -extern int ioctl(int __fd, int __request, ...); - -#endif // #ifndef __ANDROID_HELPER_FUNCTIONS_HEADER_H__ diff --git a/src/main/c/Android/jni/SerialPort_Android.c b/src/main/c/Android/jni/SerialPort_Android.c deleted file mode 100644 index 61fcdd0..0000000 --- a/src/main/c/Android/jni/SerialPort_Android.c +++ /dev/null @@ -1,741 +0,0 @@ -/* - * SerialPort_Android.c - * - * Created on: Mar 13, 2015 - * Last Updated on: Feb 18, 2020 - * Author: Will Hedgecock - * - * Copyright (C) 2012-2020 Fazecast, Inc. - * - * This file is part of jSerialComm. - * - * jSerialComm is free software: you can redistribute it and/or modify - * it under the terms of either the Apache Software License, version 2, or - * the GNU Lesser General Public License as published by the Free Software - * Foundation, version 3 or above. - * - * jSerialComm is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of both the GNU Lesser General Public - * License and the Apache Software License along with jSerialComm. If not, - * see and . - */ - -#ifdef __linux__ -#ifndef CMSPAR -#define CMSPAR 010000000000 -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "com_fazecast_jSerialComm_SerialPort.h" -#include "AndroidHelperFunctions.h" - -// Logging defines -#define LOG_TAG "com.fazecast.jSerialComm" -#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) - -// Cached class, method, and field IDs -jclass serialCommClass; -jmethodID serialCommConstructor; -jfieldID serialPortFdField; -jfieldID comPortField; -jfieldID friendlyNameField; -jfieldID portDescriptionField; -jfieldID eventListenerRunningField; -jfieldID disableConfigField; -jfieldID isDtrEnabledField; -jfieldID isRtsEnabledField; -jfieldID baudRateField; -jfieldID dataBitsField; -jfieldID stopBitsField; -jfieldID parityField; -jfieldID flowControlField; -jfieldID sendDeviceQueueSizeField; -jfieldID receiveDeviceQueueSizeField; -jfieldID rs485ModeField; -jfieldID rs485ActiveHighField; -jfieldID rs485DelayBeforeField; -jfieldID rs485DelayAfterField; -jfieldID timeoutModeField; -jfieldID readTimeoutField; -jfieldID writeTimeoutField; -jfieldID eventFlagsField; - -JNIEXPORT jobjectArray JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCommPorts(JNIEnv *env, jclass serialComm) -{ - // Enumerate serial ports on machine - charTupleVector serialPorts = { (char**)malloc(1), (char**)malloc(1), (char**)malloc(1), 0 }; - recursiveSearchForComPorts(&serialPorts, "/sys/devices/"); - jobjectArray arrayObject = (*env)->NewObjectArray(env, serialPorts.length, serialCommClass, 0); - int i; - for (i = 0; i < serialPorts.length; ++i) - { - // Create new SerialComm object containing the enumerated values - jobject serialCommObject = (*env)->NewObject(env, serialCommClass, serialCommConstructor); - (*env)->SetObjectField(env, serialCommObject, portDescriptionField, (*env)->NewStringUTF(env, serialPorts.third[i])); - (*env)->SetObjectField(env, serialCommObject, friendlyNameField, (*env)->NewStringUTF(env, serialPorts.second[i])); - (*env)->SetObjectField(env, serialCommObject, comPortField, (*env)->NewStringUTF(env, serialPorts.first[i])); - free(serialPorts.first[i]); - free(serialPorts.second[i]); - free(serialPorts.third[i]); - - // Add new SerialComm object to array - (*env)->SetObjectArrayElement(env, arrayObject, i, serialCommObject); - } - free(serialPorts.first); - free(serialPorts.second); - free(serialPorts.third); - - return arrayObject; -} - -JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_initializeLibrary(JNIEnv *env, jclass serialComm) -{ - // Cache class and method ID as global references - serialCommClass = (jclass)(*env)->NewGlobalRef(env, serialComm); - serialCommConstructor = (*env)->GetMethodID(env, serialCommClass, "", "()V"); - - // Cache - serialPortFdField = (*env)->GetFieldID(env, serialCommClass, "portHandle", "J"); - comPortField = (*env)->GetFieldID(env, serialCommClass, "comPort", "Ljava/lang/String;"); - friendlyNameField = (*env)->GetFieldID(env, serialCommClass, "friendlyName", "Ljava/lang/String;"); - portDescriptionField = (*env)->GetFieldID(env, serialCommClass, "portDescription", "Ljava/lang/String;"); - eventListenerRunningField = (*env)->GetFieldID(env, serialCommClass, "eventListenerRunning", "Z"); - disableConfigField = (*env)->GetFieldID(env, serialCommClass, "disableConfig", "Z"); - isDtrEnabledField = (*env)->GetFieldID(env, serialCommClass, "isDtrEnabled", "Z"); - isRtsEnabledField = (*env)->GetFieldID(env, serialCommClass, "isRtsEnabled", "Z"); - baudRateField = (*env)->GetFieldID(env, serialCommClass, "baudRate", "I"); - dataBitsField = (*env)->GetFieldID(env, serialCommClass, "dataBits", "I"); - stopBitsField = (*env)->GetFieldID(env, serialCommClass, "stopBits", "I"); - parityField = (*env)->GetFieldID(env, serialCommClass, "parity", "I"); - flowControlField = (*env)->GetFieldID(env, serialCommClass, "flowControl", "I"); - sendDeviceQueueSizeField = (*env)->GetFieldID(env, serialCommClass, "sendDeviceQueueSize", "I"); - receiveDeviceQueueSizeField = (*env)->GetFieldID(env, serialCommClass, "receiveDeviceQueueSize", "I"); - rs485ModeField = (*env)->GetFieldID(env, serialCommClass, "rs485Mode", "Z"); - rs485ActiveHighField = (*env)->GetFieldID(env, serialCommClass, "rs485ActiveHigh", "Z"); - rs485DelayBeforeField = (*env)->GetFieldID(env, serialCommClass, "rs485DelayBefore", "I"); - rs485DelayAfterField = (*env)->GetFieldID(env, serialCommClass, "rs485DelayAfter", "I"); - timeoutModeField = (*env)->GetFieldID(env, serialCommClass, "timeoutMode", "I"); - readTimeoutField = (*env)->GetFieldID(env, serialCommClass, "readTimeout", "I"); - writeTimeoutField = (*env)->GetFieldID(env, serialCommClass, "writeTimeout", "I"); - eventFlagsField = (*env)->GetFieldID(env, serialCommClass, "eventFlags", "I"); -} - -JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_uninitializeLibrary(JNIEnv *env, jclass serialComm) -{ - // Delete the cached global reference - (*env)->DeleteGlobalRef(env, serialCommClass); -} - -JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(JNIEnv *env, jobject obj) -{ - // TODO: SET A FLAG SAYING THAT WE ARE NOT USING USBFS - jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField); - const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL); - unsigned char isDtrEnabled = (*env)->GetBooleanField(env, obj, isDtrEnabledField); - unsigned char isRtsEnabled = (*env)->GetBooleanField(env, obj, isRtsEnabledField); - - // Try to open existing serial port with read/write access - int serialPortFD = -1; - if ((serialPortFD = open(portName, O_RDWR | O_NOCTTY | O_NONBLOCK)) > 0) - { - // Clear any serial port flags and set up raw, non-canonical port parameters - if (isatty(serialPortFD)) - { - struct termios options = {0}; - fcntl(serialPortFD, F_SETFL, 0); - ioctl(serialPortFD, TCGETS, &options); - options.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON); - options.c_oflag &= ~OPOST; - options.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN); - options.c_cflag &= ~(CSIZE | PARENB); - options.c_cflag |= CS8; - if (!isDtrEnabled || !isRtsEnabled) - options.c_cflag &= ~HUPCL; - options.c_iflag |= BRKINT; - ioctl(serialPortFD, TCSETS, &options); - } - - // Configure the port parameters and timeouts - if (Java_com_fazecast_jSerialComm_SerialPort_configPort(env, obj, serialPortFD)) - (*env)->SetLongField(env, obj, serialPortHandleField, serialPortFD); - else - { - // Close the port if there was a problem setting the parameters - tcdrain(serialPortFD); - while ((close(serialPortFD) == -1) && (errno != EBADF)); - serialPortFD = -1; - } - } - - (*env)->ReleaseStringUTFChars(env, portNameJString, portName); - return serialPortFD; -} - -JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_configPort(JNIEnv *env, jobject obj, jlong serialPortFD) -{ - if (serialPortFD <= 0) - return JNI_FALSE; - struct serial_struct serInfo = {0}; - 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); - int flowControl = (*env)->GetIntField(env, obj, flowControlField); - int sendDeviceQueueSize = (*env)->GetIntField(env, obj, sendDeviceQueueSizeField); - int receiveDeviceQueueSize = (*env)->GetIntField(env, obj, receiveDeviceQueueSizeField); - int rs485DelayBefore = (*env)->GetIntField(env, obj, rs485DelayBeforeField); - int rs485DelayAfter = (*env)->GetIntField(env, obj, rs485DelayAfterField); - unsigned char configDisabled = (*env)->GetBooleanField(env, obj, disableConfigField); - unsigned char rs485ModeEnabled = (*env)->GetBooleanField(env, obj, rs485ModeField); - unsigned char rs485ActiveHigh = (*env)->GetBooleanField(env, obj, rs485ActiveHighField); - unsigned char isDtrEnabled = (*env)->GetBooleanField(env, obj, isDtrEnabledField); - unsigned char isRtsEnabled = (*env)->GetBooleanField(env, obj, isRtsEnabledField); - 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); - 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; - - // Set updated port parameters - if (isatty(serialPortFD)) - { - ioctl(serialPortFD, TCGETS, &options); - options.c_cflag = (byteSize | stopBits | parity | CLOCAL | CREAD | CTSRTSEnabled); - if (parityInt == com_fazecast_jSerialComm_SerialPort_SPACE_PARITY) - options.c_cflag &= ~PARODD; - if (!isDtrEnabled || !isRtsEnabled) - options.c_cflag &= ~HUPCL; - options.c_iflag &= ~(INPCK | IGNPAR | PARMRK | ISTRIP); - if (byteSizeInt < 8) - options.c_iflag |= ISTRIP; - if (parityInt != 0) - options.c_iflag |= (INPCK | IGNPAR); - options.c_iflag |= (XonXoffInEnabled | XonXoffOutEnabled); - } - else - return JNI_FALSE;/* - { - struct usbdevfs_ioctl requestWrapper; - requestWrapper.ifno = 1;// TODO - requestWrapper.ioctl_code = TCGETS; - requestWrapper.data = &options; - ioctl(serialPortFD, USBDEVFS_IOCTL, &requestWrapper); - }*/ - - // Set baud rate - unsigned int baudRateCode = getBaudRateCode(baudRate); - if (baudRateCode != 0) - options.c_cflag = (options.c_cflag & ~CBAUD) | (baudRateCode & CBAUD); - - // Apply changes - int retVal = -1; - if (isatty(serialPortFD)) - retVal = configDisabled ? 0 : ioctl(serialPortFD, TCSETS, &options); - else - return JNI_FALSE;/* - { - struct usbdevfs_ioctl requestWrapper; - requestWrapper.ifno = 1;// TODO - requestWrapper.ioctl_code = TCSETS; - requestWrapper.data = &options; - retVal = ioctl(serialPortFD, USBDEVFS_IOCTL, &requestWrapper); - }*/ - - // Attempt to set the transmit buffer size and any necessary custom baud rates - (*env)->SetIntField(env, obj, receiveDeviceQueueSizeField, sysconf(_SC_PAGESIZE)); - ioctl(serialPortFD, TIOCGSERIAL, &serInfo); - serInfo.xmit_fifo_size = sendDeviceQueueSize; - ioctl(serialPortFD, TIOCSSERIAL, &serInfo); - if (baudRateCode == 0) - setBaudRate(serialPortFD, baudRate); - - // Attempt to set the requested RS-485 mode - struct serial_rs485 rs485Conf = {0}; - if (ioctl(serialPortFD, TIOCGRS485, &rs485Conf) == 0) - { - if (rs485ModeEnabled) - rs485Conf.flags |= SER_RS485_ENABLED; - else - rs485Conf.flags &= ~SER_RS485_ENABLED; - if (rs485ActiveHigh) - { - rs485Conf.flags |= SER_RS485_RTS_ON_SEND; - rs485Conf.flags &= ~(SER_RS485_RTS_AFTER_SEND); - } - else - { - rs485Conf.flags &= ~(SER_RS485_RTS_ON_SEND); - rs485Conf.flags |= SER_RS485_RTS_AFTER_SEND; - } - rs485Conf.delay_rts_before_send = rs485DelayBefore; - rs485Conf.delay_rts_after_send = rs485DelayAfter; - ioctl(serialPortFD, TIOCSRS485, &rs485Conf); - } - return ((retVal == 0) && Java_com_fazecast_jSerialComm_SerialPort_configEventFlags(env, obj, serialPortFD) ? 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}; - if (isatty(serialPortFD)) - ioctl(serialPortFD, TCGETS, &options); - else - return JNI_FALSE;/* - { - struct usbdevfs_ioctl requestWrapper; - requestWrapper.ifno = 1;// TODO - requestWrapper.ioctl_code = TCGETS; - requestWrapper.data = &options; - if (ioctl(serialPortFD, USBDEVFS_IOCTL, &requestWrapper) < 0) - LOGD("ERROR GETTING tcgetattr PORT SETTINGS = %d\n", errno); - }*/ - int flags = fcntl(serialPortFD, F_GETFL); - if (flags == -1) - return JNI_FALSE; - - // 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 - int retVal = fcntl(serialPortFD, F_SETFL, flags); - if (retVal != -1) - { - if (isatty(serialPortFD)) - retVal = ioctl(serialPortFD, TCSETS, &options); - else - return JNI_FALSE;/* - { - struct usbdevfs_ioctl requestWrapper; - requestWrapper.ifno = 1;// TODO - requestWrapper.ioctl_code = TCSETS; - requestWrapper.data = &options; - if (ioctl(serialPortFD, USBDEVFS_IOCTL, &requestWrapper) < 0) - LOGD("ERROR SETTING ioctl PORT SETTINGS = %d\n", errno); - }*/ - } - 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_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 jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_waitForEvent(JNIEnv *env, jobject obj, jlong serialPortFD) -{ - // Initialize the waiting set - if (serialPortFD <= 0) - return 0; - struct pollfd waitingSet = { serialPortFD, POLLIN, 0 }; - - // Wait for a serial port event - if (poll(&waitingSet, 1, 1000) <= 0) - return 0; - return (waitingSet.revents & POLLIN) ? com_fazecast_jSerialComm_SerialPort_LISTENING_EVENT_DATA_AVAILABLE : 0; -} - -JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_closePortNative(JNIEnv *env, jobject obj, jlong serialPortFD) -{ - // Ensure that the port is open - if (serialPortFD <= 0) - return JNI_TRUE; - - // Force the port to enter non-blocking mode to ensure that any current reads return - struct termios options = {0}; - ioctl(serialPortFD, TCGETS, &options); - int flags = fcntl(serialPortFD, F_GETFL); - flags |= O_NONBLOCK; - options.c_cc[VMIN] = 0; - options.c_cc[VTIME] = 0; - int retVal = fcntl(serialPortFD, F_SETFL, flags); - ioctl(serialPortFD, TCSETS, &options); - - // Close the port - while ((close(serialPortFD) == -1) && (errno != EBADF)); - (*env)->SetLongField(env, obj, serialPortFdField, -1l); - return JNI_TRUE; -} - -JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_bytesAvailable(JNIEnv *env, jobject obj, jlong serialPortFD) -{ - int numBytesAvailable = -1; - if ((serialPortFD > 0) && (ioctl(serialPortFD, FIONREAD, &numBytesAvailable) == -1)) - { - // Problem detected, close the port - tcdrain(serialPortFD); - while ((close(serialPortFD) == -1) && (errno != EBADF)); - (*env)->SetLongField(env, obj, serialPortFdField, -1l); - } - - return numBytesAvailable; -} - -JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_bytesAwaitingWrite(JNIEnv *env, jobject obj, jlong serialPortFD) -{ - int numBytesToWrite = -1; - if (serialPortFD > 0) - ioctl(serialPortFD, TIOCOUTQ, &numBytesToWrite); - - return numBytesToWrite; -} - -JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv *env, jobject obj, jlong serialPortFD, jbyteArray buffer, jlong bytesToRead, jlong offset) -{ - // Get port handle and read timeout from Java class - if (serialPortFD <= 0) - return -1; - int timeoutMode = (*env)->GetIntField(env, obj, timeoutModeField); - int readTimeout = (*env)->GetIntField(env, obj, readTimeoutField); - int numBytesRead, numBytesReadTotal = 0, bytesRemaining = bytesToRead, ioctlResult = 0; - char* readBuffer = (char*)malloc(bytesToRead); - - // Infinite blocking mode specified, don't return until we have completely finished the read - if (((timeoutMode & com_fazecast_jSerialComm_SerialPort_TIMEOUT_READ_BLOCKING) > 0) && (readTimeout == 0)) - { - // While there are more bytes we are supposed to read - while (bytesRemaining > 0) - { - do { numBytesRead = read(serialPortFD, readBuffer+numBytesReadTotal, bytesRemaining); } while ((numBytesRead < 0) && (errno == EINTR)); - if ((numBytesRead == -1) || ((numBytesRead == 0) && (ioctl(serialPortFD, FIONREAD, &ioctlResult) == -1))) - { - // Problem reading, close port - while ((close(serialPortFD) == -1) && (errno != EBADF)); - serialPortFD = -1; - (*env)->SetLongField(env, obj, serialPortFdField, -1l); - break; - } - - // Fix index variables - numBytesReadTotal += numBytesRead; - bytesRemaining -= numBytesRead; - } - } - else if ((timeoutMode & com_fazecast_jSerialComm_SerialPort_TIMEOUT_READ_BLOCKING) > 0) // Blocking mode, but not indefinitely - { - // Get current system time - struct timeval expireTime = {0}, currTime = {0}; - gettimeofday(&expireTime, NULL); - expireTime.tv_usec += (readTimeout * 1000); - if (expireTime.tv_usec > 1000000) - { - expireTime.tv_sec += (expireTime.tv_usec * 0.000001); - expireTime.tv_usec = (expireTime.tv_usec % 1000000); - } - - // While there are more bytes we are supposed to read and the timeout has not elapsed - do - { - do { numBytesRead = read(serialPortFD, readBuffer+numBytesReadTotal, bytesRemaining); } while ((numBytesRead < 0) && (errno == EINTR)); - if ((numBytesRead == -1) || ((numBytesRead == 0) && (ioctl(serialPortFD, FIONREAD, &ioctlResult) == -1))) - { - // Problem reading, close port - while ((close(serialPortFD) == -1) && (errno != EBADF)); - serialPortFD = -1; - (*env)->SetLongField(env, obj, serialPortFdField, -1l); - break; - } - - // Fix index variables - numBytesReadTotal += numBytesRead; - bytesRemaining -= numBytesRead; - - // Get current system time - gettimeofday(&currTime, NULL); - } while ((bytesRemaining > 0) && ((expireTime.tv_sec > currTime.tv_sec) || - ((expireTime.tv_sec == currTime.tv_sec) && (expireTime.tv_usec > currTime.tv_usec)))); - } - else // Semi- or non-blocking specified - { - // Read from port - do { numBytesRead = read(serialPortFD, readBuffer, bytesToRead); } while ((numBytesRead < 0) && (errno == EINTR)); - if ((numBytesRead == -1) || ((numBytesRead == 0) && (ioctl(serialPortFD, FIONREAD, &ioctlResult) == -1))) - { - // Problem reading, close port - while ((close(serialPortFD) == -1) && (errno != EBADF)); - serialPortFD = -1; - (*env)->SetLongField(env, obj, serialPortFdField, -1l); - } - else - numBytesReadTotal = numBytesRead; - } - - // Return number of bytes read if successful - (*env)->SetByteArrayRegion(env, buffer, offset, numBytesReadTotal, (jbyte*)readBuffer); - free(readBuffer); - return (numBytesRead == -1) || (serialPortFD == -1) ? -1 : numBytesReadTotal; -} - -JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEnv *env, jobject obj, jlong serialPortFD, jbyteArray buffer, jlong bytesToWrite, jlong offset) -{ - if (serialPortFD <= 0) - return -1; - int timeoutMode = (*env)->GetIntField(env, obj, timeoutModeField); - jbyte *writeBuffer = (*env)->GetByteArrayElements(env, buffer, 0); - int numBytesWritten, ioctlResult = 0; - - // Write to port - do { numBytesWritten = write(serialPortFD, writeBuffer+offset, bytesToWrite); } while ((numBytesWritten < 0) && (errno == EINTR)); - if ((numBytesWritten == -1) || ((numBytesWritten == 0) && (ioctl(serialPortFD, FIONREAD, &ioctlResult) == -1))) - { - // Problem writing, close the port - ioctl(serialPortFD, TCSBRK, 1); - while ((close(serialPortFD) == -1) && (errno != EBADF)); - serialPortFD = -1; - (*env)->SetLongField(env, obj, serialPortFdField, -1l); - } - - // Wait until all bytes were written in write-blocking mode - if (((timeoutMode & com_fazecast_jSerialComm_SerialPort_TIMEOUT_WRITE_BLOCKING) > 0) && (serialPortFD > 0)) - ioctl(serialPortFD, TCSBRK, 1); - - // Return number of bytes written if successful - (*env)->ReleaseByteArrayElements(env, buffer, writeBuffer, JNI_ABORT); - return numBytesWritten; -} - -JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_setBreak(JNIEnv *env, jobject obj, jlong serialPortFD) -{ - if (serialPortFD <= 0) - return JNI_FALSE; - return (ioctl(serialPortFD, TIOCSBRK) == 0); -} - -JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_clearBreak(JNIEnv *env, jobject obj, jlong serialPortFD) -{ - if (serialPortFD <= 0) - return JNI_FALSE; - return (ioctl(serialPortFD, TIOCCBRK) == 0); -} - -JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_setRTS(JNIEnv *env, jobject obj, jlong serialPortFD) -{ - if (serialPortFD <= 0) - return JNI_FALSE; - int modemBits = TIOCM_RTS; - return (ioctl(serialPortFD, TIOCMBIS, &modemBits) == 0); -} - -JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_clearRTS(JNIEnv *env, jobject obj, jlong serialPortFD) -{ - if (serialPortFD <= 0) - return JNI_FALSE; - int modemBits = TIOCM_RTS; - return (ioctl(serialPortFD, TIOCMBIC, &modemBits) == 0); -} - -JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_presetRTS(JNIEnv *env, jobject obj) -{ - jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField); - const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL); - - // Send a system command to preset the RTS mode of the serial port - char commandString[128]; - sprintf(commandString, "stty -F %s hupcl >>/dev/null 2>&1", portName); - int result = system(commandString); - - (*env)->ReleaseStringUTFChars(env, portNameJString, portName); - return (result == 0); -} - -JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_preclearRTS(JNIEnv *env, jobject obj) -{ - jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField); - const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL); - - // Send a system command to preset the RTS mode of the serial port - char commandString[128]; - sprintf(commandString, "stty -F %s -hupcl >>/dev/null 2>&1", portName); - int result = system(commandString); - - (*env)->ReleaseStringUTFChars(env, portNameJString, portName); - return (result == 0); -} - -JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_setDTR(JNIEnv *env, jobject obj, jlong serialPortFD) -{ - if (serialPortFD <= 0) - return JNI_FALSE; - int modemBits = TIOCM_DTR; - return (ioctl(serialPortFD, TIOCMBIS, &modemBits) == 0); -} - -JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_clearDTR(JNIEnv *env, jobject obj, jlong serialPortFD) -{ - if (serialPortFD <= 0) - return JNI_FALSE; - int modemBits = TIOCM_DTR; - return (ioctl(serialPortFD, TIOCMBIC, &modemBits) == 0); -} - -JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_presetDTR(JNIEnv *env, jobject obj) -{ - jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField); - const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL); - - // Send a system command to preset the DTR mode of the serial port - char commandString[128]; - sprintf(commandString, "stty -F %s hupcl >>/dev/null 2>&1", portName); - int result = system(commandString); - - (*env)->ReleaseStringUTFChars(env, portNameJString, portName); - return (result == 0); -} - -JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_preclearDTR(JNIEnv *env, jobject obj) -{ - jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField); - const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL); - - // Send a system command to preset the DTR mode of the serial port - char commandString[128]; - sprintf(commandString, "stty -F %s -hupcl >>/dev/null 2>&1", portName); - int result = system(commandString); - - (*env)->ReleaseStringUTFChars(env, portNameJString, portName); - return (result == 0); -} - -JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCTS(JNIEnv *env, jobject obj, jlong serialPortFD) -{ - if (serialPortFD <= 0) - return JNI_FALSE; - int modemBits = 0; - return (ioctl(serialPortFD, TIOCMGET, &modemBits) == 0) && (modemBits & TIOCM_CTS); -} - -JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_getDSR(JNIEnv *env, jobject obj, jlong serialPortFD) -{ - if (serialPortFD <= 0) - return JNI_FALSE; - int modemBits = 0; - return (ioctl(serialPortFD, TIOCMGET, &modemBits) == 0) && (modemBits & TIOCM_DSR); -} - -JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_getDCD(JNIEnv *env, jobject obj, jlong serialPortFD) -{ - if (serialPortFD <= 0) - return JNI_FALSE; - int modemBits = 0; - return (ioctl(serialPortFD, TIOCMGET, &modemBits) == 0) && (modemBits & TIOCM_CAR); -} - -JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_getDTR(JNIEnv *env, jobject obj, jlong serialPortFD) -{ - if (serialPortFD <= 0) - return JNI_FALSE; - int modemBits = 0; - return (ioctl(serialPortFD, TIOCMGET, &modemBits) == 0) && (modemBits & TIOCM_DTR); -} - -JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_getRTS(JNIEnv *env, jobject obj, jlong serialPortFD) -{ - if (serialPortFD <= 0) - return JNI_FALSE; - int modemBits = 0; - return (ioctl(serialPortFD, TIOCMGET, &modemBits) == 0) && (modemBits & TIOCM_RTS); -} - -JNIEXPORT jboolean JNICALL Java_com_fazecast_jSerialComm_SerialPort_getRI(JNIEnv *env, jobject obj, jlong serialPortFD) -{ - if (serialPortFD <= 0) - return JNI_FALSE; - int modemBits = 0; - return (ioctl(serialPortFD, TIOCMGET, &modemBits) == 0) && (modemBits & TIOCM_RI); -} - -#endif diff --git a/src/main/c/Posix/PosixHelperFunctions.c b/src/main/c/Posix/PosixHelperFunctions.c index 8be0807..8623529 100644 --- a/src/main/c/Posix/PosixHelperFunctions.c +++ b/src/main/c/Posix/PosixHelperFunctions.c @@ -2,7 +2,7 @@ * PosixHelperFunctions.c * * Created on: Mar 10, 2015 - * Last Updated on: Mar 07, 2019 + * Last Updated on: Feb 25, 2020 * Author: Will Hedgecock * * Copyright (C) 2012-2020 Fazecast, Inc. diff --git a/src/main/c/Posix/PosixHelperFunctions.h b/src/main/c/Posix/PosixHelperFunctions.h index 5fdf0e8..b6c2a8f 100644 --- a/src/main/c/Posix/PosixHelperFunctions.h +++ b/src/main/c/Posix/PosixHelperFunctions.h @@ -43,7 +43,11 @@ char keyExists(struct charTupleVector* vector, const char* key); // Linux-specific functionality #if defined(__linux__) typedef int baud_rate; +#ifdef __ANDROID__ +extern int ioctl(int __fd, int __request, ...); +#else extern int ioctl(int __fd, unsigned long int __request, ...); +#endif void getDriverName(const char* directoryToSearch, char* friendlyName); void getFriendlyName(const char* productFile, char* friendlyName); void getInterfaceDescription(const char* interfaceFile, char* interfaceDescription); diff --git a/src/main/c/Posix/SerialPort_Posix.c b/src/main/c/Posix/SerialPort_Posix.c index c3bad8e..acd763e 100644 --- a/src/main/c/Posix/SerialPort_Posix.c +++ b/src/main/c/Posix/SerialPort_Posix.c @@ -2,7 +2,7 @@ * SerialPort_Posix.c * * Created on: Feb 25, 2012 - * Last Updated on: Feb 19, 2020 + * Last Updated on: Feb 25, 2020 * Author: Will Hedgecock * * Copyright (C) 2012-2020 Fazecast, Inc. diff --git a/src/main/c/Android/jni/com_fazecast_jSerialComm_SerialPort.h b/src/main/c/Posix/com_fazecast_jSerialComm_SerialPort.h similarity index 100% rename from src/main/c/Android/jni/com_fazecast_jSerialComm_SerialPort.h rename to src/main/c/Posix/com_fazecast_jSerialComm_SerialPort.h diff --git a/src/main/c/Posix/jni/Android.mk b/src/main/c/Posix/jni/Android.mk new file mode 100644 index 0000000..be8d0e7 --- /dev/null +++ b/src/main/c/Posix/jni/Android.mk @@ -0,0 +1,14 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := jSerialComm +TARGET_OUT := ../../resources/Android/$(TARGET_ARCH_ABI) +LOCAL_SRC_FILES := ../SerialPort_Posix.c ../PosixHelperFunctions.c +LOCAL_LDLIBS := -llog +LOCAL_CFLAGS := -fsigned-char + +include $(BUILD_SHARED_LIBRARY) + +all: + rmdir /Q /S libs obj diff --git a/src/main/c/Android/jni/Application.mk b/src/main/c/Posix/jni/Application.mk similarity index 100% rename from src/main/c/Android/jni/Application.mk rename to src/main/c/Posix/jni/Application.mk