From 4c85cd016e7972f7affcff1f8a245b895886b69a Mon Sep 17 00:00:00 2001 From: Pavel Vymetálek Date: Tue, 16 Jan 2024 14:04:28 +0100 Subject: Add checking of ack messages --- TODO | 4 ++-- sercp.c | 52 +++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/TODO b/TODO index d560927..bc4625c 100644 --- a/TODO +++ b/TODO @@ -2,7 +2,7 @@ - check Ack messages properly 2023-07-29 - - add support for ack of messages + + add support for ack of messages 2020-04-05 + for short files < 256 bytes does not work the progressbar - underflow counter @@ -31,11 +31,11 @@ VÝHODY * funguje :-) * nejrychlejší způsob jak dostat do ZX malý soubor * nepotřebuje PC - přenos mezi dvěma Spectry ++ nastavuje datum a čas souboru - esxdosu má api utime() NEVÝHODY * nemá LFN (esxdos) - ale sercp je na to připraven :-) -* nenastavuje datum a čas souboru - esxdosu chybí api * nejde obnovit přenos * zatím není na ZX psáno portabilně - na jiné diskové systémy diff --git a/sercp.c b/sercp.c index 683ec00..f01fe2e 100644 --- a/sercp.c +++ b/sercp.c @@ -106,7 +106,7 @@ char SERIALDEVICE[128] = { static HANDLE serial_fd; #else int serial_fd; - struct sigaction saterm; /* definition of signal action */ + // struct sigaction saterm; /* definition of signal action */ struct pollfd spolfd_serial[1]; // pole descriptoru pro poll #endif @@ -396,14 +396,13 @@ uint32_t GetOverallLen(FILEINFO *p_fi) { return overall_len; } -void sendFileinfoAck(void) { +void sendAckFileinfo(void) { uint8_t fi_ack_buffer[] = {'A','c','k',0, 0x49, 0x0F}; #ifdef _WIN32 unsigned long ulNumBytes; WriteFile(serial_fd, (void*)fi_ack_buffer, sizeof(fi_ack_buffer), &ulNumBytes, NULL); #else - size_t odeslano; - odeslano = write (serial_fd, (void*)fi_ack_buffer, sizeof(fi_ack_buffer)); + write (serial_fd, (void*)fi_ack_buffer, sizeof(fi_ack_buffer)); if (tcdrain(serial_fd) == -1) { perror("tcdrain err1: "); return; @@ -411,8 +410,8 @@ uint8_t fi_ack_buffer[] = {'A','c','k',0, 0x49, 0x0F}; #endif } -void sendBlockAck(uint8_t block_num) { - uint8_t fi_ack_buffer[] = {'A','C','K',0, 0x49, 0x0F}; +void sendAckBlock(uint8_t block_num) { + uint8_t fi_ack_buffer[] = {'A','C','K',0, 0x49, 0xCF}; int x; uint8_t s_xor = 0; uint8_t s_sum = 0; @@ -431,8 +430,7 @@ void sendBlockAck(uint8_t block_num) { unsigned long ulNumBytes; WriteFile(serial_fd, (void*)fi_ack_buffer, sizeof(fi_ack_buffer), &ulNumBytes, NULL); #else - size_t odeslano; - odeslano = write (serial_fd, (void*)fi_ack_buffer, sizeof(fi_ack_buffer)); + write (serial_fd, (void*)fi_ack_buffer, sizeof(fi_ack_buffer)); if (tcdrain(serial_fd) == -1) { perror("tcdrain err1: "); return; @@ -442,7 +440,7 @@ void sendBlockAck(uint8_t block_num) { uint8_t buf_ack[8]; -uint8_t* WaitReadAck(void) { +uint8_t WaitReadAck(void) { size_t len = 0; #ifdef _WIN32 unsigned long ulNumBytes =0; @@ -478,17 +476,41 @@ uint8_t* WaitReadAck(void) { } } #endif - return (buf_ack); + return (len); } // receive fileinfo ACK +int CheckAckSum() { + int x; + uint8_t xorsum = 0; + uint8_t sumsum = 0; + for (x = 0; x < 4; x++) { + sumsum += buf_ack[x]; + xorsum ^= buf_ack[x]; + } + if ((xorsum == buf_ack[4]) && (sumsum == buf_ack[5])) { + return 0; + } else { + return 1; + } +} void RecvAckFileinfo(void) { - WaitReadAck(); + if (WaitReadAck() == 6) { + if (CheckAckSum()) { + printf("\nErr Ack fileinfo\n"); + exit(-1); + }; + }; sleep_ms(100); // 100ms to wait speccy } void RecvAckBlock(uint8_t block_number) { - WaitReadAck(); + if (WaitReadAck() == 6) { + if (CheckAckSum() || (buf_ack[3] != block_number)) { + printf("\nErr ACK block\n"); + exit(-1); + } + } sleep_ms(100); // 100ms to wait speccy } @@ -527,7 +549,7 @@ void sercpRecv(void) { // receive fileinfo #ifdef _WIN32 sleep_ms(10); - ReadFile(serial_fd, p_buff, sizeof(fileinfo), &ulNumBytes, NULL); + ReadFile(serial_fd, p_buff, sizeof(fileinfo)-length, &ulNumBytes, NULL); len = (size_t) ulNumBytes; #else sleep_ms(10); @@ -547,7 +569,7 @@ void sercpRecv(void) { expected_len = p_fileinfo->fi_blocks[block_index].block_len; // TODO Send FileinfoAck sleep_ms(100); - sendFileinfoAck(); + sendAckFileinfo(); tapout_fd = fopen ((char*)p_fileinfo->fi_name, "wb"); if (tapout_fd == NULL) { #ifdef _WIN32 @@ -600,7 +622,7 @@ void sercpRecv(void) { if (tapout_fd) fwrite(buff, length, 1, tapout_fd); // TODO sleep_ms(100); - sendBlockAck(block_index); + sendAckBlock(block_index); } length = 0; p_buff = buff; -- cgit