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
Bill Somerville 2013-10-14 22:58:18 +01:00
rodzic 3cde4f4c2d
commit 849f1e1bf8
2 zmienionych plików z 125 dodań i 119 usunięć

Wyświetl plik

@ -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);
*/

Wyświetl plik

@ -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);