aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Vymetálek <pavel@vym.cz>2019-02-19 15:43:42 +0100
committerPavel Vymetálek <pavel@vym.cz>2019-02-19 15:43:42 +0100
commitfc1b66cc509b1a38a0733049cc522acc921f521a (patch)
treea2e02bccaf622db954ee88b92afdb90c0fdffec7
parent763b0e4a17aad661705ed333f57cb989b5ac31c3 (diff)
downloadsercp-pc-fc1b66cc509b1a38a0733049cc522acc921f521a.tar.gz
sercp možno přeložit pro Win64 a Win32
- přidán soubor sercp.res s podpisem exáče :-)
-rw-r--r--Makefile14
-rw-r--r--sercp.c356
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 <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <stdint.h>
-#include <libgen.h>
-#include <getopt.h>
-#include <termios.h>
-#include <error.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/signal.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <poll.h>
+
+
+#ifdef __WIN32
+// #include <stdio.h>
+// #include <unistd.h>
+// #include <stdlib.h>
+// #include <string.h>
+
+ #include <stdio.h>
+ #include <stdint.h>
+ #include <io.h>
+ #include <fcntl.h>
+ #include <windows.h>
+ #include <getopt.h>
+ #include <signal.h>
+ #include <fcntl.h>
+ #include <errno.h>
+ #include <unistd.h>
+ #include <libgen.h>
+ #include <sys/stat.h>
+ #include <error.h>
+
+#else
+
+ #include <stdio.h>
+ #include <unistd.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <errno.h>
+ #include <stdint.h>
+ #include <libgen.h>
+ #include <getopt.h>
+ #include <termios.h>
+ #include <error.h>
+ #include <sys/stat.h>
+ #include <sys/ioctl.h>
+ #include <sys/signal.h>
+ #include <signal.h>
+ #include <fcntl.h>
+ #include <poll.h>
+#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] <filename>\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;
}