From fc1b66cc509b1a38a0733049cc522acc921f521a Mon Sep 17 00:00:00 2001 From: Pavel Vymetálek Date: Tue, 19 Feb 2019 15:43:42 +0100 Subject: sercp možno přeložit pro Win64 a Win32 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - přidán soubor sercp.res s podpisem exáče :-) --- Makefile | 14 ++- sercp.c | 356 ++++++++++++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 295 insertions(+), 75 deletions(-) diff --git a/Makefile b/Makefile index 9bcd37f..4178903 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,21 @@ PROJECT=sercp -all: $(PROJECT) +all: $(PROJECT) $(PROJECT).w32 $(PROJECT).w64 sercp: $(PROJECT).c gcc $(PROJECT).c -o $(PROJECT) -Wall -pedantic -MP -MD -std=gnu11 -Werror=format-security -O2 +sercp.w64: $(PROJECT).c + rm -f $(PROJECT).res + x86_64-w64-mingw32-windres -i $(PROJECT).rc --input-format=rc --codepage=65001 -o $(PROJECT).res -O coff + x86_64-w64-mingw32-gcc $(PROJECT).c $(PROJECT).res -o $(PROJECT).exe -Wall -pedantic -MP -MD -std=gnu11 -Werror=format-security -O2 + x86_64-w64-mingw32-strip $(PROJECT).exe + +sercp.w32: $(PROJECT).c + rm -f $(PROJECT).res + i686-w64-mingw32-windres -i $(PROJECT).rc --input-format=rc --codepage=65001 -o $(PROJECT).res -O coff + i686-w64-mingw32-gcc $(PROJECT).res $(PROJECT).c -o $(PROJECT)32.exe -Wall -pedantic -MP -MD -std=gnu11 -Werror=format-security -O2 + i686-w64-mingw32-strip $(PROJECT)32.exe + debug: $(PROJECT).c gcc $(PROJECT).c -o $(PROJECT) -Wall -pedantic -MP -MD -std=gnu11 -Werror=format-security -g -O0 diff --git a/sercp.c b/sercp.c index 545f725..33edcc7 100644 --- a/sercp.c +++ b/sercp.c @@ -1,19 +1,45 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include + + +#ifdef __WIN32 +// #include +// #include +// #include +// #include + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + +#else + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include +#endif + #define false 0 #define FALSE 0 @@ -22,7 +48,6 @@ const char* _version = "v0.2"; // SERIAL -char MODEMDEVICE[64]; FILE *tapout_fd = NULL; int is_outfile = 0; int baud_rate = 0; @@ -34,18 +59,33 @@ unsigned char buff[32768]; unsigned char *p_buff; unsigned int is_continue = 1; unsigned int is_binary = 0; -struct pollfd spolfd_serial[1]; // pole descriptoru pro poll static int inp_indx = 0; -int serial_fd; -size_t out_indx; -struct sigaction saterm; /* definition of signal action */ +size_t out_indx; float width; // width of terminal long pos = 0; int scp = 0; int is_scp_read = 0; +char MODEMDEVICE[64] = { +#ifdef __WIN32 + "\\\\.\\COM1" +#else + "/dev/ttyUSB0" +#endif +}; + +#ifdef __WIN32 + static HANDLE serial_fd; +#else + int serial_fd; + struct sigaction saterm; /* definition of signal action */ + struct pollfd spolfd_serial[1]; // pole descriptoru pro poll +#endif + + + typedef struct { uint16_t block_len; uint8_t block_xor; @@ -72,7 +112,11 @@ void usage(void) { printf ("Usage:\nsercp [-v] [-h] -d /dev/serial [-b baud_rate] [-w time] [-r] \n"); printf ("\t-v, --version\tShow version info\n"); printf ("\t-h, --help\tShow this text\n"); - printf ("\t-d, --device\tCommunication device\n"); +#ifdef __WIN32 + printf ("\t-d, --device\tSerial com port\n"); +#else + printf ("\t-d, --device\tSerial communication device\n"); +#endif printf ("\t-b, --baud\tSet the communication speed. Default 38400Bd\n"); printf ("\t-w, --wait\tWaiting in milliseconds between transmitted blocks. Default is -w 800 milliseconds\n"); printf ("\t-r, --read\tRead file from serial port\n"); @@ -101,8 +145,13 @@ void TestArgs (int argc, char *argv[]) } switch (c) { case 'd': - strncpy(MODEMDEVICE, optarg, strlen(optarg)); - // printf ("Serial port: %s\n", MODEMDEVICE); +#ifdef __WIN32 + sprintf(MODEMDEVICE, "\\\\.\\%s", optarg); +#else +// strncpy(MODEMDEVICE, optarg, strlen(optarg)); + sprintf(MODEMDEVICE, "%s", optarg); +#endif + printf ("Serial port: %s\n", MODEMDEVICE); break; case 'b': baud_rate = atoi(optarg); @@ -134,8 +183,42 @@ void TestArgs (int argc, char *argv[]) } -/************************************************************************/ +//***************************************************************************** +// +// uSleep win32 implementation + +void uSleep(int waitTime) { + #ifdef __WIN32 + __int64 time1 = 0, time2 = 0, freq = 0; + + QueryPerformanceCounter((LARGE_INTEGER *) &time1); + QueryPerformanceFrequency((LARGE_INTEGER *)&freq); + + do { + QueryPerformanceCounter((LARGE_INTEGER *) &time2); + } while ((time2 - time1) < waitTime); + #else + uSleep(waitTime); + #endif +} + +// cross-platform sleep function +void sleep_ms(int milliseconds) { +#ifdef WIN32 + Sleep(milliseconds); +// #elif _POSIX_C_SOURCE >= 199309L +// struct timespec ts; +// ts.tv_sec = milliseconds / 1000; +// ts.tv_nsec = (milliseconds % 1000) * 1000000; +// nanosleep(&ts, NULL); +#else + usleep(milliseconds * 1000); +#endif +} + + +/************************************************************************/ void signal_handler_sigterm (int status) { // CTRL+C pressed is_continue = 0; // do not continue @@ -143,9 +226,13 @@ void signal_handler_sigterm (int status) { /************************************************************************/ int GetTerminalWidth(void) { +#ifdef __WIN32 + return (80); +#else struct winsize termsize; ioctl (STDOUT_FILENO, TIOCGWINSZ, &termsize); return (termsize.ws_col); +#endif } #define PROGRESS_PERCENT 0 @@ -265,7 +352,7 @@ uint32_t GetOverallLen(FILEINFO *p_fi) { } /************************************************************************/ -void RecvSCP(void) { +void sercpRecv(void) { int recv_phase = 0; // 0 - fileinfo, 1 - blok 16kiB, 2 - posledni blok uint8_t block_index = 0; int result; @@ -277,6 +364,7 @@ void RecvSCP(void) { uint32_t overall_length = 0; // celkova delka souboru uint32_t recv_length = 0; // zatim prijatych dat ze souboru int err; + unsigned long ulNumBytes; FILEINFO *p_fileinfo = &fileinfo; unsigned char *p_buff = buff; @@ -284,16 +372,25 @@ void RecvSCP(void) { memset (p_fileinfo, 0, sizeof(fileinfo)); while (is_continue) { + #ifndef __WIN32 result = poll (spolfd_serial, 1, 200); // 200ms timeout if (result == 0) { // nic neprislo continue; } + #endif switch (recv_phase) { case 0: // prijem fileinfo - if (spolfd_serial[0].revents & POLLIN) { +// if (spolfd_serial[0].revents & POLLIN) { +#ifdef __WIN32 + sleep_ms(10); + ReadFile(serial_fd, p_buff, sizeof(fileinfo), &ulNumBytes, NULL); + len = (uint16_t) ulNumBytes; +#else + sleep_ms(10); len = read (serial_fd, p_buff, sizeof(fileinfo)); +#endif p_buff += len; length += len; if (length == sizeof(fileinfo)) { @@ -307,12 +404,16 @@ void RecvSCP(void) { p_buff = buff; // buffer na zacatek length = 0; expected_len = p_fileinfo->fi_blocks[block_index].block_len; - - - tapout_fd = fopen ((char*)p_fileinfo->fi_name, "w"); + tapout_fd = fopen ((char*)p_fileinfo->fi_name, "wb"); if (tapout_fd == NULL) { err = errno; + #ifdef __WIN32 + printf ("can't open output file"); + exit (EXIT_FAILURE); + + #else error (1, err, "can't open output file"); + #endif } } else { printf("Fileinfo neni v cajku. Koncim...\n"); @@ -320,16 +421,30 @@ void RecvSCP(void) { } break; } else if (length > sizeof(fileinfo)){ +#ifdef __WIN32 + ReadFile(serial_fd, p_buff, sizeof(fileinfo), &ulNumBytes, NULL); + len = (uint16_t)ulNumBytes; +#else + len = read (serial_fd, p_buff, sizeof(fileinfo)); +#endif printf("Nejaky bordel. Koncim...\n"); break; } - } +// } break; case 1: // prijem datoveho bloku - max. delka 16kiB - if (spolfd_serial[0].revents & POLLIN) { +// if (spolfd_serial[0].revents & POLLIN) { +#ifdef __WIN32 + ReadFile(serial_fd, p_buff, expected_len, &ulNumBytes, NULL); + len = (uint16_t)ulNumBytes; + sleep_ms(10); +#else len = read (serial_fd, p_buff, expected_len); + sleep_ms(10); +#endif +// printf ("read len: %d\n", len); p_buff += len; expected_len -= len; length += len; @@ -353,19 +468,28 @@ void RecvSCP(void) { is_continue = 0; break; } - } else if (length > 16384) { - len = read (serial_fd, p_buff, 16384); - printf("Nejaky bordel. Koncim...\n"); - break; - } +// } + /*else if (length > 16384) { +#ifdef __WIN32 + ReadFile(serial_fd, p_buff, 16384, &ulNumBytes, NULL); + len = (uint16_t)ulNumBytes; +#else + len = read (serial_fd, p_buff, 16384); +#endif + printf("Nejaky bordel. Koncim...\n"); + break; + }*/ } } - if (tapout_fd) fclose (tapout_fd); + if (tapout_fd) { + fflush (tapout_fd); + fclose (tapout_fd); + } printf ("\n\nulozeno...\n"); } /************************************************************************/ -void SendSCP(void) { +void sercpSend(void) { FILE *tap_fd; char *bname, *basec; // pinter na kopii nazvu souboru - basename char *shortfilename; @@ -380,18 +504,23 @@ void SendSCP(void) { uint32_t len_sent; uint16_t sent_size; uint32_t overall_sent; + unsigned long ulNumBytes; no = stat(sercp_file, &st); if (no != 0) { err = errno; - error(1, err, "can't stat input file"); +// error(1, err, "can't stat input file"); + printf ("can't stat input file\n"); + exit (EXIT_FAILURE); } - tap_fd = fopen(sercp_file, "r"); + tap_fd = fopen(sercp_file, "rb"); if (tap_fd == NULL) { err = errno; - error(1, err, "can't open input file"); +// error(1, err, "can't open input file"); + printf ("can't open input file\n"); + exit (EXIT_FAILURE); } if (st.st_size == 0) { printf ("Zero length of file. End\n"); @@ -424,11 +553,16 @@ void SendSCP(void) { p_fileinfo->fi_numblocks = num_blocks; p_fileinfo->length = num_blocks*4 + 85; CountFileInfoChecksum(p_fileinfo); +#ifdef __WIN32 + WriteFile(serial_fd, (void*)p_fileinfo, sizeof(fileinfo), &ulNumBytes, NULL); +#else odeslano = write (serial_fd, (void*)p_fileinfo, sizeof(fileinfo)); tcdrain(serial_fd); +#endif printf("Fileinfo sent with filename: %s\n", bname); // TODO Cekat pauzu mezi bloky - usleep (wait_ms * 1000); +// uSleep (wait_ms * 1000); + sleep_ms(wait_ms); rewind(tap_fd); // prenaseny soubor na zacatek file_len = (uint32_t) st.st_size; @@ -439,8 +573,14 @@ void SendSCP(void) { sent_size = 256; len_sent = len; while (len_sent && is_continue) { +#ifdef __WIN32 + WriteFile(serial_fd, (void*)p_buff, sent_size, &ulNumBytes, NULL); + odeslano = (size_t)ulNumBytes; +// sleep_ms(wait_ms); +#else odeslano = write (serial_fd, (void*)p_buff, sent_size); tcdrain(serial_fd); +#endif p_buff += odeslano; overall_sent += odeslano; len_sent -= odeslano; @@ -449,32 +589,57 @@ void SendSCP(void) { } DoProgress(overall_sent, st.st_size, PROGRESS_PERCENT); } - usleep (wait_ms * 1000); +// uSleep (wait_ms * 1000); + sleep_ms(wait_ms); + file_len -= len; } printf("\nFile sent...\n"); fclose(tap_fd); } -/************************************************************************/ -/************************************************************************/ -int main(int argc, char** argv, char** env) -{ - // osetreni breaku ^C - saterm.sa_handler = signal_handler_sigterm; - saterm.sa_flags = 0; - sigaction (SIGINT, &saterm, NULL); - width = GetTerminalWidth(); +int OpenUart() { +#ifdef __WIN32 + DCB sDCB; + COMMTIMEOUTS sCommTimeouts; - // nastaveni serioveho portu - struct termios oldtio, newtio; - inp_indx = 0; - if (argc < 2) { - printf("You must specify the Serial device and file\n"); - usage(); - exit(1); + serial_fd = CreateFile(MODEMDEVICE, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + if (serial_fd == INVALID_HANDLE_VALUE) { + return (-1); } - TestArgs (argc, argv); + if (GetCommState(serial_fd, &sDCB) == 0) { + return (-1); + } + if (baud_rate == 0) baud_rate = 38400; + sDCB.BaudRate = baud_rate; + sDCB.ByteSize = 8; + sDCB.Parity = NOPARITY; + sDCB.fBinary = TRUE; + sDCB.StopBits = ONESTOPBIT; + sDCB.fAbortOnError = TRUE; + sDCB.fOutxCtsFlow = FALSE; + sDCB.fOutxDsrFlow = FALSE; +// sDCB.fDtrControl = DTR_CONTROL_ENABLE; + if (SetCommState(serial_fd, &sDCB) == 0) { + return (-1); + } + + if (GetCommTimeouts(serial_fd, &sCommTimeouts) == 0) { + return (-1); + } + + sCommTimeouts.ReadIntervalTimeout = MAXDWORD; //80 + sCommTimeouts.ReadTotalTimeoutConstant = 00; + sCommTimeouts.ReadTotalTimeoutMultiplier = 00; + sCommTimeouts.WriteTotalTimeoutConstant = 80; + sCommTimeouts.WriteTotalTimeoutMultiplier = 80; + + if (SetCommTimeouts(serial_fd, &sCommTimeouts) == 0) { + return (-1); + } + return (0); +#else + struct termios oldtio, newtio; /* open the device to be non-blocking (read will return immediatly) */ serial_fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK); if (serial_fd < 0) { @@ -484,33 +649,33 @@ int main(int argc, char** argv, char** env) tcgetattr(serial_fd, &oldtio); /* save current port settings */ switch (baud_rate){ case 115200: - newtio.c_cflag = B115200 | CS8 | CLOCAL | CREAD; + newtio.c_cflag = B115200; break; case 57600: - newtio.c_cflag = B57600 | CS8 | CLOCAL | CREAD; + newtio.c_cflag = B57600; break; default: baud_rate = 38400; case 38400: - newtio.c_cflag = B38400 | CS8 | CLOCAL | CREAD; // dva stopbity jsou nastaveny vsude, ale tady ne + newtio.c_cflag = B38400; break; case 19200: - newtio.c_cflag = B19200 | CS8 | CLOCAL | CREAD; + newtio.c_cflag = B19200; break; case 9600: - newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD; + newtio.c_cflag = B9600; break; case 4800: - newtio.c_cflag = B4800 | CS8 | CLOCAL | CREAD; + newtio.c_cflag = B4800; break; case 2400: - newtio.c_cflag = B2400 | CS8 | CLOCAL | CREAD; + newtio.c_cflag = B2400; break; case 1200: - newtio.c_cflag = B1200 | CS8 | CLOCAL | CREAD; + newtio.c_cflag = B1200; break; } - newtio.c_cflag |= CRTSCTS; // CSTOPB - dva stop bity NEE + newtio.c_cflag |= CS8 | CLOCAL | CREAD | CRTSCTS; // CSTOPB - dva stop bity NEE printf ("Serial device: %s, communication speed is: %d Bd\n", MODEMDEVICE, baud_rate); newtio.c_iflag = 0; newtio.c_oflag = 0; @@ -519,15 +684,58 @@ int main(int argc, char** argv, char** env) newtio.c_cc[VTIME] = 10; tcsetattr(serial_fd, TCSANOW, &newtio); tcflush(serial_fd, TCIOFLUSH); + return 0; +#endif +} + +void CloseUart() { + if (serial_fd) { +#ifdef __WIN32 + CloseHandle(serial_fd); +#else + close (serial_fd); +#endif + } +} + + + +/************************************************************************/ +/************************************************************************/ +int main(int argc, char** argv, char** env) +{ +#ifndef __WIN32 + // osetreni breaku ^C v unixech + saterm.sa_handler = signal_handler_sigterm; + saterm.sa_flags = 0; + sigaction (SIGINT, &saterm, NULL); +#endif + width = GetTerminalWidth(); + + // nastaveni serioveho portu + inp_indx = 0; + if (argc < 2) { + printf("You must specify the Serial device and file\n"); + usage(); + exit(1); + } + TestArgs (argc, argv); + + if (OpenUart() == -1) { + printf ("Can't open serial port\n"); + exit (EXIT_FAILURE); + } + + #ifndef __WIN32 spolfd_serial[0].fd = serial_fd; // nastaveni hlidaneho descriptoru spolfd_serial[0].events = POLLIN; // hlidaji se data na vstupu - + #endif // serial copy activated if (is_scp_read) { - RecvSCP(); + sercpRecv(); } else { - SendSCP(); + sercpSend(); } - close (serial_fd); + CloseUart(); return 0; } -- cgit