Retry POSIX calls if EINTR value is returned and try a last-ditch brute force enumeration of any ports that aren't properly listed in sysfs on Linux.
This commit is contained in:
parent
7e7ac77796
commit
ec0acd7ac4
|
@ -53,6 +53,15 @@ void push_back(struct charPairVector* vector, const char* firstString, const cha
|
|||
strcpy(vector->second[vector->length-1], secondString);
|
||||
}
|
||||
|
||||
char keyExists(struct charPairVector* 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;
|
||||
|
@ -201,6 +210,47 @@ void recursiveSearchForComPorts(charPairVector* comPorts, const char* fullPathTo
|
|||
closedir(directoryIterator);
|
||||
}
|
||||
|
||||
void lastDitchSearchForComPorts(charPairVector* comPorts)
|
||||
{
|
||||
// Open the linux dev directory
|
||||
DIR *directoryIterator = opendir("/dev/");
|
||||
if (!directoryIterator)
|
||||
return;
|
||||
|
||||
// Read all files in the current directory
|
||||
struct dirent *directoryEntry = readdir(directoryIterator);
|
||||
while (directoryEntry)
|
||||
{
|
||||
// See if the file names a potential serial port
|
||||
if ((strlen(directoryEntry->d_name) >= 6) && (directoryEntry->d_name[0] == 't') && (directoryEntry->d_name[1] == 't') && (directoryEntry->d_name[2] == 'y') &&
|
||||
(((directoryEntry->d_name[3] == 'A') && (directoryEntry->d_name[4] == 'M') && (directoryEntry->d_name[5] == 'A')) ||
|
||||
((directoryEntry->d_name[3] == 'A') && (directoryEntry->d_name[4] == 'C') && (directoryEntry->d_name[5] == 'M')) ||
|
||||
((directoryEntry->d_name[3] == 'U') && (directoryEntry->d_name[4] == 'S') && (directoryEntry->d_name[5] == 'B'))))
|
||||
{
|
||||
// Determine system name of port
|
||||
char* systemName = (char*)malloc(256);
|
||||
strcpy(systemName, "/dev/");
|
||||
strcat(systemName, directoryEntry->d_name);
|
||||
|
||||
// Set static friendly name
|
||||
char* friendlyName = (char*)malloc(256);
|
||||
strcpy(friendlyName, "USB-Based Serial Port");
|
||||
|
||||
// Determine if port is already in the list, and add it if not
|
||||
if (!keyExists(comPorts, systemName))
|
||||
push_back(comPorts, systemName, friendlyName);
|
||||
|
||||
// Clean up memory
|
||||
free(systemName);
|
||||
free(friendlyName);
|
||||
}
|
||||
directoryEntry = readdir(directoryIterator);
|
||||
}
|
||||
|
||||
// Close the directory
|
||||
closedir(directoryIterator);
|
||||
}
|
||||
|
||||
unsigned int getBaudRateCode(int baudRate)
|
||||
{
|
||||
switch (baudRate)
|
||||
|
|
|
@ -32,9 +32,11 @@ typedef struct charPairVector
|
|||
size_t length;
|
||||
} charPairVector;
|
||||
void push_back(struct charPairVector* vector, const char* firstString, const char* secondString);
|
||||
char keyExists(struct charPairVector* vector, const char* key);
|
||||
|
||||
void getDriverName(const char* directoryToSearch, char* friendlyName);
|
||||
void recursiveSearchForComPorts(charPairVector* comPorts, const char* fullPathToSearch);
|
||||
void lastDitchSearchForComPorts(charPairVector* comPorts);
|
||||
void getFriendlyName(const char* productFile, char* friendlyName);
|
||||
unsigned int getBaudRateCode(int baudRate);
|
||||
void setBaudRate(int portFD, int baudRate);
|
||||
|
|
|
@ -61,6 +61,7 @@ JNIEXPORT jobjectArray JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCommP
|
|||
// Enumerate serial ports on machine
|
||||
charPairVector serialPorts = { (char**)malloc(1), (char**)malloc(1), 0 };
|
||||
recursiveSearchForComPorts(&serialPorts, "/sys/devices/");
|
||||
lastDitchSearchForComPorts(&serialPorts);
|
||||
jobjectArray arrayObject = (*env)->NewObjectArray(env, serialPorts.length, serialCommClass, 0);
|
||||
int i;
|
||||
for (i = 0; i < serialPorts.length; ++i)
|
||||
|
@ -317,7 +318,8 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_waitForEvent(JNI
|
|||
FD_SET(serialPortFD, &waitingSet);
|
||||
|
||||
// Wait for a serial port event
|
||||
int retVal = select(serialPortFD + 1, &waitingSet, NULL, NULL, &timeout);
|
||||
int retVal;
|
||||
do { retVal = select(serialPortFD + 1, &waitingSet, NULL, NULL, &timeout); } while ((retVal < 0) && (errno == EINTR));
|
||||
if (retVal <= 0)
|
||||
return 0;
|
||||
return (FD_ISSET(serialPortFD, &waitingSet)) ? com_fazecast_jSerialComm_SerialPort_LISTENING_EVENT_DATA_AVAILABLE : 0;
|
||||
|
@ -361,7 +363,8 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
|
|||
// While there are more bytes we are supposed to read
|
||||
while (bytesRemaining > 0)
|
||||
{
|
||||
if ((numBytesRead = read(serialPortFD, readBuffer+numBytesReadTotal, bytesRemaining)) == -1)
|
||||
do { numBytesRead = read(serialPortFD, readBuffer+numBytesReadTotal, bytesRemaining); } while ((numBytesRead < 0) && (errno == EINTR));
|
||||
if (numBytesRead == -1)
|
||||
{
|
||||
// Problem reading, close port
|
||||
close(serialPortFD);
|
||||
|
@ -391,7 +394,8 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
|
|||
// While there are more bytes we are supposed to read and the timeout has not elapsed
|
||||
do
|
||||
{
|
||||
if ((numBytesRead = read(serialPortFD, readBuffer+numBytesReadTotal, bytesRemaining)) == -1)
|
||||
do { numBytesRead = read(serialPortFD, readBuffer+numBytesReadTotal, bytesRemaining); } while ((numBytesRead < 0) && (errno == EINTR));
|
||||
if (numBytesRead == -1)
|
||||
{
|
||||
// Problem reading, close port
|
||||
close(serialPortFD);
|
||||
|
@ -413,7 +417,8 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
|
|||
else // Semi- or non-blocking specified
|
||||
{
|
||||
// Read from port
|
||||
if ((numBytesRead = read(serialPortFD, readBuffer, bytesToRead)) == -1)
|
||||
do { numBytesRead = read(serialPortFD, readBuffer, bytesToRead); } while ((numBytesRead < 0) && (errno == EINTR));
|
||||
if (numBytesRead == -1)
|
||||
{
|
||||
// Problem reading, close port
|
||||
close(serialPortFD);
|
||||
|
@ -436,10 +441,11 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEn
|
|||
if (serialPortFD <= 0)
|
||||
return -1;
|
||||
jbyte *writeBuffer = (*env)->GetByteArrayElements(env, buffer, 0);
|
||||
int numBytesWritten;
|
||||
int numBytesWritten, result = 0;
|
||||
|
||||
// Write to port
|
||||
if ((numBytesWritten = write(serialPortFD, writeBuffer, bytesToWrite)) == -1)
|
||||
do { numBytesWritten = write(serialPortFD, writeBuffer, bytesToWrite); } while ((numBytesWritten < 0) && (errno == EINTR));
|
||||
if (numBytesWritten == -1)
|
||||
{
|
||||
// Problem writing, close port
|
||||
close(serialPortFD);
|
||||
|
|
|
@ -356,7 +356,8 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_waitForEvent(JNI
|
|||
FD_SET(serialPortFD, &waitingSet);
|
||||
|
||||
// Wait for a serial port event
|
||||
int retVal = select(serialPortFD + 1, &waitingSet, NULL, NULL, &timeout);
|
||||
int retVal;
|
||||
do { retVal = select(serialPortFD + 1, &waitingSet, NULL, NULL, &timeout); } while ((retVal < 0) && (errno == EINTR));
|
||||
if (retVal <= 0)
|
||||
return 0;
|
||||
return (FD_ISSET(serialPortFD, &waitingSet)) ? com_fazecast_jSerialComm_SerialPort_LISTENING_EVENT_DATA_AVAILABLE : 0;
|
||||
|
@ -401,7 +402,8 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
|
|||
// While there are more bytes we are supposed to read
|
||||
while (bytesRemaining > 0)
|
||||
{
|
||||
if ((numBytesRead = read(serialPortFD, readBuffer+numBytesReadTotal, bytesRemaining)) == -1)
|
||||
do { numBytesRead = read(serialPortFD, readBuffer+numBytesReadTotal, bytesRemaining); } while ((numBytesRead < 0) && (errno == EINTR));
|
||||
if (numBytesRead == -1)
|
||||
{
|
||||
// Problem reading, close port
|
||||
close(serialPortFD);
|
||||
|
@ -431,7 +433,8 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
|
|||
// While there are more bytes we are supposed to read and the timeout has not elapsed
|
||||
do
|
||||
{
|
||||
if ((numBytesRead = read(serialPortFD, readBuffer+numBytesReadTotal, bytesRemaining)) == -1)
|
||||
do { numBytesRead = read(serialPortFD, readBuffer+numBytesReadTotal, bytesRemaining); } while ((numBytesRead < 0) && (errno == EINTR));
|
||||
if (numBytesRead == -1)
|
||||
{
|
||||
// Problem reading, close port
|
||||
close(serialPortFD);
|
||||
|
@ -453,7 +456,8 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_readBytes(JNIEnv
|
|||
else // Semi- or non-blocking specified
|
||||
{
|
||||
// Read from port
|
||||
if ((numBytesRead = read(serialPortFD, readBuffer, bytesToRead)) == -1)
|
||||
do { numBytesRead = read(serialPortFD, readBuffer, bytesToRead); } while ((numBytesRead < 0) && (errno == EINTR));
|
||||
if (numBytesRead == -1)
|
||||
{
|
||||
// Problem reading, close port
|
||||
close(serialPortFD);
|
||||
|
@ -479,7 +483,8 @@ JNIEXPORT jint JNICALL Java_com_fazecast_jSerialComm_SerialPort_writeBytes(JNIEn
|
|||
int numBytesWritten;
|
||||
|
||||
// Write to port
|
||||
if ((numBytesWritten = write(serialPortFD, writeBuffer, bytesToWrite)) == -1)
|
||||
do { numBytesWritten = write(serialPortFD, writeBuffer, bytesToWrite); } while ((numBytesWritten < 0) && (errno == EINTR));
|
||||
if (numBytesWritten == -1)
|
||||
{
|
||||
// Problem writing, close port
|
||||
close(serialPortFD);
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue