Skip to content
Snippets Groups Projects
Commit 074edbc1 authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Better HEX frame corruption detection.

More logging details (e.g. subpacket byte progress).
Identify XON and XOFF by name (e.g. when purging receive buffer).
Some variable naming and comment improvements.
parent 421db044
No related branches found
No related tags found
1 merge request!463MRC mods by Codefenix (2024-10-20)
...@@ -139,7 +139,8 @@ static char *chr(int ch) ...@@ -139,7 +139,8 @@ static char *chr(int ch)
case ZCRCG: return("ZCRCG"); case ZCRCG: return("ZCRCG");
case ZCRCQ: return("ZCRCQ"); case ZCRCQ: return("ZCRCQ");
case ZCRCW: return("ZCRCW"); case ZCRCW: return("ZCRCW");
case XON: return "XON";
case XOFF: return "XOFF";
} }
if(ch<0) if(ch<0)
sprintf(str,"%d",ch); sprintf(str,"%d",ch);
...@@ -818,7 +819,7 @@ int zmodem_rx(zmodem_t* zm) ...@@ -818,7 +819,7 @@ int zmodem_rx(zmodem_t* zm)
* data subpacket reception * data subpacket reception
*/ */
int zmodem_recv_data32(zmodem_t* zm, unsigned char * p, unsigned maxlen, unsigned* l, int* type) int zmodem_recv_data32(zmodem_t* zm, unsigned char * p, unsigned maxlen, unsigned* len, int* type)
{ {
int c; int c;
uint32_t rxd_crc; uint32_t rxd_crc;
...@@ -839,13 +840,13 @@ int zmodem_recv_data32(zmodem_t* zm, unsigned char * p, unsigned maxlen, unsigne ...@@ -839,13 +840,13 @@ int zmodem_recv_data32(zmodem_t* zm, unsigned char * p, unsigned maxlen, unsigne
if(c > 0xff) if(c > 0xff)
break; break;
if(*l >= maxlen) { if(*len >= maxlen) {
lprintf(zm, LOG_ERR, "%lu Subpacket OVERFLOW (%u > %u)",(ulong)zm->ack_file_pos, *l, maxlen); lprintf(zm, LOG_ERR, "%lu Subpacket OVERFLOW (%u > %u)",(ulong)zm->ack_file_pos, *len, maxlen);
return SUBPKTOVERFLOW; return SUBPKTOVERFLOW;
} }
crc = ucrc32(c,crc); crc = ucrc32(c,crc);
*p++ = c; *p++ = c;
(*l)++; (*len)++;
} while(1); } while(1);
subpkt_type = c & 0xff; subpkt_type = c & 0xff;
...@@ -862,18 +863,18 @@ int zmodem_recv_data32(zmodem_t* zm, unsigned char * p, unsigned maxlen, unsigne ...@@ -862,18 +863,18 @@ int zmodem_recv_data32(zmodem_t* zm, unsigned char * p, unsigned maxlen, unsigne
if(rxd_crc != crc) { if(rxd_crc != crc) {
lprintf(zm,LOG_WARNING, "%lu %s CRC ERROR (%08lX, expected: %08lX) Bytes=%u, subpacket type=%s" lprintf(zm,LOG_WARNING, "%lu %s CRC ERROR (%08lX, expected: %08lX) Bytes=%u, subpacket type=%s"
,(ulong)zm->ack_file_pos, __FUNCTION__, rxd_crc, crc, *l, chr(subpkt_type)); ,(ulong)zm->ack_file_pos, __FUNCTION__, rxd_crc, crc, *len, chr(subpkt_type));
return CRCFAILED; return CRCFAILED;
} }
// lprintf(zm,LOG_DEBUG, "%lu %s GOOD CRC: %08lX (Bytes=%u, subpacket type=%s)" // lprintf(zm,LOG_DEBUG, "%lu %s GOOD CRC: %08lX (Bytes=%u, subpacket type=%s)"
// ,(ulong)zm->ack_file_pos, __FUNCTION__, crc, *l, chr(subpkt_type)); // ,(ulong)zm->ack_file_pos, __FUNCTION__, crc, *len, chr(subpkt_type));
zm->ack_file_pos += *l; zm->ack_file_pos += *len;
return subpkt_type; return subpkt_type;
} }
int zmodem_recv_data16(zmodem_t* zm, register unsigned char* p, unsigned maxlen, unsigned* l, int* type) int zmodem_recv_data16(zmodem_t* zm, register unsigned char* p, unsigned maxlen, unsigned* len, int* type)
{ {
int c; int c;
int subpkt_type; int subpkt_type;
...@@ -894,11 +895,11 @@ int zmodem_recv_data16(zmodem_t* zm, register unsigned char* p, unsigned maxlen, ...@@ -894,11 +895,11 @@ int zmodem_recv_data16(zmodem_t* zm, register unsigned char* p, unsigned maxlen,
if(c > 0xff) if(c > 0xff)
break; break;
if(*l >= maxlen) if(*len >= maxlen)
return SUBPKTOVERFLOW; return SUBPKTOVERFLOW;
crc = ucrc16(c,crc); crc = ucrc16(c,crc);
*p++ = c; *p++ = c;
(*l)++; (*len)++;
} while(1); } while(1);
subpkt_type = c & 0xff; subpkt_type = c & 0xff;
...@@ -911,24 +912,24 @@ int zmodem_recv_data16(zmodem_t* zm, register unsigned char* p, unsigned maxlen, ...@@ -911,24 +912,24 @@ int zmodem_recv_data16(zmodem_t* zm, register unsigned char* p, unsigned maxlen,
if(rxd_crc != crc) { if(rxd_crc != crc) {
lprintf(zm,LOG_WARNING, "%lu %s CRC ERROR (%04hX, expected: %04hX) Bytes=%u, subpacket type=%s" lprintf(zm,LOG_WARNING, "%lu %s CRC ERROR (%04hX, expected: %04hX) Bytes=%u, subpacket type=%s"
,(ulong)zm->ack_file_pos, __FUNCTION__, rxd_crc, crc, *l, chr(subpkt_type)); ,(ulong)zm->ack_file_pos, __FUNCTION__, rxd_crc, crc, *len, chr(subpkt_type));
return CRCFAILED; return CRCFAILED;
} }
// lprintf(zm,LOG_DEBUG, "%lu %s GOOD CRC: %04hX (Bytes=%d, subpacket type=%s)" // lprintf(zm,LOG_DEBUG, "%lu %s GOOD CRC: %04hX (Bytes=%d, subpacket type=%s)"
// ,(ulong)zm->ack_file_pos, __FUNCTION__, crc, *l, chr(subpkt_type)); // ,(ulong)zm->ack_file_pos, __FUNCTION__, crc, *len, chr(subpkt_type));
zm->ack_file_pos += *l; zm->ack_file_pos += *len;
return subpkt_type; return subpkt_type;
} }
int zmodem_recv_data(zmodem_t* zm, unsigned char* p, size_t maxlen, unsigned* l, BOOL ack, int* type) int zmodem_recv_data(zmodem_t* zm, unsigned char* p, size_t maxlen, unsigned* len, BOOL ack, int* type)
{ {
int subpkt_type; int subpkt_type;
unsigned n=0; unsigned n=0;
if(l==NULL) if(len == NULL)
l=&n; len = &n;
// lprintf(zm,LOG_DEBUG, __FUNCTION__ " (%u-bit)", zm->receive_32bit_data ? 32:16); // lprintf(zm,LOG_DEBUG, __FUNCTION__ " (%u-bit)", zm->receive_32bit_data ? 32:16);
...@@ -936,21 +937,23 @@ int zmodem_recv_data(zmodem_t* zm, unsigned char* p, size_t maxlen, unsigned* l, ...@@ -936,21 +937,23 @@ int zmodem_recv_data(zmodem_t* zm, unsigned char* p, size_t maxlen, unsigned* l,
* receive the right type of frame * receive the right type of frame
*/ */
*l = 0; *len = 0;
if(zm->receive_32bit_data) { if(zm->receive_32bit_data) {
subpkt_type = zmodem_recv_data32(zm, p, maxlen, l, type); subpkt_type = zmodem_recv_data32(zm, p, maxlen, len, type);
} }
else { else {
subpkt_type = zmodem_recv_data16(zm, p, maxlen, l, type); subpkt_type = zmodem_recv_data16(zm, p, maxlen, len, type);
} }
if(subpkt_type <= 0) { /* e.g. TIMEOUT, SUBPKTOVERFLOW, CRCFAILED */ if(subpkt_type <= 0) { /* e.g. TIMEOUT, SUBPKTOVERFLOW, CRCFAILED */
lprintf(zm, LOG_WARNING, "%lu %s ERROR: %s",(ulong)zm->ack_file_pos, __FUNCTION__, chr(subpkt_type)); lprintf(zm, LOG_WARNING, "%lu %s ERROR: %s (after %u bytes)"
,(ulong)zm->ack_file_pos, __FUNCTION__, chr(subpkt_type), *len);
return(subpkt_type); return(subpkt_type);
} }
lprintf(zm, LOG_DEBUG, "%lu Successful receipt of subpacket type: %s", (ulong)zm->ack_file_pos, chr(subpkt_type)); lprintf(zm, LOG_DEBUG, "%lu Successful receipt of subpacket type: %s (%u bytes)"
,(ulong)zm->ack_file_pos, chr(subpkt_type), *len);
switch(subpkt_type) { switch(subpkt_type) {
/* /*
...@@ -979,7 +982,8 @@ int zmodem_recv_data(zmodem_t* zm, unsigned char* p, size_t maxlen, unsigned* l, ...@@ -979,7 +982,8 @@ int zmodem_recv_data(zmodem_t* zm, unsigned char* p, size_t maxlen, unsigned* l,
return ENDOFFRAME; return ENDOFFRAME;
} }
lprintf(zm,LOG_WARNING, "%lu INVALID subpacket type: %s", (ulong)zm->ack_file_pos, chr(subpkt_type)); lprintf(zm,LOG_WARNING, "%lu INVALID subpacket type: %s (%u bytes)"
,(ulong)zm->ack_file_pos, chr(subpkt_type), *len);
return INVALIDSUBPKT; return INVALIDSUBPKT;
} }
...@@ -987,11 +991,12 @@ int zmodem_recv_data(zmodem_t* zm, unsigned char* p, size_t maxlen, unsigned* l, ...@@ -987,11 +991,12 @@ int zmodem_recv_data(zmodem_t* zm, unsigned char* p, size_t maxlen, unsigned* l,
BOOL zmodem_recv_subpacket(zmodem_t* zm, BOOL ack, int* type) BOOL zmodem_recv_subpacket(zmodem_t* zm, BOOL ack, int* type)
{ {
int result; int result;
unsigned len = 0;
result = zmodem_recv_data(zm,zm->rx_data_subpacket,sizeof(zm->rx_data_subpacket),NULL,ack, type); result = zmodem_recv_data(zm,zm->rx_data_subpacket, sizeof(zm->rx_data_subpacket), &len, ack, type);
if(result != FRAMEOK && result != ENDOFFRAME) { if(result != FRAMEOK && result != ENDOFFRAME) {
lprintf(zm, LOG_ERR, "%lu %s ERROR: %s (subpacket type: %s)" lprintf(zm, LOG_ERR, "%lu %s ERROR: %s (subpacket type: %s, %u bytes)"
,(ulong)zm->ack_file_pos, __FUNCTION__, chr(result), chr(*type)); ,(ulong)zm->ack_file_pos, __FUNCTION__, chr(result), chr(*type), len);
zmodem_send_znak(zm); zmodem_send_znak(zm);
return(FALSE); return(FALSE);
} }
...@@ -1154,7 +1159,12 @@ BOOL zmodem_recv_hex_header(zmodem_t* zm) ...@@ -1154,7 +1159,12 @@ BOOL zmodem_recv_hex_header(zmodem_t* zm)
/* /*
* both are expected with CR * both are expected with CR
*/ */
zmodem_rx(zm); /* drop LF */ c = zmodem_rx(zm); /* drop LF */
}
if(c != '\n') {
lprintf(zm, LOG_ERR, "%s HEX header not terminated with LF: %s"
,__FUNCTION__, chr(c));
return FALSE;
} }
return TRUE; return TRUE;
...@@ -1351,7 +1361,7 @@ int zmodem_recv_header(zmodem_t* zm) ...@@ -1351,7 +1361,7 @@ int zmodem_recv_header(zmodem_t* zm)
BOOL zmodem_request_crc(zmodem_t* zm, int32_t length) BOOL zmodem_request_crc(zmodem_t* zm, int32_t length)
{ {
zmodem_recv_purge(zm, /* timeout: */0); zmodem_recv_purge(zm, /* timeout: */0);
zmodem_send_pos_header(zm,ZCRC,length,TRUE); zmodem_send_pos_header(zm, ZCRC, length, /* HEX: */TRUE);
return TRUE; return TRUE;
} }
...@@ -1841,7 +1851,7 @@ BOOL zmodem_send_file(zmodem_t* zm, char* fname, FILE* fp, BOOL request_init, ti ...@@ -1841,7 +1851,7 @@ BOOL zmodem_send_file(zmodem_t* zm, char* fname, FILE* fp, BOOL request_init, ti
else else
lprintf(zm,LOG_NOTICE,"Receiver requested CRC of first %lu bytes of file" lprintf(zm,LOG_NOTICE,"Receiver requested CRC of first %lu bytes of file"
,zm->crc_request); ,zm->crc_request);
zmodem_send_pos_header(zm,ZCRC,fcrc32(fp,zm->crc_request),TRUE); zmodem_send_pos_header(zm, ZCRC, fcrc32(fp,zm->crc_request), /* Hex: */TRUE);
type = zmodem_recv_header(zm); type = zmodem_recv_header(zm);
} }
...@@ -2251,7 +2261,6 @@ unsigned zmodem_recv_file_data(zmodem_t* zm, FILE* fp, int64_t offset) ...@@ -2251,7 +2261,6 @@ unsigned zmodem_recv_file_data(zmodem_t* zm, FILE* fp, int64_t offset)
int zmodem_recv_file_frame(zmodem_t* zm, FILE* fp, int* type) int zmodem_recv_file_frame(zmodem_t* zm, FILE* fp, int* type)
{ {
int result; int result;
unsigned n;
unsigned attempt; unsigned attempt;
/* /*
...@@ -2294,21 +2303,22 @@ int zmodem_recv_file_frame(zmodem_t* zm, FILE* fp, int* type) ...@@ -2294,21 +2303,22 @@ int zmodem_recv_file_frame(zmodem_t* zm, FILE* fp, int* type)
} }
do { do {
result = zmodem_recv_data(zm,zm->rx_data_subpacket,sizeof(zm->rx_data_subpacket), &n, /* ack */TRUE, type); unsigned len = 0;
result = zmodem_recv_data(zm,zm->rx_data_subpacket,sizeof(zm->rx_data_subpacket), &len, /* ack */TRUE, type);
/* fprintf(stderr,"packet len %d type %d\n",n,type); /* fprintf(stderr,"packet len %d type %d\n",n,type);
*/ */
if (result == ENDOFFRAME || result == FRAMEOK) { if (result == ENDOFFRAME || result == FRAMEOK) {
if(fwrite(zm->rx_data_subpacket,1,n,fp)!=n) { if(fwrite(zm->rx_data_subpacket, sizeof(uint8_t), len, fp) != len) {
lprintf(zm,LOG_ERR,"ERROR %d writing %u bytes at file offset %"PRIu64 lprintf(zm,LOG_ERR,"ERROR %d writing %u bytes at file offset %"PRIu64
,errno, n,(uint64_t)ftello(fp)); ,errno, len, (uint64_t)ftello(fp));
zmodem_send_pos_header(zm, ZFERR, (uint32_t)ftello(fp), /* Hex? */ TRUE); zmodem_send_pos_header(zm, ZFERR, (uint32_t)ftello(fp), /* Hex? */ TRUE);
return FALSE; return FALSE;
} }
} }
if(result == FRAMEOK) if(result == FRAMEOK)
zm->block_size = n; zm->block_size = len;
if(zm->progress!=NULL) if(zm->progress!=NULL)
zm->progress(zm->cbdata, ftello(fp)); zm->progress(zm->cbdata, ftello(fp));
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment