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 )
|
||||
{
|
||||
/* pull mucho-cpu here? */
|
||||
do {
|
||||
{
|
||||
/* pull mucho-cpu here? */
|
||||
do
|
||||
{
|
||||
#ifdef DEBUG_VERBOSE
|
||||
report( "vmin=0\n" );
|
||||
report( "vmin=0\n" );
|
||||
#endif /* DEBUG_VERBOSE */
|
||||
ClearErrors( index, &stat);
|
||||
/*
|
||||
usleep(1000);
|
||||
usleep(50);
|
||||
*/
|
||||
/* we should use -1 instead of 0 for disabled timeout */
|
||||
now = GetTickCount();
|
||||
if ( index->ttyset->c_cc[VTIME] &&
|
||||
now-start >= (index->ttyset->c_cc[VTIME]*100)) {
|
||||
/*
|
||||
sprintf( message, "now = %i start = %i time = %i total =%i\n", now, start, index->ttyset->c_cc[VTIME]*100, total);
|
||||
report( message );
|
||||
*/
|
||||
return total; /* read timeout */
|
||||
}
|
||||
} while( stat.cbInQue < size && size > 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
/* VTIME is in units of 0.1 seconds */
|
||||
ClearErrors( index, &stat);
|
||||
|
||||
if (stat.cbInQue < index->ttyset->c_cc[VMIN])
|
||||
{
|
||||
/*
|
||||
usleep(1000);
|
||||
usleep(50);
|
||||
*/
|
||||
/* we should use -1 instead of 0 for disabled timeout */
|
||||
now = GetTickCount();
|
||||
if (index->ttyset->c_cc[VTIME] &&
|
||||
now-start >= (index->ttyset->c_cc[VTIME]*100))
|
||||
{
|
||||
/*
|
||||
sprintf( message, "now = %i start = %i time = %i total =%i\n", now, start, index->ttyset->c_cc[VTIME]*100, total);
|
||||
report( message );
|
||||
*/
|
||||
return total; /* read timeout */
|
||||
}
|
||||
}
|
||||
} while (size > 1 && stat.cbInQue < index->ttyset->c_cc[VMIN]);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* VTIME is in units of 0.1 seconds */
|
||||
|
||||
#ifdef DEBUG_VERBOSE
|
||||
report( "vmin!=0\n" );
|
||||
report( "vmin!=0\n" );
|
||||
#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;
|
||||
do {
|
||||
ClearErrors( index, &stat);
|
||||
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 );
|
||||
#ifdef DEBUG_VERBOSE
|
||||
/* warning Roy Rogers! */
|
||||
sprintf(message, " ========== ReadFile = %i %s\n",
|
||||
( int ) nBytes, (char *) dest + total );
|
||||
report( message );
|
||||
/* warning Roy Rogers! */
|
||||
sprintf(message, " ========== ReadFile = %i %s\n",
|
||||
( int ) nBytes, (char *) dest + total );
|
||||
report( message );
|
||||
#endif /* DEBUG_VERBOSE */
|
||||
size -= nBytes;
|
||||
total += nBytes;
|
||||
|
||||
if ( !err )
|
||||
{
|
||||
switch ( GetLastError() )
|
||||
{
|
||||
case ERROR_BROKEN_PIPE:
|
||||
report( "ERROR_BROKEN_PIPE\n ");
|
||||
nBytes = 0;
|
||||
break;
|
||||
case ERROR_MORE_DATA:
|
||||
/*
|
||||
usleep(1000);
|
||||
*/
|
||||
report( "ERROR_MORE_DATA\n" );
|
||||
break;
|
||||
case ERROR_IO_PENDING:
|
||||
while( ! GetOverlappedResult(
|
||||
index->hComm,
|
||||
&index->rol,
|
||||
&nBytes,
|
||||
TRUE ) )
|
||||
{
|
||||
if( GetLastError() !=
|
||||
ERROR_IO_INCOMPLETE )
|
||||
{
|
||||
ClearErrors(
|
||||
index,
|
||||
&stat);
|
||||
return( total );
|
||||
}
|
||||
}
|
||||
size -= nBytes;
|
||||
total += nBytes;
|
||||
if (size > 0) {
|
||||
now = GetTickCount();
|
||||
sprintf(message, "size > 0: spent=%ld have=%d\n", now-start, index->ttyset->c_cc[VTIME]*100);
|
||||
report( message );
|
||||
/* we should use -1 for disabled
|
||||
timouts */
|
||||
if ( index->ttyset->c_cc[VTIME] && now-start >= (index->ttyset->c_cc[VTIME]*100)) {
|
||||
report( "TO " );
|
||||
/* read timeout */
|
||||
return total;
|
||||
}
|
||||
}
|
||||
sprintf(message, "end nBytes=%ld] ", nBytes);
|
||||
report( message );
|
||||
/*
|
||||
usleep(1000);
|
||||
*/
|
||||
report( "ERROR_IO_PENDING\n" );
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
usleep(1000);
|
||||
*/
|
||||
YACK();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
usleep(1000);
|
||||
*/
|
||||
ClearErrors( index, &stat);
|
||||
return( total );
|
||||
}
|
||||
}
|
||||
LEAVE( "serial_read" );
|
||||
return total;
|
||||
}
|
||||
if ( !err )
|
||||
{
|
||||
switch ( GetLastError() )
|
||||
{
|
||||
case ERROR_BROKEN_PIPE:
|
||||
report( "ERROR_BROKEN_PIPE\n ");
|
||||
nBytes = 0;
|
||||
break;
|
||||
case ERROR_MORE_DATA:
|
||||
/*
|
||||
usleep(1000);
|
||||
*/
|
||||
report( "ERROR_MORE_DATA\n" );
|
||||
break;
|
||||
case ERROR_IO_PENDING:
|
||||
while( ! GetOverlappedResult(
|
||||
index->hComm,
|
||||
&index->rol,
|
||||
&nBytes,
|
||||
TRUE ) )
|
||||
{
|
||||
if( GetLastError() !=
|
||||
ERROR_IO_INCOMPLETE )
|
||||
{
|
||||
ClearErrors(
|
||||
index,
|
||||
&stat);
|
||||
return( total );
|
||||
}
|
||||
}
|
||||
size -= nBytes;
|
||||
total += nBytes;
|
||||
if (size > 0) {
|
||||
now = GetTickCount();
|
||||
sprintf(message, "size > 0: spent=%ld have=%d\n", now-start, index->ttyset->c_cc[VTIME]*100);
|
||||
report( message );
|
||||
/* we should use -1 for disabled
|
||||
timouts */
|
||||
if ( index->ttyset->c_cc[VTIME] && now-start >= (index->ttyset->c_cc[VTIME]*100)) {
|
||||
report( "TO " );
|
||||
/* read timeout */
|
||||
return total;
|
||||
}
|
||||
}
|
||||
sprintf(message, "end nBytes=%ld] ", nBytes);
|
||||
report( message );
|
||||
/*
|
||||
usleep(1000);
|
||||
*/
|
||||
report( "ERROR_IO_PENDING\n" );
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
usleep(1000);
|
||||
*/
|
||||
YACK();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
size -= nBytes;
|
||||
total += nBytes;
|
||||
|
||||
/*
|
||||
usleep(1000);
|
||||
*/
|
||||
ClearErrors( index, &stat);
|
||||
return( total );
|
||||
}
|
||||
}
|
||||
LEAVE( "serial_read" );
|
||||
return total;
|
||||
}
|
||||
|
||||
#ifdef asdf
|
||||
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 );
|
||||
report( message );
|
||||
#endif /* DEBUG_VERBOSE */
|
||||
size -= nBytes;
|
||||
total += nBytes;
|
||||
|
||||
if ( !err )
|
||||
{
|
||||
|
@ -1682,6 +1687,9 @@ int win32_serial_read( int fd, void *vb, int size )
|
|||
}
|
||||
else
|
||||
{
|
||||
size -= nBytes;
|
||||
total += nBytes;
|
||||
|
||||
/*
|
||||
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;
|
||||
|
||||
retval = port_select(p, p->fd+1, &rfds, NULL, &efds, &tv);
|
||||
if (retval == 0) /* Timed out */
|
||||
break;
|
||||
if (retval == 0) {
|
||||
/* 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) {
|
||||
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';
|
||||
|
||||
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);
|
||||
dump_hex((unsigned char *) rxbuffer, total_count);
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue