diff options
| author | Pavel Vymetálek <pavel@vym.cz> | 2019-02-07 17:05:56 +0100 | 
|---|---|---|
| committer | Pavel Vymetálek <pavel@vym.cz> | 2019-02-07 17:05:56 +0100 | 
| commit | aee21c54320a5e85153314e8f4efdb7bea67e762 (patch) | |
| tree | 0d717b1336035249a216203ef99271cf82728b8c | |
| download | sercp-pc-aee21c54320a5e85153314e8f4efdb7bea67e762.tar.gz | |
První commit: vychází se z programu taptoser
| -rw-r--r-- | Makefile | 8 | ||||
| -rw-r--r-- | sercp.c | 786 | 
2 files changed, 794 insertions, 0 deletions
| diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ffe0501 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +PROJECT=sercp +all: +	gcc $(PROJECT).c -o $(PROJECT) -Wall -pedantic -MP -MD -std=gnu11 -Werror=format-security -O2 +debug: +	gcc $(PROJECT).c -o $(PROJECT) -Wall -pedantic -MP -MD -std=gnu11 -Werror=format-security -g -O0 + +clean: +	rm -f $(PROJECT) $(PROJECT).d $(PROJECT).o @@ -0,0 +1,786 @@ +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <stdint.h> +#include <getopt.h> +#include <termios.h> +#include <error.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/signal.h> +#include <fcntl.h> +#include <poll.h> + +#define false 0 +#define FALSE 0 +#define true 1 +#define TRUE 1 + + +// SERIAL +char MODEMDEVICE[64]; +FILE *tapout_fd = NULL; +int is_outfile = 0; +int baud_rate = 0; +int wait_us = 200; +int wait_ms	= 800; +#define FILENAME_LENGTH 400 +char output_dump_file[FILENAME_LENGTH]; +char tap_file[FILENAME_LENGTH]; +unsigned char in_buff[65538]; +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 */ + +float width;		// width of terminal +long pos = 0; +int scp = 0; +int is_scp_read = 0; + +typedef struct { +	uint16_t block_len; +	uint8_t  block_xor; +	uint8_t  block_sum; +} __attribute__((packed))  fi_sum; + +typedef struct { +	uint16_t length;		// delka dat ve fileinfo +	uint8_t h_xor;			// xor bajtu fileinfa od fi_numblocks +	uint8_t h_sum;			// sum bajtu fileinfa od fi_numblocks +	uint8_t fi_numblocks;	// pocet bloku +	uint8_t fi_name[64];	// jmeno souboru - prozatim musi byt ve fromatu 8.3 - kvuli esxdosu +	uint8_t fi_date[8];		// nepouzito +	uint8_t fi_time[8];		// nepouzito +	fi_sum fi_blocks[256];	// delky a soucty bloku +} __attribute__((packed)) FILEINFO; + +FILEINFO fileinfo; + + +void usage(void) { +	printf ("Tap file over serial port uploader/downloader. (c)2012-2015 Pavel Vymetálek <pavel@vym.cz>\n"); +	printf ("Based on utility tapheader: http://zeroteam.sk/tapheader.html (c)2012 Michal Jurica <mike@zeroteam.sk>\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\n"); +	printf ("\t-h, --help\tShow this text\n"); +	printf ("\t-d, --device\tCommunication device\n"); +	printf ("\t-w, --wait\tWaiting in microseconds between transmitted bytes. Default is -w 200us\n"); +	printf ("\t-b, --baud\tSet the communication speed. 4800Bd, 9600Bd, 19200Bd and 57600Bd (default) are supported\n"); +	printf ("\t-B, --binary\tBinary output - received tap from ZX Spectrum will save without all tap's specific mishmash\n"); +	printf ("\t-o, --outfile\tOutput file. Usualy *.tap or *.bin with in --binary mode\n"); +	printf ("SCP mode -----\n"); +	printf ("\t-s, --scp\tSCP mode - sent files with fileinfo 1109bytes\n"); +	printf ("\t-r, --read\tread file\n"); +	printf ("\t-w, --wait\tWaiting in milliseconds between transmitted blocks. Default is -w 800 milliseconds\n"); +} + +void Set_DTR(unsigned short level) { +	int status; +	ioctl(serial_fd, TIOCMGET, &status); +	if (level) { +		status |= TIOCM_DTR; +	} else { +		status &= ~TIOCM_DTR; +	} +	ioctl(serial_fd, TIOCMSET, &status); +} + +void TestCts(void) { +	int status; +	do { +		ioctl(serial_fd, TIOCMGET, &status); +		if (status & 0x20) break; +		usleep (100); +		if (is_continue == 0) return; +		//		printf ("status: %X\n",status); +	} while (1); +} + + +void TestArgs (int argc, char *argv[]) +{ +	int c; +	while (1) { +		int option_index = 0; +		static struct option long_options[] = { + 			{"outfile", required_argument, NULL, 'o'}, +			{"device", required_argument, NULL, 'd'}, +			{"baud", required_argument, NULL, 'b'}, +			{"wait", required_argument, NULL, 'w'}, +			{"scp", no_argument, NULL, 's'}, +			{"read", no_argument, NULL, 'r'}, +			{"binary", no_argument, NULL, 'B'}, +			{"version", no_argument, NULL, 'v'}, +			{"help", no_argument, NULL, 'h'}, +			{0, 0, 0, 0} +		}; +		c = getopt_long (argc, argv, "o:d:b:w:srBvh", long_options, &option_index); +		if (c == -1) { +			// konec parametru +			break; +		} +		switch (c) { +			case 'h': +				usage(); +				exit(1); +				break; +			case 'b': +				baud_rate = atoi(optarg); +				break; +			case 'w': +				wait_us = atoi(optarg); +				wait_ms = atoi(optarg); +				break; +			case 's': +				printf ("Serial CP mode is activated\n"); +				scp = 1; +				break; +			case 'r': +				printf ("scp read...\n"); +				is_scp_read = 1; +				break; +			case 'd': +				strncpy(MODEMDEVICE, optarg, strlen(optarg)); +// 				printf ("Serial port: %s\n", MODEMDEVICE); +				break; +			case 'o': +				strncpy (output_dump_file, optarg, strlen(optarg)); +				is_outfile = 1; +				break; +			case 'B': +				printf ("Running in binary output mode\n"); +				is_binary = 1; +				break; +			case 'v': +				printf ("Version 0.9.1 2015-07-22\n"); +				exit(1); +				break; +			default: +				break; +		} +	} +	if (optind < argc) { +		while (optind < argc){ +			strncpy (&tap_file[0], argv[optind++], 63);		// input tap file name - without option switch +		} +	} +} + + +// from tapheader utility +unsigned int h_len; + +unsigned int getword(unsigned char* data) { +	return *data + 256 * (*(data + 1)); +} + +void tooshort(FILE *fd) { +	printf("Input file too short.\n\n"); +	fclose(fd); +	exit(2); +} + +// decode header1 +void decode(unsigned char *header) { +	char name[11]; +	unsigned int n; +	printf("\n"); +	strncpy(name, (char*)(header+2), 10); +	name[10] = '\0'; +	printf("Filename: %12s \n", name); +	printf("Flag: %4u ", (unsigned int)*header); +	n = getword(header+14); +	h_len = getword(header+12); + +	switch(*(header+1)) { +		case '\0': +			printf("Type: 0 => program\nProgram length: %6u bytes ", h_len); +			if (n < 32768)	printf("Runs from line %5u\t", n); +			printf("Length without variables: %5u bytes ", getword(header+16)); +			break; +		case '\1': +			printf("Type: 1 => number array\tLength: %6u bytes", h_len); +			break; +		case '\2': +			printf("Type: 2 => character array\tLength: %6u bytes", h_len); +			break; +		case '\3': +			if (n == 16384 && h_len == 6912) +				printf("Type: 3 => screen image\n"); +			else +				printf("Type: 3 => bytes  " +					"Start address: %5u\t" +					"Length: %6u bytes\t3rd param: %4u", +					n, h_len, getword(header+16)); +			break; +	} +	printf("\n"); +} + +void signal_handler_sigterm (int status) { +	// CTRL+C pressed +	is_continue = 0; 	// do not continue +} + +int GetTerminalWidth(void) { +	struct winsize termsize; +	ioctl (STDOUT_FILENO, TIOCGWINSZ, &termsize); +	return (termsize.ws_col); +} + +#define PROGRESS_PERCENT	0 +#define PROGRESS_COMPLETTE	1 +#define PROGRESS_ERROR_CSUM	2 + +void DoProgress(size_t pos, size_t max, unsigned char csum_ok) { +	width = GetTerminalWidth(); +	float percent, p, m; +	int imax = width - 40; +	int ipercent; +	int px; +	char progress_char; +	p = pos; +	m = max; +	percent = 100 / m * p; +	ipercent = percent / 100 * imax; +	if (is_binary) progress_char = '#'; +	else  progress_char = '='; +	printf ("Proceed bytes: %6d/%6d [", (int) pos, (int)max); +	for (px = 0; px < imax; px++) { +		if (px < ipercent) printf ("%c", progress_char); +		else printf (" "); +	} +	if (csum_ok == 0) { +		printf ("] %3d %%\r", (int)percent); +	} else if (csum_ok == 1) { +		printf ("]  OK  \r"); +	} else { +		printf ("]  ERR \r"); +	} +	fflush (stdout); +} + +#define HEADER_RAW_LEN	21 + +void RecvTap() { +	unsigned int err; +	size_t len; +	int result; +	size_t block_pos = 0, last_block_pos = 0; +	size_t block_len = 10000; +	size_t tap_pos = 0; +	unsigned char xor_csum, xor_csum_ok; +	unsigned char *p_write; +	unsigned char block_type;				// typ bloku 255 data  0 - hlavicka +	unsigned char recv_status = 0;			// 0 - zacatek, 1 - hlavicka nactena,  2 - blok se nacita, 3- header less +	tapout_fd = fopen (output_dump_file, "a"); +	if (tapout_fd == NULL) { +		err = errno; +		error (1, err, "can't open output file"); +	} +	printf("Output file is: %s\n", output_dump_file); +	p_buff = in_buff; +	p_write = in_buff; +	while (is_continue) { +		result = poll (spolfd_serial, 1, 200);		// 200ms timeout +		if (result == 0) { +			// nic neprislo +			continue; +		} +		if (spolfd_serial[0].revents & POLLIN) { +			len = read (serial_fd, p_buff, 256); +			block_pos += len; +			p_buff += len; +			if (is_binary == 0) { +				// ulozeni dat ze seriaku jako tap file +				while (len) { +					fputc(*p_write, tapout_fd); +					p_write++; +					len--; +				} +			} +			if (block_pos != last_block_pos && recv_status >= 2) { +				last_block_pos = block_pos; +				DoProgress(block_pos, block_len+2, PROGRESS_PERCENT); +			} +			if (block_pos >= HEADER_RAW_LEN && recv_status == 0) { +				recv_status = 1;		// hlavicka nactena +				block_len = getword(in_buff); +				block_type = *(in_buff + 2); +				if (block_type == 0) { +					// Hlavicka komplet +					decode (in_buff + 2); +					block_len = 0; +					block_pos = 0; +					xor_csum = 0; +					recv_status = 0; +					p_buff = in_buff; +					p_write = in_buff; +				} else if (block_type == 255) { +					// data block +					printf ("Data block len: %6zu\n", block_len-2); +					recv_status = 3; +				} +				continue; +			} +			if (block_pos > HEADER_RAW_LEN + 3 && recv_status == 1) { +				// nactena delka dalsiho bloku +				recv_status = 2; +				block_len = getword(in_buff + HEADER_RAW_LEN); +				block_type = *(in_buff + HEADER_RAW_LEN + 2); +				printf ("Block len: %zu Block type: %d\n", block_len, block_type); +				continue; +			} +			if (block_len + 2 == block_pos && recv_status > 2) { +				// Blok komplet nacten cekej novy +				block_len = getword(in_buff); +				block_type = *(in_buff + 2); +				for (tap_pos = 0; tap_pos < block_len -1; tap_pos++) { +					xor_csum ^= *(in_buff + 2 + tap_pos); +				} +				xor_csum_ok = *(in_buff + 2 + block_len - 1); +				if (xor_csum == xor_csum_ok) { +					DoProgress(block_pos, block_len+2, PROGRESS_COMPLETTE);	// vypis jeste OK +					if (is_binary == 1) { +						// binarni vystup do souboru +						for (tap_pos = 0; tap_pos < block_len - 2; tap_pos++){ +							fputc(*(in_buff + 3 + tap_pos), tapout_fd);	// uloz do souboru +						} +						DoProgress(tap_pos, block_len - 2, PROGRESS_COMPLETTE); +					} +// 					printf ("Checksum OK\n"); +				} else { +					DoProgress(block_pos, block_len+2, PROGRESS_ERROR_CSUM);	// vypis error CSUM +				} +				block_len = 0; +				block_pos = 0; +				xor_csum = 0; +				recv_status = 0; +				p_buff = in_buff; +				p_write = in_buff; +				continue; +			} +		} +	} +	fclose (tapout_fd); +	printf ("\n\nulozeno...\n"); +} + +void SendByte(unsigned char *p_dato) { +	TestCts(); +	write (serial_fd, p_dato, 1); +// 	tcdrain(serial_fd);		// better solution, but usleep at the next line is +	usleep (wait_us);			// faster solution, TODO change sleep time according to serial communication speed  200us is for 57600Bd +} + +void SendTap() { +	FILE *tap_fd; +	unsigned int err, no, len; +	struct stat st; +	unsigned char header[19]; + +	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) { +		if (is_continue == 0) break; +		pos += no = fread(header, 1, 2, tap_fd); +		if (no != 2) +			tooshort(tap_fd); +		for (out_indx = 0; out_indx < 2; out_indx++) { +			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 ("Header len: %d\n", no); +			decode(header); +			for (out_indx = 0; out_indx < 19; out_indx++) { +				SendByte(&header[out_indx]); +			} +		} 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); +				DoProgress(1, no, PROGRESS_PERCENT); +				if (no != 1) tooshort(tap_fd); +				printf("Flag: %u\n\n", (int)*header); +				len--; +			} else { +				len = no; +			} +			pos += len; +			for (out_indx = 0; out_indx < len; out_indx++) { +				fread(header, 1, 1, tap_fd); +				SendByte(header); +				DoProgress(out_indx+1, len, PROGRESS_PERCENT); +				if (is_continue == 0) break; +			} +			printf ("\n"); +			usleep (800000); +		} +	} +	fclose(tap_fd); +} + + +int CheckFileInfo(FILEINFO* p_fi) { +	unsigned char *p_fiinfo = (unsigned char*)p_fi; +	uint16_t fi_len; +	uint8_t fi_xor = 0; +	uint8_t fi_sum = 0; +	fi_len = p_fi->length; +	p_fiinfo += 4;			// suma se bude pocitat od offsetu 4 +	for (uint16_t indx = 0; indx < (fi_len-4); indx++) { +		fi_xor ^= *p_fiinfo; +		fi_sum += *p_fiinfo; +		p_fiinfo++; +	} +	if (fi_xor == p_fi->h_xor && fi_sum == p_fi->h_sum) { +		return 0; +	} +	return -1; +} + +void CountFileInfoChecksum(FILEINFO* p_fi) { +	unsigned char *p_fiinfo = (unsigned char*)p_fi; +	uint16_t fi_len; +	uint8_t fi_xor = 0; +	uint8_t fi_sum = 0; +	fi_len = p_fi->length; +	p_fiinfo += 4;			// suma se bude pocitat od offsetu 4 +	for (uint16_t indx = 0; indx < (fi_len-4); indx++) { +		fi_xor ^= *p_fiinfo; +		fi_sum += *p_fiinfo; +		p_fiinfo++; +	} +	p_fi->h_xor = fi_xor; +	p_fi->h_sum = fi_sum; +} + +int CheckSumBlock(FILEINFO* p_fi, uint8_t block_indx, uint8_t *p_buffer) { +	uint16_t block_len; +	uint8_t b_xor = 0; +	uint8_t b_sum = 0; +	uint8_t block_xor; +	uint8_t block_sum; +	block_len = p_fi->fi_blocks[block_indx].block_len; +	block_sum = p_fi->fi_blocks[block_indx].block_sum; +	block_xor = p_fi->fi_blocks[block_indx].block_xor; +	for (uint16_t indx = 0; indx < block_len; indx++) { +		b_xor ^= *p_buffer; +		b_sum += *p_buffer; +		p_buffer++; +	} +	if (b_xor == block_xor && b_sum == block_sum) { +		return 0;	// vrat se, je to v poradku +	} +	return -1;		// vrat se s chybou bloku +} + +void CountSumBlock(FILEINFO* p_fi, uint8_t block_indx, uint8_t *p_buffer, uint16_t block_len) { +	uint8_t block_xor = 0; +	uint8_t block_sum = 0; +	for (uint16_t indx = 0; indx < block_len; indx++) { +		block_xor ^= *p_buffer; +		block_sum += *p_buffer; +		p_buffer++; +	} +	p_fi->fi_blocks[block_indx].block_len = block_len; +	p_fi->fi_blocks[block_indx].block_sum = block_sum; +	p_fi->fi_blocks[block_indx].block_xor = block_xor; +} + + +unsigned char buff[32768]; + +uint32_t GetOverallLen(FILEINFO *p_fi) { +	uint32_t overall_len = 0; +	uint8_t block_num = p_fi->fi_numblocks; +	for (uint8_t indx = 0; indx < block_num; indx++) { +		overall_len += p_fi->fi_blocks[indx].block_len; +	} +	return overall_len; +} + +void RecvSCP(void) { +	int recv_phase = 0;			// 0 - fileinfo, 1 - blok 16kiB, 2 - posledni blok +	uint8_t block_index = 0; +	int result; +	uint16_t len; +	uint16_t length = 0; +	uint16_t expected_len = 0; +// 	uint8_t expected_xor; +// 	uint8_t expected_sum; +	uint32_t overall_length = 0;		// celkova delka souboru +	uint32_t recv_length = 0;			// zatim prijatych dat ze souboru +	int err; + +	FILEINFO *p_fileinfo = &fileinfo; +	unsigned char *p_buff = buff; +	tapout_fd = NULL; + +	memset (p_fileinfo, 0, sizeof(fileinfo)); +	while (is_continue) { +		result = poll (spolfd_serial, 1, 200);		// 200ms timeout +		if (result == 0) { +			// nic neprislo +			continue; +		} +		switch (recv_phase) { +			case 0: +				// prijem fileinfo +				if (spolfd_serial[0].revents & POLLIN) { +					len = read (serial_fd, p_buff, sizeof(fileinfo)); +					p_buff += len; +					length += len; +					if (length == sizeof(fileinfo)) { +						memcpy((unsigned char*) p_fileinfo, buff, sizeof(fileinfo)); +						if (CheckFileInfo(p_fileinfo) == 0) { +							printf("Prijato fileinfo\n"); +							overall_length = GetOverallLen(p_fileinfo); +							printf("Nazev souboru: \"%s\" pocet bloku:%d, delka souboru: %u\n", p_fileinfo->fi_name, p_fileinfo->fi_numblocks, overall_length); +							recv_phase++;			// priste se uz prijimaji bloky +							block_index = 0;		// zacina se prvnim blokem +							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"); +							if (tapout_fd == NULL) { +								err = errno; +								error (1, err, "can't open output file"); +							} +// 							expected_xor = p_fileinfo->fi_blocks[block_index].block_xor; +// 							expected_sum = p_fileinfo->fi_blocks[block_index].block_sum; +						} else { +							printf("Fileinfo neni v cajku. Koncim...\n"); +							break; +						} +						break; +					} else if (length > sizeof(fileinfo)){ +						len = read (serial_fd, p_buff, sizeof(fileinfo)); +						printf("Nejaky bordel. Koncim...\n"); +						break; +					} +				} +				break; +			case 1: +				// prijem datoveho bloku - max. delka 16kiB +				if (spolfd_serial[0].revents & POLLIN) { +					len = read (serial_fd, p_buff, expected_len); +					p_buff += len; +					expected_len -= len; +					length += len; +					recv_length += len; +					DoProgress(recv_length, overall_length, PROGRESS_PERCENT); +					if (length == p_fileinfo->fi_blocks[block_index].block_len) { +						// prijaty prvni block +// 						printf("Prijaty blok c.%d delky: %d\n", block_index, length); +						if (CheckSumBlock(p_fileinfo, block_index, buff) == 0) { +							// blok je v cajku - zapsat do souboru +							if (tapout_fd) fwrite(buff, length, 1, tapout_fd); +						} +						length = 0; +						p_buff = buff; +						block_index++; +						expected_len = p_fileinfo->fi_blocks[block_index].block_len; +					} +					if (expected_len == 0 || block_index == 255) { +						printf ("\nKonec prenosu\n"); +						recv_phase++; +						is_continue = 0; +						break; +					} +				} else if (length > 16384) { +						len = read (serial_fd, p_buff, 16384); +						printf("Nejaky bordel. Koncim...\n"); +						break; +				} +			} +	} +	if (tapout_fd) fclose (tapout_fd); +	printf ("\n\nulozeno...\n"); +} + +void SendSCP(void) { +	FILE *tap_fd; +	unsigned int err, no, len; +	struct stat st; +	FILEINFO *p_fileinfo = &fileinfo; +	unsigned char *p_buff = buff; +	uint32_t file_len; +	uint8_t num_blocks = 0; +	ssize_t odeslano; +	uint32_t len_sent; +	uint16_t sent_size; +	uint32_t overall_sent; + + +	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"); +	} +	printf ("Soubor %s delky: %ld\n", tap_file, st.st_size); +	memset (p_fileinfo, 0, sizeof(fileinfo));		// smazat fileinfo + +	memcpy(p_fileinfo->fi_name, tap_file, strlen(tap_file)); +	file_len = (uint32_t) st.st_size; +	while (file_len) { +		len = fread(buff, 1, 16384, tap_fd);			// precti 16kiB dat +		CountSumBlock(p_fileinfo, num_blocks, buff, len); +// 		printf ("Blok c. %d, delka: %d\n", num_blocks, len); +		file_len -= len; +		num_blocks++; +	} +	p_fileinfo->fi_numblocks = num_blocks; +	p_fileinfo->length = num_blocks*4 + 85; +	CountFileInfoChecksum(p_fileinfo); +	odeslano = write (serial_fd, (void*)p_fileinfo, sizeof(fileinfo)); +	tcdrain(serial_fd); +	printf("Fileinfo sent...\n"); +	// TODO Cekat pauzu mezi bloky +	usleep (wait_ms * 1000); + +	rewind(tap_fd);				// prenaseny soubor na zacatek +	file_len = (uint32_t) st.st_size; +	overall_sent = 0; +	while (file_len && is_continue) { +		len = fread(buff, 1, 16384, tap_fd);			// precti 16kiB dat +		p_buff = buff; +		sent_size = 256; +		len_sent = len; +		while (len_sent && is_continue) { +			odeslano = write (serial_fd, (void*)p_buff, sent_size); +			tcdrain(serial_fd); +			p_buff += odeslano; +			overall_sent += odeslano; +			len_sent -= odeslano; +			if (len_sent < 256) { +				sent_size = len_sent; +			} +			DoProgress(overall_sent, st.st_size, PROGRESS_PERCENT); +		} +		usleep (wait_ms * 1000); +		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(); + +	// nastaveni serioveho portu +	struct termios oldtio, newtio; +	inp_indx = 0; +	if (argc < 3) { +		printf("You must specify the Serial device and file\n"); +		usage(); +		exit(1); +	} +	TestArgs (argc, argv); +	/* 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) { +		perror(MODEMDEVICE); +		return(-1); +	} +	tcgetattr(serial_fd, &oldtio); /* save current port settings */ +	switch (baud_rate){ +		default: +			baud_rate = 57600;			// default speed +			newtio.c_cflag = B57600 | CS8 | CLOCAL | CREAD | CSTOPB;// | CRTSCTS; +			break; +		case 115200: +			newtio.c_cflag = B115200 | CS8 | CLOCAL | CREAD | CSTOPB | CRTSCTS; +			break; +		case 57600: +			newtio.c_cflag = B57600 | CS8 | CLOCAL | CREAD | CSTOPB | CRTSCTS; +			break; +		case 38400: +			newtio.c_cflag = B38400 | CS8 | CLOCAL | CREAD | CRTSCTS;	// dva stopbity jsou nastaveny vsude, ale tady ne +			break; +		case 19200: +			newtio.c_cflag = B19200 | CS8 | CLOCAL | CREAD | CSTOPB | CRTSCTS; +			break; +		case 9600: +			newtio.c_cflag = B9600 | CS8 | CLOCAL | CREAD | CSTOPB | CRTSCTS; +			break; +		case 4800: +			newtio.c_cflag = B4800 | CS8 | CLOCAL | CREAD | CSTOPB | CRTSCTS; +			break; +		case 2400: +			newtio.c_cflag = B2400 | CS8 | CLOCAL | CREAD | CSTOPB | CRTSCTS; +			break; +		case 1200: +			newtio.c_cflag = B1200 | CS8 | CLOCAL | CREAD | CSTOPB | CRTSCTS; +			break; +	} +	newtio.c_cflag |= CRTSCTS; +	printf ("Serial device: %s, communication speed is: %d Bd\n", MODEMDEVICE, baud_rate); +// 	newtio.c_iflag &= ~(IXON | IXOFF | IXANY);	// vypne XON/XOFF +	newtio.c_iflag = 0;		//IGNPAR | IXOFF; +	newtio.c_oflag = 0; +// 	newtio.c_oflag &= ~OPOST; +	newtio.c_lflag = 0; //NOFLSH; +	newtio.c_cc[VMIN] = 0; +	newtio.c_cc[VTIME] = 10; +	tcsetattr(serial_fd, TCSANOW, &newtio); +	tcflush(serial_fd, TCIOFLUSH); +	spolfd_serial[0].fd = serial_fd;		// nastaveni hlidaneho descriptoru +	spolfd_serial[0].events = POLLIN;		// hlidaji se data na vstupu + +	if (scp) { +		// serial copy activated +		if (is_scp_read) { +			RecvSCP(); +		} else { +			SendSCP(); +		} +	} else { +		Set_DTR(true);		// PC can read data from speccy everytime +		if (is_outfile) { +			RecvTap();	// cteni tap souboru ze seriaku a zapis na disk pocitace +		} else { +			SendTap();	// poslat na seriak tap soubor do spectra +		} +	} +	close (serial_fd); +	return 0; +} | 
