Skip to content

Instantly share code, notes, and snippets.

@ckent
Created June 1, 2015 15:15
Show Gist options
  • Save ckent/b926c5149da064ce29f0 to your computer and use it in GitHub Desktop.
Save ckent/b926c5149da064ce29f0 to your computer and use it in GitHub Desktop.
Bridge an incoming socket to a serial port.
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/select.h>
#include <sys/ioctl.h>
#include <errno.h>
int main(int argc,char** argv)
{
struct termios tio;
struct termios stdio;
struct termios old_stdio;
int tty_fd;
tcgetattr(STDOUT_FILENO,&old_stdio);
memset(&stdio,0,sizeof(stdio));
stdio.c_iflag=0;
stdio.c_oflag=0;
stdio.c_cflag=0;
stdio.c_lflag=0;
stdio.c_cc[VMIN]=1;
stdio.c_cc[VTIME]=0;
tcsetattr(STDOUT_FILENO,TCSANOW,&stdio);
tcsetattr(STDOUT_FILENO,TCSAFLUSH,&stdio);
fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK); // make the reads non-blocking
memset(&tio,0,sizeof(tio));
tio.c_iflag=0;
tio.c_oflag=0;
tio.c_cflag=CS8|CREAD|CLOCAL; // 8n1, see termios.h for more information
tio.c_lflag=0;
tio.c_cc[VMIN]=1;
tio.c_cc[VTIME]=5;
cfsetospeed(&tio,B19200);
cfsetispeed(&tio,B19200);
tty_fd=open(argv[1], O_RDWR | O_NONBLOCK);
if(tty_fd <= 0)
{
perror("ERROR: couldn't open device");
exit(1);
}
tcsetattr(tty_fd,TCSANOW,&tio);
while(1)
{
// Set timeout
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 250000;
// Add file descriptors to be monitored
fd_set rd_set;
fd_set err_set;
FD_ZERO(&rd_set);
FD_ZERO(&err_set);
int fd = -1;
int maxfd = -1;
fd = STDIN_FILENO;
FD_SET(fd, &rd_set);
FD_SET(fd, &err_set);
if(fd > maxfd) maxfd = fd;
fd = tty_fd;
FD_SET(fd, &rd_set);
FD_SET(fd, &err_set);
if(fd > maxfd) maxfd = fd;
int rc = select(maxfd+1, &rd_set, NULL, &err_set, &tv);
// Check for errors
if(FD_ISSET(tty_fd, &err_set))
break;
if(FD_ISSET(STDIN_FILENO, &err_set))
break;
// We read some data
if(rc > 0)
{
char buffer[1024];
if(FD_ISSET(tty_fd, &rd_set))
{
ssize_t nread = read(tty_fd, buffer, sizeof(buffer));
if(nread > 0)
write(STDOUT_FILENO,buffer,nread);
else if(nread < 0)
break;
}
if(FD_ISSET(STDIN_FILENO, &rd_set))
{
ssize_t nread = read(STDIN_FILENO, buffer, sizeof(buffer));
if(nread > 0)
{
int i;
for(i=0; i<nread; i++)
{
// Add a small inter-character delay
write(tty_fd,&(buffer[i]),1);
usleep(5000);
}
}
else if(nread < 0)
break;
}
}
else if(rc < 0)
{
if(errno != EINTR)
{
// continue on EINTR
break;
}
}
}
close(tty_fd);
tcsetattr(STDOUT_FILENO,TCSANOW,&old_stdio);
perror("ERROR: closed");
exit(1);
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment