kopia lustrzana https://github.com/Hamlib/Hamlib
Fix serial i/o on Windows.
Fix bytes read count accumulation in Windows serial I/O. read_string from communications port doesn't handle timeout on anything but the first character read. Honour VMIN tty parameter correctly.Hamlib-3.0
rodzic
3cde4f4c2d
commit
849f1e1bf8
220
lib/termios.c
220
lib/termios.c
|
@ -1385,43 +1385,49 @@ int win32_serial_read( int fd, void *vb, int size )
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( index->open_flags & O_NONBLOCK )
|
if ( index->open_flags & O_NONBLOCK )
|
||||||
{
|
{
|
||||||
/* pull mucho-cpu here? */
|
/* pull mucho-cpu here? */
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
#ifdef DEBUG_VERBOSE
|
#ifdef DEBUG_VERBOSE
|
||||||
report( "vmin=0\n" );
|
report( "vmin=0\n" );
|
||||||
#endif /* DEBUG_VERBOSE */
|
#endif /* DEBUG_VERBOSE */
|
||||||
ClearErrors( index, &stat);
|
ClearErrors( index, &stat);
|
||||||
/*
|
|
||||||
usleep(1000);
|
if (stat.cbInQue < index->ttyset->c_cc[VMIN])
|
||||||
usleep(50);
|
{
|
||||||
*/
|
/*
|
||||||
/* we should use -1 instead of 0 for disabled timeout */
|
usleep(1000);
|
||||||
now = GetTickCount();
|
usleep(50);
|
||||||
if ( index->ttyset->c_cc[VTIME] &&
|
*/
|
||||||
now-start >= (index->ttyset->c_cc[VTIME]*100)) {
|
/* we should use -1 instead of 0 for disabled timeout */
|
||||||
/*
|
now = GetTickCount();
|
||||||
sprintf( message, "now = %i start = %i time = %i total =%i\n", now, start, index->ttyset->c_cc[VTIME]*100, total);
|
if (index->ttyset->c_cc[VTIME] &&
|
||||||
report( message );
|
now-start >= (index->ttyset->c_cc[VTIME]*100))
|
||||||
*/
|
{
|
||||||
return total; /* read timeout */
|
/*
|
||||||
}
|
sprintf( message, "now = %i start = %i time = %i total =%i\n", now, start, index->ttyset->c_cc[VTIME]*100, total);
|
||||||
} while( stat.cbInQue < size && size > 1 );
|
report( message );
|
||||||
}
|
*/
|
||||||
else
|
return total; /* read timeout */
|
||||||
{
|
}
|
||||||
/* VTIME is in units of 0.1 seconds */
|
}
|
||||||
|
} while (size > 1 && stat.cbInQue < index->ttyset->c_cc[VMIN]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* VTIME is in units of 0.1 seconds */
|
||||||
|
|
||||||
#ifdef DEBUG_VERBOSE
|
#ifdef DEBUG_VERBOSE
|
||||||
report( "vmin!=0\n" );
|
report( "vmin!=0\n" );
|
||||||
#endif /* DEBUG_VERBOSE */
|
#endif /* DEBUG_VERBOSE */
|
||||||
/* vmin = index->ttyset->c_cc[VMIN]; */
|
/* vmin = index->ttyset->c_cc[VMIN]; */
|
||||||
|
|
||||||
c = clock() + index->ttyset->c_cc[VTIME] * CLOCKS_PER_SEC / 10;
|
c = clock() + index->ttyset->c_cc[VTIME] * CLOCKS_PER_SEC / 10;
|
||||||
do {
|
do {
|
||||||
ClearErrors( index, &stat);
|
ClearErrors( index, &stat);
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
} while ( c > clock() );
|
} while (stat.cbInQue < index->ttyset->c_cc[VMIN] && c > clock());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1436,85 +1442,86 @@ int win32_serial_read( int fd, void *vb, int size )
|
||||||
|
|
||||||
err = ReadFile( index->hComm, dest + total, size, &nBytes, &index->rol );
|
err = ReadFile( index->hComm, dest + total, size, &nBytes, &index->rol );
|
||||||
#ifdef DEBUG_VERBOSE
|
#ifdef DEBUG_VERBOSE
|
||||||
/* warning Roy Rogers! */
|
/* warning Roy Rogers! */
|
||||||
sprintf(message, " ========== ReadFile = %i %s\n",
|
sprintf(message, " ========== ReadFile = %i %s\n",
|
||||||
( int ) nBytes, (char *) dest + total );
|
( int ) nBytes, (char *) dest + total );
|
||||||
report( message );
|
report( message );
|
||||||
#endif /* DEBUG_VERBOSE */
|
#endif /* DEBUG_VERBOSE */
|
||||||
size -= nBytes;
|
|
||||||
total += nBytes;
|
|
||||||
|
|
||||||
if ( !err )
|
if ( !err )
|
||||||
{
|
{
|
||||||
switch ( GetLastError() )
|
switch ( GetLastError() )
|
||||||
{
|
{
|
||||||
case ERROR_BROKEN_PIPE:
|
case ERROR_BROKEN_PIPE:
|
||||||
report( "ERROR_BROKEN_PIPE\n ");
|
report( "ERROR_BROKEN_PIPE\n ");
|
||||||
nBytes = 0;
|
nBytes = 0;
|
||||||
break;
|
break;
|
||||||
case ERROR_MORE_DATA:
|
case ERROR_MORE_DATA:
|
||||||
/*
|
/*
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
*/
|
*/
|
||||||
report( "ERROR_MORE_DATA\n" );
|
report( "ERROR_MORE_DATA\n" );
|
||||||
break;
|
break;
|
||||||
case ERROR_IO_PENDING:
|
case ERROR_IO_PENDING:
|
||||||
while( ! GetOverlappedResult(
|
while( ! GetOverlappedResult(
|
||||||
index->hComm,
|
index->hComm,
|
||||||
&index->rol,
|
&index->rol,
|
||||||
&nBytes,
|
&nBytes,
|
||||||
TRUE ) )
|
TRUE ) )
|
||||||
{
|
{
|
||||||
if( GetLastError() !=
|
if( GetLastError() !=
|
||||||
ERROR_IO_INCOMPLETE )
|
ERROR_IO_INCOMPLETE )
|
||||||
{
|
{
|
||||||
ClearErrors(
|
ClearErrors(
|
||||||
index,
|
index,
|
||||||
&stat);
|
&stat);
|
||||||
return( total );
|
return( total );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
size -= nBytes;
|
size -= nBytes;
|
||||||
total += nBytes;
|
total += nBytes;
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
now = GetTickCount();
|
now = GetTickCount();
|
||||||
sprintf(message, "size > 0: spent=%ld have=%d\n", now-start, index->ttyset->c_cc[VTIME]*100);
|
sprintf(message, "size > 0: spent=%ld have=%d\n", now-start, index->ttyset->c_cc[VTIME]*100);
|
||||||
report( message );
|
report( message );
|
||||||
/* we should use -1 for disabled
|
/* we should use -1 for disabled
|
||||||
timouts */
|
timouts */
|
||||||
if ( index->ttyset->c_cc[VTIME] && now-start >= (index->ttyset->c_cc[VTIME]*100)) {
|
if ( index->ttyset->c_cc[VTIME] && now-start >= (index->ttyset->c_cc[VTIME]*100)) {
|
||||||
report( "TO " );
|
report( "TO " );
|
||||||
/* read timeout */
|
/* read timeout */
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sprintf(message, "end nBytes=%ld] ", nBytes);
|
sprintf(message, "end nBytes=%ld] ", nBytes);
|
||||||
report( message );
|
report( message );
|
||||||
/*
|
/*
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
*/
|
*/
|
||||||
report( "ERROR_IO_PENDING\n" );
|
report( "ERROR_IO_PENDING\n" );
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/*
|
/*
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
*/
|
*/
|
||||||
YACK();
|
YACK();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
size -= nBytes;
|
||||||
usleep(1000);
|
total += nBytes;
|
||||||
*/
|
|
||||||
ClearErrors( index, &stat);
|
/*
|
||||||
return( total );
|
usleep(1000);
|
||||||
}
|
*/
|
||||||
}
|
ClearErrors( index, &stat);
|
||||||
LEAVE( "serial_read" );
|
return( total );
|
||||||
return total;
|
}
|
||||||
}
|
}
|
||||||
|
LEAVE( "serial_read" );
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef asdf
|
#ifdef asdf
|
||||||
int win32_serial_read( int fd, void *vb, int size )
|
int win32_serial_read( int fd, void *vb, int size )
|
||||||
|
@ -1614,8 +1621,6 @@ int win32_serial_read( int fd, void *vb, int size )
|
||||||
( int ) nBytes, (char *) dest + total );
|
( int ) nBytes, (char *) dest + total );
|
||||||
report( message );
|
report( message );
|
||||||
#endif /* DEBUG_VERBOSE */
|
#endif /* DEBUG_VERBOSE */
|
||||||
size -= nBytes;
|
|
||||||
total += nBytes;
|
|
||||||
|
|
||||||
if ( !err )
|
if ( !err )
|
||||||
{
|
{
|
||||||
|
@ -1682,6 +1687,9 @@ int win32_serial_read( int fd, void *vb, int size )
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
size -= nBytes;
|
||||||
|
total += nBytes;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
*/
|
*/
|
||||||
|
|
24
src/iofunc.c
24
src/iofunc.c
|
@ -504,8 +504,17 @@ int HAMLIB_API read_string(hamlib_port_t *p, char *rxbuffer, size_t rxmax, const
|
||||||
efds = rfds;
|
efds = rfds;
|
||||||
|
|
||||||
retval = port_select(p, p->fd+1, &rfds, NULL, &efds, &tv);
|
retval = port_select(p, p->fd+1, &rfds, NULL, &efds, &tv);
|
||||||
if (retval == 0) /* Timed out */
|
if (retval == 0) {
|
||||||
break;
|
/* Record timeout time and caculate elapsed time */
|
||||||
|
gettimeofday(&end_time, NULL);
|
||||||
|
timersub(&end_time, &start_time, &elapsed_time);
|
||||||
|
|
||||||
|
dump_hex((unsigned char *) rxbuffer, total_count);
|
||||||
|
rig_debug(RIG_DEBUG_WARN, "%s(): Timed out %d.%d seconds after %d chars\n",
|
||||||
|
__func__, elapsed_time.tv_sec, elapsed_time.tv_usec, total_count);
|
||||||
|
|
||||||
|
return -RIG_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
if (retval < 0) {
|
if (retval < 0) {
|
||||||
dump_hex((unsigned char *) rxbuffer, total_count);
|
dump_hex((unsigned char *) rxbuffer, total_count);
|
||||||
|
@ -543,17 +552,6 @@ int HAMLIB_API read_string(hamlib_port_t *p, char *rxbuffer, size_t rxmax, const
|
||||||
*/
|
*/
|
||||||
rxbuffer[total_count] = '\000';
|
rxbuffer[total_count] = '\000';
|
||||||
|
|
||||||
if (total_count == 0) {
|
|
||||||
/* Record timeout time and caculate elapsed time */
|
|
||||||
gettimeofday(&end_time, NULL);
|
|
||||||
timersub(&end_time, &start_time, &elapsed_time);
|
|
||||||
|
|
||||||
rig_debug(RIG_DEBUG_WARN, "%s(): Timed out %d.%d seconds without reading a character.\n",
|
|
||||||
__func__, elapsed_time.tv_sec, elapsed_time.tv_usec);
|
|
||||||
|
|
||||||
return -RIG_ETIMEOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
rig_debug(RIG_DEBUG_TRACE,"%s(): RX %d characters\n", __func__, total_count);
|
rig_debug(RIG_DEBUG_TRACE,"%s(): RX %d characters\n", __func__, total_count);
|
||||||
dump_hex((unsigned char *) rxbuffer, total_count);
|
dump_hex((unsigned char *) rxbuffer, total_count);
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue