/* sertrans.c */
/* Transmits a file to another computer over a serial cable */
/* Last modified: September 20, 2005 */
/* http://www.gomorgan89.com */
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Function to set up the serial port settings with the specified baud rate,
no parity, and one stop bit */
void set_up_serial_port(HANDLE h, long baud);
/* Function to print out usage */
void usage(void);
/* Function to get size of file */
unsigned long get_file_size(char *file_name);
/* Function to write the file to the serial port */
void write_file_to_serial_port(HANDLE h, char *file_name, unsigned long file_size);
int main(int argc, char **argv)
{
HANDLE serial_port; /* Handle to the serial port */
long baud_rate = 9600; /* Specified baud rate */
char port_name[] = "COM1:"; /* Name of the serial port */
unsigned long file_size; /* File size to transmit in bytes */
unsigned long bytes_written; /* Bytes written to serial port */
unsigned long file_name_size; /* Size of file name */
/* Check command line arguments */
if (argc == 4)
{
/* Read in baud rate */
if (argv[2][1] != 'b' || sscanf(argv[3], "%ld", &baud_rate) != 1)
{
usage();
exit(0);
}
}
else if (argc != 2)
{
usage();
exit(0);
}
/* Open up a handle to the serial port */
serial_port = CreateFile(port_name, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
/* Make sure port was opened */
if (serial_port == INVALID_HANDLE_VALUE)
{
fprintf(stderr, "Error opening port\n");
CloseHandle(serial_port);
exit(0);
}
/* Set up the serial port */
set_up_serial_port(serial_port, baud_rate);
/* Get the file size */
file_size = get_file_size(argv[1]);
/* Print out information */
printf("Preparing to transmit file %s: %lu bytes\n", argv[1], file_size);
/* Write file name size to serial port */
file_name_size = (unsigned long)strlen(argv[1]);
WriteFile(serial_port, (void *)&file_name_size, sizeof(unsigned long), &bytes_written, NULL);
if (bytes_written != sizeof(unsigned long))
{
fprintf(stderr, "Error writing file name size.\n");
CloseHandle(serial_port);
exit(0);
}
/* Write file name to serial port */
WriteFile(serial_port, (void *)argv[1], file_name_size, &bytes_written, NULL);
if (bytes_written != file_name_size)
{
fprintf(stderr, "Error writing file name.\n");
CloseHandle(serial_port);
exit(0);
}
/* Write file size to serial port */
WriteFile(serial_port, (void *)&file_size, sizeof(unsigned long), &bytes_written, NULL);
if (bytes_written != sizeof(unsigned long))
{
fprintf(stderr, "Error writing file size.\n");
CloseHandle(serial_port);
exit(0);
}
/* Write file to serial port */
write_file_to_serial_port(serial_port, argv[1], file_size);
printf("\n%lu bytes successfully transmitted.\n", file_size);
/* Close the handle */
CloseHandle(serial_port);
return 0;
}
void set_up_serial_port(HANDLE h, long baud)
{
DCB properties; /* Properties of serial port */
/* Get the properties */
GetCommState(h, &properties);
/* Set the baud rate */
switch(baud)
{
case 1200:
properties.BaudRate = CBR_1200;
break;
case 2400:
properties.BaudRate = CBR_2400;
break;
case 4800:
properties.BaudRate = CBR_4800;
break;
case 9600:
properties.BaudRate = CBR_9600;
break;
case 14400:
properties.BaudRate = CBR_14400;
break;
case 19200:
properties.BaudRate = CBR_19200;
break;
case 38400:
properties.BaudRate = CBR_38400;
break;
default:
fprintf(stderr, "Invalid baud rate: %ld", baud);
usage();
exit(0);
break;
}
/* Set the other properties */
properties.Parity = NOPARITY;
properties.ByteSize = 8;
properties.StopBits = ONESTOPBIT;
SetCommState(h, &properties);
return;
}
void usage(void)
{
fprintf(stderr, "Usage:\n");
fprintf(stderr, "\tsertrans file [-b baud_rate]\n");
fprintf(stderr, "\tDefault baud rate is 9600\n");
fprintf(stderr, "\tSupported baud rates: 1200, 2400, 4800, 9600, 14400, 19200, 38400\n");
return;
}
unsigned long get_file_size(char *file_name)
{
FILE *data_file;
unsigned long size = 0;
size_t bytes_read;
char byte_read;
/* Open the file */
data_file = fopen(file_name, "rb");
/* Quit if file couldn't be opened */
if (data_file == NULL)
{
fprintf(stderr, "Could not open file %s\n", file_name);
exit(0);
}
/* Read in data one byte at a time until we reach the end */
while (1)
{
bytes_read = fread((void *)&byte_read, 1, 1, data_file);
if (bytes_read <= 0)
{
break;
}
++size;
}
/* Close file */
fclose(data_file);
return size;
}
void write_file_to_serial_port(HANDLE h, char *file_name, unsigned long file_size)
{
FILE *data_file;
unsigned long bytes_left = file_size;
unsigned long bytes_sent;
unsigned long bytes_read;
unsigned long total_bytes_sent = 0;
size_t bytes_to_send;
char buffer[200];
/* Open the file */
data_file = fopen(file_name, "rb");
/* Quit if file couldn't be opened */
if (data_file == NULL)
{
fprintf(stderr, "Could not open file %s\n", file_name);
exit(0);
}
while (1)
{
/* Determine how many bytes to send */
if (bytes_left == 0)
{
break;
}
else if (bytes_left < 200)
{
bytes_to_send = bytes_left;
}
else
{
bytes_to_send = 200;
}
/* Read in specified number of bytes */
bytes_read = (unsigned long)fread((void *)buffer, 1, bytes_to_send, data_file);
/* Send data over serial cable */
WriteFile(h, (void *)buffer, bytes_read, &bytes_sent, NULL);
if (bytes_sent != bytes_read)
{
fprintf(stderr, "Error writing file.\n");
CloseHandle(h);
exit(0);
}
/* Decrement number of bytes left */
bytes_left -= bytes_sent;
/* Increment number of bytes sent */
total_bytes_sent += bytes_sent;
/* Print out progress */
printf("\r%5lu bytes transmitted.", total_bytes_sent);
}
fclose(data_file);
return;
}