#define PORT 8080
// ttyGS0 is a virtual serial line implemented by the Pi as a gadget, fed from a Windows PC USB port
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <error.h>
#include <errno.h>
#include <ctype.h>
#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>
#include <libgen.h>
#include <termios.h>
#include <sys/stat.h>
#include <sys/select.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdarg.h>
#include <signal.h>
#ifndef FALSE
#define FALSE (0!=0)
#define TRUE (0==0)
#endif
#define BUF_SIZE 1024
char USB0_buf[BUF_SIZE + 1], WIFI_buf[BUF_SIZE + 1];
struct termios ttyUSB0Orig, t0;
int USB0_Fd, WIFI_Fd;
fd_set inFds;
static char ServerName[1024];
void ttyReset (void)
{
// close the socket
close (WIFI_Fd);
(void) tcsetattr (USB0_Fd, TCSANOW, &ttyUSB0Orig); // restore
// keyboard/stdin
fprintf (stderr, "\nexit()\n");
_exit (EXIT_SUCCESS);
}
char *progname;
void errExit (char *what)
{
fprintf (stderr, "Exit: %s\n", what);
exit (EXIT_FAILURE);
}
void INThandler (int sig)
{ // force ^C to go via atexit() handler...
signal (sig, SIG_IGN);
exit (0);
// signal(SIGINT, INThandler);
}
int main (int argc, char **argv)
{
size_t numRead;
char *s;
// Get clean version of executable name. Should work on most existing
// systems (2006)
progname = argv[0];
if ((s = strrchr (progname, '/')) != NULL)
progname = s + 1; // Unix
if ((s = strrchr (progname, '\\')) != NULL)
progname = s + 1; // M$
if ((s = strrchr (progname, ']')) != NULL)
progname = s + 1; // Dec
if ((s = strrchr (progname, ';')) != NULL)
*s = '\0'; // Version no's
if (((s = strrchr (progname, '.')) != NULL)
&& (strcasecmp (s, ".exe") == 0))
*s = '\0';
if (((s = strrchr (progname, '.')) != NULL)
&& (strcasecmp (s, ".com") == 0))
*s = '\0';
if (argc > 2) {
fprintf(stderr, "syntax: %s [server]\n", progname);
exit(EXIT_FAILURE);
}
strcpy(ServerName, "127.0.0.1");
if (argc == 2) strcpy(ServerName, argv[1]);
struct sockaddr_in servaddr;
// socket create and varification
WIFI_Fd = socket (AF_INET, SOCK_STREAM, 0);
if (WIFI_Fd == -1) {
fprintf (stderr, "socket creation failed...\n");
exit (0);
} else {
fprintf (stderr, "Socket successfully created..\n");
}
bzero (&servaddr, sizeof (servaddr));
// assign IP, PORT
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr (ServerName);
servaddr.sin_port = htons (PORT);
// connect the client socket to server socket
while (connect (WIFI_Fd, (struct sockaddr *) &servaddr, sizeof (servaddr))
!= 0) {
fprintf (stderr, "connection with %s failed... retrying...\n", ServerName);
sleep (1);
}
fprintf (stderr, "Connected to %s..\n", ServerName);
// fprintf(stderr, "Debug: 1\n");
if (tcgetattr (USB0_Fd, &ttyUSB0Orig) == -1)
errExit ("tcgetattr");
// fprintf(stderr, "Debug: 2\n");
system ("stty -F /dev/ttyGS0 speed 115200 > /dev/null 2>&1");
// fprintf(stderr, "Debug: 3\n");
USB0_Fd = open ("/dev/ttyGS0", O_RDWR);
// fprintf(stderr, "Debug: 3a\n");
if (USB0_Fd < 0) {
errExit ("open");
}
// fprintf(stderr, "Debug: 4\n");
tcsendbreak (USB0_Fd, 0);
/* relay data between both USB serial ports */
// fprintf(stderr, "Debug: 5\n");
if (tcgetattr (USB0_Fd, &t0) == -1) /* return -1 */
errExit ("tcgetattr");
ttyUSB0Orig = t0;
t0.c_lflag &= ~(ICANON | ISIG | IEXTEN | ECHO); // COMMENT OUT THIS
// "| ECHO"
// to cause GRBL commands to
// be echoed on the incoming
// connection
/* Noncanonical mode, disable signals, extended input processing, and
echoing */
t0.c_iflag &=
~(BRKINT | ICRNL | IGNBRK | IGNCR | INLCR | INPCK | ISTRIP | IXON |
PARMRK);
/* Disable special handling of CR, NL, and BREAK. No 8th-bit stripping or
parity error handling. Disable START/STOP output flow control. */
// If it weren't for the fact that I might later want to support ^S/^Q, I
// would probably put these in RAW mode instead:
#ifdef NEVER // RAW:
t ?.c_iflag |= IGNBRK;
t ?.c_iflag &= ~(INLCR | ICRNL | IXON | IXOFF);
t ?.c_lflag &= ~(ICANON | ECHO | ECHOK | ECHOE | ECHONL | ISIG | IEXTEN);
#endif
t0.c_oflag &= ~OPOST; /* Disable all output processing */
t0.c_cc[VMIN] = 1; /* Character-at-a-time input */
t0.c_cc[VTIME] = 0; /* with blocking */
// fprintf(stderr, "Debug: 6\n");
(void) tcsetattr (USB0_Fd, TCSAFLUSH, &t0);
// fprintf(stderr, "Debug: 7\n");
if (atexit (ttyReset) != 0)
errExit ("atexit");
/* everything that comes from USB0 is forwarded to WIFI, and vice-versa */
// TEMP!!! signal(SIGINT, INThandler);
fprintf (stderr, "Starting main loop\n");
for (;;) {
int rc, got_any;
got_any = FALSE;
FD_ZERO (&inFds);
FD_SET (USB0_Fd, &inFds);
FD_SET (WIFI_Fd, &inFds);
if (WIFI_Fd > USB0_Fd) {
rc = select (WIFI_Fd + 1, &inFds, NULL, NULL, NULL);
} else {
rc = select (USB0_Fd + 1, &inFds, NULL, NULL, NULL);
}
if (FD_ISSET (USB0_Fd, &inFds)) { /* USB0 -> WIFI */
// fprintf(stderr, "getting serial data\n");
numRead = read (USB0_Fd, USB0_buf, BUF_SIZE);
if (numRead > 0) {
got_any = TRUE;
// fprintf(stderr, "got serial data %d\n", numRead);
(void) write (WIFI_Fd, USB0_buf, numRead); // for now assume all
//
// writes succeed.
(void) write (2, USB0_buf, numRead); // for now assume all
// writes succeed.
}
}
if (FD_ISSET (WIFI_Fd, &inFds)) { /* WIFI -> USB0 */
numRead = read (WIFI_Fd, WIFI_buf, BUF_SIZE);
if (numRead > 0) {
got_any = TRUE;
(void) write (USB0_Fd, WIFI_buf, numRead);
// (void)write(2, WIFI_buf, numRead);
}
}
if (!got_any) {
fprintf (stderr,
"server died? Will retry until we re-establish a connection...\n");
// socket create and varification
WIFI_Fd = socket (AF_INET, SOCK_STREAM, 0);
if (WIFI_Fd == -1) {
fprintf (stderr, "socket creation failed...\n");
exit (0);
} else {
fprintf (stderr, "Socket successfully created..\n");
}
bzero (&servaddr, sizeof (servaddr));
// assign IP, PORT
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr ("127.0.0.1");
servaddr.sin_port = htons (PORT);
// connect the client socket to server socket
while (connect
(WIFI_Fd, (struct sockaddr *) &servaddr,
sizeof (servaddr)) != 0) {
fprintf (stderr,
"reconnection with the %s failed... retrying...\n", ServerName);
sleep (1);
}
fprintf (stderr, "Connected to %s.\n", ServerName);
// fprintf(stderr, "Debug: 1\n");
// close(WIFI_Fd);
// (void)tcsetattr (USB0_Fd, TCSANOW, &ttyUSB0Orig); // restore
// keyboard/stdin
// exit(EXIT_FAILURE);
}
}
return (EXIT_FAILURE); // killing is the only expected exit
}