Fix 3 rx handling bugs; timeout, short read, out-of-sync.

When not plugging in the radio we expect to only see timeout errors.
However due to timeout being checked AFTER the read() call the len parameter
was updated and no longer was 0 returned.

If less then 4 was read (a short read) then uninitialized data was used,
for length and/or magic check.

If the magic byte does not match then the  rx buffer should be flushed before
trying again. Otherwise sync will probably never be achieved. This
solves the bug where plugging in the radio show continues streams of
magic packet errors. For me k5prog -Y -D now always works, while before
it could fail.
pull/20/head
Wouter van Gulik 2023-12-18 22:22:13 +13:00
rodzic 6eb4ac3822
commit c42c8b9f9d
1 zmienionych plików z 26 dodań i 15 usunięć

Wyświetl plik

@ -229,6 +229,13 @@ int read_timeout(int fd, unsigned char *buf, int maxlen, int timeout)
ret=select(fd+1,&rfd,0,0,&tv);
if (ret==0) {
if(timeout) /* Only print if we requested a timeout */
fprintf(stderr,"read_timeout\n");
/* error albo timeout */
break;
}
if (FD_ISSET(fd,&rfd)) {
nr=read(fd,buf,maxlen);
@ -236,17 +243,9 @@ int read_timeout(int fd, unsigned char *buf, int maxlen, int timeout)
buf=buf+nr;
if (nr>=0) maxlen=maxlen-nr;
if (maxlen==0) break;
}
if (ret==0) {
fprintf(stderr,"read_timeout\n");
/* error albo timeout */
break;
}
}
if (verbose>2) {
if (verbose>2 && len > 0) {
printf("RXRXRX:\n");
hdump(buf2,len);
}
@ -427,11 +426,22 @@ struct k5_command *k5_receive(int fd,int tmout) {
return(0);
}
/* During plugging in etc we can receive a single byte.
* Handle this case here. */
if (len != sizeof(buf))
{
fprintf(stderr,"k5_receive: got %d expected %ld\n", len, sizeof(buf));
return(0);
}
if ((buf[0]!=0xab)||(buf[1]!=0xcd)) {
fprintf(stderr,"k5_receive: bad magic number\n");
return(0);
}
if ((buf[0]!=0xab)||(buf[1]!=0xcd)) {
fprintf(stderr,"k5_receive: bad magic number\n");
/* Assume we are out of sync and flush rx buffer by reading everything.
* This works because the boot message is repeated. */
while(len > 0)
len =read_timeout(fd,(unsigned char *)&buf,sizeof(buf),0);
return(0);
}
if (buf[3]!=0) {
fprintf(stderr,"k5_receive: it seems that byte 3 can be something else than 0, please notify the author\n");
@ -564,8 +574,9 @@ int wait_flash_message(int fd,int ntimes) {
cmd=k5_receive(fd,10000);
if (!cmd) {
printf("wait_flash_message: timeout\n");
continue;
/* No need to print, k5_receive already printed why it failed */
//printf("wait_flash_message: timeout\n");
continue;
}
k5_hexdump(cmd);