summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Vymetálek <pavel@vym.cz>2015-07-21 22:43:19 +0200
committerPavel Vymetálek <pavel@vym.cz>2015-07-21 22:43:19 +0200
commit0f4456a3280420cde1814ca3afc73d44ac364da0 (patch)
treeb6a58cf33537ce840dee3ce7f2fe4706a34747e9
parent671ad5d27057217faad7645ebacfdbe37b975794 (diff)
downloadtaptoserial-0f4456a3280420cde1814ca3afc73d44ac364da0.tar.gz
Přidáno čtení (dump) ze sériového portu do tap souboru.\n\nPřidán progress bar pro čtení.
-rw-r--r--taptoser.c321
1 files changed, 203 insertions, 118 deletions
diff --git a/taptoser.c b/taptoser.c
index 20b962e..1e0d4e0 100644
--- a/taptoser.c
+++ b/taptoser.c
@@ -8,6 +8,7 @@
#include <error.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
+#include <sys/signal.h>
#include <fcntl.h>
#define false 0
@@ -18,24 +19,35 @@
// SERIAL
char MODEMDEVICE[64];
-FILE *outfile = NULL;
+FILE *tapout_fd = NULL;
int is_outfile = 0;
int baud_rate = 0;
-#define FILENAME_LENGTH 2048
+#define FILENAME_LENGTH 400
char output_dump_file[FILENAME_LENGTH];
char tap_file[FILENAME_LENGTH];
+unsigned char in_buff[16386];
+unsigned char *p_buff;
+unsigned int is_reading = 1;
+
static int inp_indx = 0;
int serial_fd;
size_t out_indx;
+struct sigaction saterm; /* definition of signal action */
+
+
+// variables for progress bar
+unsigned int pos_progress;
float width, progress_pos, progress_part;
+long pos = 0;
void usage(void) {
printf ("Tap file serial port uploader/downloader. (c)2012 Pavel Vymetálek <pvymetalek@seznam.cz>\n");
- printf ("Usage:\ntaptoser [-v] [-h] [-o] [-b|--baud baud_rate] /dev/serial tap_file\n");
+ printf ("Usage:\ntaptoser [-v] [-h] [-o filename.tap] [-b|--baud baud_rate] -d /dev/serial tap_file\n");
printf ("\t-v, --version\tShow version info (program and protocol)\n");
printf ("\t-h, --help\tShow this text\n");
+ printf ("\t-d, --device\tCommunication device\n");
printf ("\t-b, --baud\tSet the communication speed. 9600Bd or 19200Bd are supported by ZX Spectrum\n");
printf ("\t-o, --outfile\tOutput to file, instead of stdout. Without coloring ESC sequences\n");
}
@@ -56,9 +68,9 @@ void TestCts(void) {
int status;
do {
ioctl(serial_fd, TIOCMGET, &status);
- usleep (100);
if (status & 0x20) break;
-// printf ("status: %X\n",status);
+ usleep (100);
+ // printf ("status: %X\n",status);
} while (1);
}
@@ -70,12 +82,13 @@ void TestArgs (int argc, char *argv[])
int option_index = 0;
static struct option long_options[] = {
{"outfile", required_argument, NULL, 'o'},
+ {"device", required_argument, NULL, 'd'},
{"baud", required_argument, NULL, 'b'},
{"version", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
{0, 0, 0, 0}
};
- c = getopt_long (argc, argv, "o:b:vh", long_options, &option_index);
+ c = getopt_long (argc, argv, "o:d:b:vh", long_options, &option_index);
if (c == -1)
// konec parametru
break;
@@ -88,8 +101,12 @@ void TestArgs (int argc, char *argv[])
case 'b':
baud_rate = atoi(optarg);
break;
+ case 'd':
+ strncpy(MODEMDEVICE, optarg, strlen(optarg));
+// printf ("Serial port: %s\n", MODEMDEVICE);
+ break;
case 'o':
- strncpy (&output_dump_file[0], optarg, FILENAME_LENGTH);
+ strncpy (output_dump_file, optarg, strlen(optarg));
is_outfile = 1;
break;
case 'v':
@@ -104,7 +121,6 @@ void TestArgs (int argc, char *argv[])
/* Done with options. OPTIND points to first nonoption argument. */
if (optind < argc) {
while (optind < argc){
- strncpy (&MODEMDEVICE[0], argv[optind++], 63);
strncpy (&tap_file[0], argv[optind++], 63);
}
}
@@ -130,11 +146,11 @@ void tooshort(FILE *fd)
exit(2);
}
+// decode header
void decode(unsigned char *header)
{
char name[11];
unsigned int n;
- unsigned int pos_progress;
strncpy(name, (char*)(header+2), 10);
name[10] = '\0';
@@ -170,35 +186,189 @@ void decode(unsigned char *header)
printf("\n");
}
-int main(int argc, char** argv, char** env)
-{
- FILE *fd;
- unsigned int err, no, l;
- long pos = 0;
+void signal_handler_sigterm (int status) {
+ is_reading = 0;
+// if (is_outfile) {
+// fclose (tapout_fd);
+// }
+// printf ("\n\nbye...\n");
+// exit (0);
+}
+
+int GetTerminalWidth(void) {
+ struct winsize termsize;
+ ioctl (STDOUT_FILENO, TIOCGWINSZ, &termsize);
+ return (termsize.ws_col);
+}
+
+void DoProgress(size_t pos, size_t max) {
+ width = GetTerminalWidth();
+ float percent, p, m;
+ int imax = width - 40;
+ int ipercent;
+ int px;
+ p = pos;
+ m = max;
+ percent = 100 / m * p;
+ ipercent = percent / 100 * imax;
+
+// printf ("\npercent: %f, ipercent: %d\n", percent, ipercent);
+ printf ("Received bytes: %6d/%6d [", (int) pos, (int)max);
+ for (px = 0; px < imax; px++) {
+ if (px < ipercent) printf ("=");
+ else printf (" ");
+ }
+ printf ("] %3d %%\r", (int)percent);
+ fflush (stdout);
+}
+
+void RecvTap() {
+ unsigned int err, len;
+ size_t total_len = 0, last_len = 0;
+ tapout_fd = fopen (output_dump_file, "a");
+ if (tapout_fd == NULL) {
+ err = errno;
+ error (1, err, "can't open output file");
+ }
+// if (is_outfile) {
+ printf("Output file is: %s\n", output_dump_file);
+// } else {
+// outfile = stdout;
+// }
+ while (is_reading) {
+ usleep (100000);
+ len = read (serial_fd, in_buff, 256);
+ p_buff = in_buff;
+ total_len += len;
+ p_buff += len;
+ while (len) {
+ fputc(*p_buff, tapout_fd);
+ p_buff++;
+ len--;
+ if (total_len != last_len) {
+ last_len = total_len;
+ DoProgress(total_len, 16384);
+ }
+ }
+ }
+ fclose (tapout_fd);
+
+ printf ("\n\nulozeno...\n");
+}
+
+void SendByte(unsigned char *p_dato) {
+ unsigned char dat;
+// TestCts();
+ // write byte to serial port
+ dat = *p_dato;
+ printf ("%2.2X ", dat);
+// write (serial_fd, p_dato, 1);
+// // tcdrain(serial_fd);
+ usleep (200);
+}
+
+void SendTap() {
+ FILE *tap_fd;
+ unsigned int err, no, len;
struct stat st;
unsigned char header[19];
- struct winsize termsize;
- ioctl (STDOUT_FILENO, TIOCGWINSZ, &termsize);
- printf ("width: %d \n", termsize.ws_col);
- width = termsize.ws_col;
+ no = stat(tap_file, &st);
+ if (no != 0) {
+ err = errno;
+ error(1, err, "can't stat input file");
+ }
+
+ tap_fd = fopen(tap_file, "r");
+ if (tap_fd == NULL) {
+ err = errno;
+ error(1, err, "can't open input file");
+ }
+
+ while (pos < st.st_size) {
+ pos += no = fread(header, 1, 2, tap_fd);
+ if (no != 2)
+ tooshort(tap_fd);
+ for (out_indx = 0; out_indx < 2; out_indx++) {
+ progress_pos = 0;
+ printf("[");
+ SendByte(&header[out_indx]);
+ }
+
+ no = getword(header);
+ if (no == 19) /* HEADER */
+ {
+ pos += no = fread(header, 1, 19, tap_fd);
+ if (no != 19)
+ tooshort(tap_fd);
+ printf ("NO header: %d\n", no);
+ decode(header);
+ for (out_indx = 0; out_indx < 19; out_indx++) {
+ SendByte(&header[out_indx]);
+ usleep (3000);
+ }
+ usleep (10000);
+ } else {
+ if (h_len != no - 2) /* zobrazuj iba bloky bez hl. */
+ {
+ len = no;
+ printf ("NO datablock without header: %d\n", no);
+ printf("Type: datablock\nLength: %u\n", len - 2);
+ pos += no = fread(header, 1, 1, tap_fd);
+ SendByte(header);
+ progress_part = h_len / width;
+ // for (progress_pos = 0; progress_pos < out_indx*progress_part; progress_pos++) {
+ // printf ("#\r");
+ // }
+
+ // usleep (1000);
+ if (no != 1) tooshort(tap_fd);
+ printf("Flag: %u\n\n", (int)*header);
+ len--;
+ }
+ else {
+ len = no;
+ }
+ pos += len;
+ // no = fseek(fd, pos, SEEK_SET);
+ // if (no != 0)
+ // {
+ // err = errno;
+ // error(1, err, "can't seek in input file");
+ // }
+ printf ("NO datablock: %d\n\n", len);
+ for (out_indx = 0; out_indx < len; out_indx++) {
+ fread(header, 1, 1, tap_fd);
+ SendByte(header);
+ // printf ("len: %5d\r", out_indx);
+ // usleep (621);
+ }
+ printf ("\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();
struct termios oldtio, newtio;
- int z;
inp_indx = 0;
if (argc < 3) {
printf("You must specify the Serial device and file\n");
usage();
exit(1);
}
+ printf ("tu som... \n");
TestArgs (argc, argv);
+
printf ("Serial device: %s, communication speed is: %d Bd\n", MODEMDEVICE, baud_rate);
- if (is_outfile) {
- outfile = fopen (output_dump_file, "a");
- printf("Output file is: %s\n", output_dump_file);
- } else {
- outfile = stdout;
- }
/* 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) {
@@ -228,99 +398,14 @@ int main(int argc, char** argv, char** env)
tcflush(serial_fd, TCIOFLUSH);
tcsetattr(serial_fd, TCSANOW, &newtio);
Set_DTR(true);
-
- no = stat(tap_file, &st);
- if (no != 0)
- {
- err = errno;
- error(1, err, "can't stat input file");
- }
-
- fd = fopen(tap_file, "r");
- if (fd == NULL)
- {
- err = errno;
- error(1, err, "can't open input file");
- }
-
- while (pos < st.st_size)
- {
-
- pos += no = fread(header, 1, 2, fd);
- if (no != 2)
- tooshort(fd);
- for (out_indx = 0; out_indx < 2; out_indx++) {
- TestCts();
- progress_pos = 0;
-
- printf("[");
- write (serial_fd, &header[out_indx], 1);
- usleep (200);
- }
-
- no = getword(header);
- if (no == 19) /* HEADER */
- {
- pos += no = fread(header, 1, 19, fd);
- if (no != 19)
- tooshort(fd);
- printf ("NO header: %d\n", no);
- decode(header);
- for (out_indx = 0; out_indx < 19; out_indx++) {
- TestCts();
- write (serial_fd, &header[out_indx], 1);
- usleep (3000);
- }
- usleep (10000);
-
- } else {
- if (h_len != no - 2) /* zobrazuj iba bloky bez hl. */
- {
- l = no;
- printf ("NO datablock without header: %d\n", no);
- printf("Type: datablock\nLength: %u\n", l - 2);
- pos += no = fread(header, 1, 1, fd);
- TestCts();
- write (serial_fd, header, 1);
- progress_part = h_len / width;
-
-// for (progress_pos = 0; progress_pos < out_indx*progress_part; progress_pos++) {
-// printf ("#\r");
-// }
-
- usleep (1000);
- if (no != 1)
- tooshort(fd);
- printf("Flag: %u\n\n", (int)*header);
- l--;
- }
- else
- {
- l = no;
- }
-
- pos += l;
-
-
-
-// no = fseek(fd, pos, SEEK_SET);
-// if (no != 0)
-// {
-// err = errno;
-// error(1, err, "can't seek in input file");
-// }
- printf ("NO datablock: %d\n\n", l);
- for (out_indx = 0; out_indx < l; out_indx++) {
- fread(header, 1, 1, fd);
- TestCts();
- write (serial_fd, header, 1);
-// printf ("len: %5d\r", out_indx);
- usleep (621);
- }
- printf ("\n");
- }
+
+ if (is_outfile) {
+ // cteni souboru ze seriaku
+ RecvTap();
+ } else {
+ // poslat na seriak tap soubor
+ SendTap();
}
-
- fclose(fd);
+ close (serial_fd);
return 0;
}