Example #1
0
int main(int argc, char *argv[]) {
	fd_set rset;
	struct timeval timeout;
	char * IP; //IP address of socket
	char * PTY; //Pseudo Terminal Name
	
	unsigned char cBuff[BUFFER];
	//char c[BUFFER];
	
	int csize;
	int pty = -1; //Pseudo Terminal File Descriptor
	int sockfd1, sockfd2 = -1;
	int x;
	int args = 0;
	int tmp;
	
	char argSerial[] = "-serial";
	char argHelp[]   = "-help";
	char argPort[]   = "-port";
	char argPTY[]    = "-pty";
	char argStrip[]  = "-strip";
	char argBaud[]   = "-baud";
	char argDebug[]  = "-debug";
	
	int SOCKET_PORT, BAUD, STRIP, DEBUG = 0;
	char SERIAL[100];


	for (x = 0; x < argc; x++){//Cycle through the command line arguments
		if (!strcmp(argSerial,argv[x])) {//Look for the -serial option
			strcpy(SERIAL,argv[x+1]); //Copies the port to SERIAL
			if(BAUD>0){ //If the baud option has been passed
				sockfd2 = connectSerial(SERIAL, BAUD); //Open the serial port and return the file descriptor
				if (sockfd2 < 0) {
					close(sockfd2);
					if(sockfd1>=0)
						close(sockfd1);
					if(pty>=0)
						close(pty);
					return -1;
				}else{
					args+=3;
				}
			}else{ 
				args+=3;
			}
		}
		else if (!strcmp(argPort,argv[x])) {  //Look for -port  option
			SOCKET_PORT = atoi(argv[x+1]); //Convert string address into int
			sockfd1 = makeSocket(SOCKET_PORT);  //Make the socket and return the file descriptor
			if (sockfd1 < 0) {
				close(sockfd1);
				if(sockfd2>=0)
					close(sockfd2);
				if(pty>=0)
					close(pty);
				return -1;
			}else{
				args+=5;
			}
		}
		else if (!strcmp(argPTY,argv[x])) {  //Look for -pty  option
			pty = pseudoTY(&PTY);
			if(pty<0){
				close(pty);
				if(sockfd2>=0)
					close(sockfd2);
				if(sockfd1>=0)
					close(sockfd1);
				return -1;
			}else{
				args+=7;
			}
		}
		else if (!strcmp(argBaud,argv[x])) { //Look for -baud option
			tmp = atoi(argv[x+1]); //Convert string baud rate to int
			switch (tmp) { //Make sure the value is supported
				case 115200:
					BAUD = B115200;
					break;
				case 38400:
					BAUD = B38400;
					break;
				case 19200:
					BAUD = B19200;
					break;
				case 9600:
					BAUD = B9600;
					break;
				default:
					printf("ERROR!: Unknown baud rate.\n");
					return -1;
					break;
			}
			
			if(strlen(SERIAL) != 0) //If we got the tag for a serial port, create the serial port
				sockfd2 = connectSerial(SERIAL, BAUD); //Open the serial port and return the file descriptor
			args+=1;
		}
		else if ( (args != 9 &&  args != 11 && args !=16 && x == argc-1) || (!strcmp(argHelp,argv[x]))) { 
                        //If not enough arguments, output usage directions and exit
			// Serial <=> Socket  w/ baud  = 9
			// Serial <=> PTY  w/ baud = 11
			// Serial <=> Socket, Serial <=> PTY w/ baud = 16
			printf("--------------------------------------\n");
			printf("------------ SerialDaemon ------------\n");
			printf("--------------------------------------\n");
			printf("Usage:");
			printf("\t./serialdaemon [options] [arguments]\n");
			printf("\t-serial [Use to indicate which serial port to connect to. E.G. /dev/ttyS1]\n");
			printf("\t-port   [Use to indicate which TCP/IP port of the local host to connect to. E.G. 5000]\n");
			printf("\t-pty    [Create a pseudo terminal for the serial port to connect to.]\n");
			printf("\t-baud   [Serial port baudrate.]\n");
			printf("\t\t115200\n");
			printf("\t\t38400\n");
			printf("\t\t19200\n");
			printf("\t\t9600\n");
			printf("\t-strip  [Strip the endline character and replace with a space.]\n");
			printf("\t-debug  [Set the verbose debug mode for help.]\n");
			printf("\t-help   [For this help screen.]\n\n");
			printf("Example Usage:\t./serialdaemon -serial /dev/ttyS1 -baud 115200 -pty -port 5000\n");
			printf("This will link ttyS1 to localhost:5000 and ttyS1 to a pseudo terminal.  The connection to ttyS1 will have a baudrate of 115200.\n");
			return -1;
		}
		else if (!strcmp(argStrip,argv[x])){STRIP = 1;}  //Look for the -strip option
		else if (!strcmp(argDebug,argv[x])){DEBUG = 1; printf ("DEBUG: debug mode on!\n");}  //Look for the -debug option
		
	}
	
	signal(SIGINT, controlC);	// catch ^C so we can close sockets & exit cleanly

	IP = getIP(); //Get the local IP address

	if(args == 9)//Serial to Socket
		printf("Connections made: \n\t\t\t%s < = > http://%s:%d\n",SERIAL,IP,SOCKET_PORT); 
	else if(args == 11)//Serial to PTY
		printf("Connections made: \n\t\t\t%s < = > %s\n",SERIAL,PTY); 
	else if(args == 16)//Serial to PTY  &  Serial to Socket
		printf("Connections made: \n\t\t\t%s < = > http://%s:%d\n\t\t\t%s < = > %s\n",SERIAL,IP,SOCKET_PORT,SERIAL,PTY); 

	sd1 = waitOnSocket(sockfd1); //Check for a connection to the socket

	while(1){
		/* Select on sockets */
		if(sd1 > 0){ //If There is a connection to the socket then potentially set up these connections:  tty < = > socket and tty < = > pty
			if (DEBUG)
				printf("DEBUG: New client socket opened.\n");
			if (sd1 < 0) { //Error in creating connection
				close(sd1); 
				return -1;
			}
			sd2 = sockfd2; //File descriptor of the serial port
			if (sd2 < 0) { //If an error
				close(sd1);
				close(sd2); 
				return -1;
			}
			FD_ZERO(&rset); //Clear file descriptors in the rset set
			while(1) {
				FD_SET(sd1,&rset);//Set sd1 in rset
				FD_SET(sd2,&rset);//Set sd2 in rset
				if(pty!=-1) {//If a virtual port is requested
					FD_SET(pty,&rset);
					select(max(max(sd1,sd2),pty)+1,&rset,NULL,NULL,NULL); 
                                       //Select specifies which of the file descriptors is ready for reading or writing
				}else {
					select(max(sd1,sd2)+1,&rset,NULL,NULL,NULL); 
					//Select tests file descriptors in the range of 0 to nfds-1 or in this case 0 to max(sd1,sd2).
				}
				//----------------Check The Socket For Data ------------------
				if (FD_ISSET(sd1,&rset)) {  //Is there stuff to read from the socket
					/* There's stuff to read */
					if ((csize= read(sd1, &cBuff, BUFFER)) >= 1) { //If there's something worth reading
						if (STRIP==1) { //Remove endline characters and replace with space
							for(x = 0 ; x < csize; x++) {
								if (cBuff[x] == '\n' ) {
									cBuff[x] = ' ';
									if (DEBUG)
										printf ("DEBUG: **STRIPPED**\n");
								}
							}
						}
						if (DEBUG) {
							//Replace &cBuff and cBuff with c
							//cBuff[csize] = '\0';
							printf("\nDEBUG: %s <== ",SERIAL);
							for(x=0; x<csize;x++){
								printf("%#.2x ",cBuff[x]);
							}
							printf("\n");
						}
						write(sd2, &cBuff, csize);//Write data from sd1 to sd2
					}else{break;}// Failed  -- port closed
				}
				
				//----------------Check The Serial Port For Data ------------------
				if (FD_ISSET(sd2,&rset)) {//Is there stuff to read from the serial port
					if ((csize = read(sd2, &cBuff, BUFFER)) >= 1) {//If there is something worth reading from the serial port
						write(sd1, &cBuff, csize); //Write this data to the socket
						if(pty != -1){write(pty,&cBuff,csize);} //Write this data to the virtual com port
						if (DEBUG) {
							//Replace &cBuff and cBuff with c
							//cBuff[csize] = '\0';
							printf("DEBUG: http://%s:%d <== ",IP,SOCKET_PORT);
							for(x=0; x<csize;x++){
								printf("%#.2x ",cBuff[x]);
							}
							printf("\n");
							
							if(pty !=-1){
								printf("DEBUG: %s <== ",PTY);
								for(x=0; x<csize;x++){
									printf("%#.2x ",cBuff[x]);
								}
								printf("\n");
							}
						}
					}
					//else break;           /* Failed */
				}
				//----------------Check The PTY Port For Data ------------------
				if (pty != -1 && FD_ISSET(pty,&rset)) {//If there is a virtual port, and data is ready, write data from 
					if ((csize = read(pty, &cBuff, BUFFER)) >= 1) {//If there is something worth reading from the serial port
						write(sd2, &cBuff, csize); //Write this data to the serial port
						if (DEBUG) {
							//Replace &cBuff and cBuff with c
							//cBuff[csize] = '\0';
							printf("\nDEBUG: %s <== ",SERIAL);
							for(x=0; x<csize;x++){
								printf("%#.2x ",cBuff[x]);
							}
							printf("\n");
						}
					}
					//else break;           /* Failed */
				}
			}
			printf("Restarting\n");
			close(sd1);/* clean up */
			sd1 = waitOnSocket(sockfd1); //Check for a connection to the socket

		}else if(pty != -1) {//Else, if there is a virtual port then tty <=> pty
			sd2 = sockfd2; //File descriptor of the serial port
			if (sd2 < 0) { //If an error
				close(sd2); 
				close(pty);
				return -1;
			}
			FD_ZERO(&rset); //Clear file descriptors in the rset set
			while(1) {
				FD_SET(sd2,&rset);//Set sd2 in rset
				FD_SET(pty,&rset);//Set pty in rset
				sd1 = waitOnSocket(sockfd1);
				if(sd1 >= 0){break;} //Check for socket connection, if there is, break out of this loop.
				select(max(sd2,pty)+1,&rset,NULL,NULL,NULL); // Specifies which of the file descriptors is ready for reading or writing
				if (FD_ISSET(pty,&rset)) { //If there is a virtual port, and data is ready, write data from 
					if ((csize = read(pty, &cBuff, BUFFER)) >= 1) {//If there is something worth reading from the serial port
						write(sd2, &cBuff, csize); //Write this data to the serial port
						if (DEBUG) {
							//Replace &cBuff and cBuff with c
							//cBuff[csize] = '\0';
							printf("\nDEBUG: %s <== ",SERIAL);
							for(x=0; x<csize;x++){
								printf("%#.2x ",cBuff[x]);
							}
							printf("\n");
						}
					}
					//else break;           // Failed 
				}


				if (FD_ISSET(sd2,&rset)) {//Is there stuff to read from the serial port				  
					if ((csize = read(sd2, &cBuff, BUFFER)) >= 1) { //If there is something worth reading from the serial port
						write(pty, &cBuff, csize); //Write this data to the virtual com port
						if (DEBUG) {
							//Replace &cBuff and cBuff with c
							//cBuff[csize] = '\0';
							printf("DEBUG: %s <== ",PTY);
							for(x=0; x<csize;x++){
								printf("%#.2x ",cBuff[x]);
							}
							printf("\n");
						}
					}
					//else break;           /* Failed */
				}

			}
		}else {//If there isn't a pty, then check the socket for a connection once a second
			if(DEBUG)
				printf("\rWaiting on the socket connection...\n");
			sd1 = waitOnSocket(sockfd1); //Check for a connection to the socket
			sleep(1);
		}
	}
}
Example #2
0
int main(int argc, char *argv[])
    {
    fd_set rset;
    struct timeval timeout;
    char c[BUFFER_SIZE];
    int csize;

    int mode;
    int x;
    int y;
    int args = 0;
    int tmp;
    int result;
    int blockerror = 0;

    char argSerial[] = "-serial";
    char argPort[]   = "-port";
    char argStrip[]  = "-strip";
    char argBaud[]   = "-baud";
    char argDebug[]  = "-debug";
    char argInDebug[]  = "-indebug";
    char argOutDebug[]  = "-outdebug";
    char argNonblock[]  = "-nonblock";
    char argAux[]  = "-aux";

    int SOCKET_PORT = 0;
    int BAUD = 0;
    int STRIP = 0;
    int NONBLOCK = 0;
    int AUX_PORT = 0;
    char SERIAL[100];
        
    for (x=1; x<argc; x++)
        {
        if (!strcmp(argSerial,argv[x]))
            {
            strcpy(SERIAL,argv[x+1]);
            x++;
            args++;
            }
        else if (!strcmp(argPort,argv[x]))
            {
            SOCKET_PORT = atoi(argv[x+1]);
            x++;
            args++;
            }
        else if (!strcmp(argBaud,argv[x]))
            {
            BAUD = parseBaudRates(argv[x+1]);
            if (!BAUD) return 1;
            x++;
            args++;
            }
        else if (!strcmp(argAux, argv[x]))
            {
            AUX_PORT = atoi(argv[x+1]);
            x++;
            }
        else if (!strcmp(argStrip,argv[x]))
            STRIP = 1;
        else if (!strcmp(argInDebug,argv[x]))
            INDEBUG = 1;
        else if (!strcmp(argOutDebug,argv[x]))
            OUTDEBUG = 1;
        else if (!strcmp(argDebug,argv[x]))
            INDEBUG = OUTDEBUG = 1;
        else if (!strcmp(argNonblock,argv[x]))
            NONBLOCK = 1;
        else { 
            printf("ERROR!: Unknown argument %s\n", argv[x]); 
            return 1; 
            }
        }

    if (args < 3)
        {
        printf("--------------------------------------------------------------\n");
        printf("------------------  GMU SerialDaemon  ------------------------\n");
        printf("--------------------------------------------------------------\n");
        printf("Usage:\n");
        printf("\tserialdaemon\n");
        printf("\t\t-serial [serialPort]\n");
        printf("\t\t-port   [TCP/IP Port]\n");
        printf("\t\t-aux    [auxiliary TCP/IP Port]\n");
        printf("\t\t-baud   [baudRate]\n");
        printf("\t\t\t500000    (available on Linux only)\n");
        printf("\t\t\t460800    (available on Linux only)\n");
        printf("\t\t\t230400\n");
        printf("\t\t\t115200\n");
        printf("\t\t\t57600\n");
        printf("\t\t\t38400\n");
        printf("\t\t\t19200\n");
        printf("\t\t\t9600\n");
        printf("\t\t-strip\n");
        printf("\t\t-indebug\n");
        printf("\t\t-outdebug\n");
        printf("\t\t-debug\n");
        printf("\t\t-nonblock\n");
        printf("\n");
        printf("Notes:\n");
        printf("1) If you have declared an auxiliary port, your client program\n");
        printf("   must connect to the primary TCP/IP port, THEN the auxiliary\n"); 
		printf("   port, and both must be connected before any traffic is sent\n");
        printf("2) Baud rates 460800 and 500000 are not available on OS/X\n");
        return(1);
        }

    if (INDEBUG || OUTDEBUG)
        printf ("DEBUG: debug mode on!\n");

    sockfd_pre = makeSocket(SOCKET_PORT);
    if (sockfd_pre <= 0)
        { 
        printf("ERROR: couldn't make TCP/IP socket!\n"); 
        closeAll(); 
        return; 
        }

    if (AUX_PORT != 0)
        {
        auxfd_pre = makeSocket(AUX_PORT);
        if (auxfd_pre <= 0)
            { 
            printf("ERROR: couldn't make TCP/IP socket!\n"); 
            closeAll(); 
            return; 
            }
        }

    serialfd = makeSerialPortFd(SERIAL, BAUD);
    if (serialfd <= 0)
        { 
        printf("ERROR: couldn't open serial port!\n"); 
        closeAll(); 
        return; 
        }

    if (argc <= 1)
        mode = 0;
    else
        mode = atoi(argv[1]);

    printf("Listening for data connections on port: %i\n",SOCKET_PORT);
    if (AUX_PORT != 0)
        {
        printf("Listening for aux  connections on port: %i\n",AUX_PORT);
        }

    while(1)
        {
        /* Wait for connection on data socket */
        sockfd = waitOnSocket(sockfd_pre);
        if (INDEBUG || OUTDEBUG)
            printf("DEBUG: New data socket opened.\n");
        if (sockfd < 0)
            {
            closeAll(); 
            return;
            }

        /* Set data socket to non-blocking */
        if (NONBLOCK)
            {
            if (fcntl(sockfd, F_SETFL, O_NONBLOCK) != 0)
                {
                printf("ERROR: couldn't make TCP/IP socket non-blocking!\n"); 
                closeAll(); 
                return; 
                }
            }

        /* Wait for connection on AUX socket (if specified) */
        if (auxfd_pre != NOTHING)
            {
            auxfd = waitOnSocket(auxfd_pre);
            if (INDEBUG || OUTDEBUG)
                printf("DEBUG: New aux  socket opened.\n");
            if (auxfd < 0)
                {
                closeAll(); 
                return;
                }
            }

        /* Must have a serial file descriptor (else, why are we running?) */
        if (serialfd < 0)
            {
            closeAll();
            return;
            }
    
        FD_ZERO(&rset);

        /* Main Loop */
        while(1)
            {
            /* Add connections to set */
            FD_SET(sockfd,&rset);
            if (auxfd!=NOTHING) FD_SET(auxfd,&rset);
            FD_SET(serialfd,&rset);

            /* Select on connection */
            select(max(max(sockfd,auxfd),serialfd)+1,&rset,NULL,NULL,NULL);
                        
            /* There's stuff to read on AUX */
            if (FD_ISSET(auxfd,&rset))
                { 
                if ((csize = readline(auxfd, c, BUFFER_SIZE)) >= 1)
                    {
                    c[csize] = '\0';  // after length, so no problem
                    char cmd = c[0];
                    if (c[1] != ' ')
                        printf("ERROR!: Malformed AUX command; ignoring\n");
                    char* data = &c[2];
                    switch (cmd)
                        {
                        case 'B':
                            if (INDEBUG)
                                {
                                printf("DEBUG: AUX baud change\n");
                                }
                            auxShiftBaud(data);
                            break;
                        default:
                            printf("ERROR!: Unknown AUX command; ignoring\n");
                            break;
                        }                                                       
                    }
                else break;             /* Failed */
                }
                        
            /* There's stuff to read on SOCKET */
            if (FD_ISSET(sockfd,&rset))
                {
                if ((csize= read(sockfd, c, BUFFER_SIZE)) >= 1)
                    {
                    y = csize;
                    if (STRIP==1)
                        {
                        for(x = 0, y = 0 ; x < csize; x++, y++)
                            {
                            if (c[x] == '\n')  { // get rid of it
                                y--;
                                if (OUTDEBUG) printf ("DEBUG: **STRIPPED**\n");
                                }
                            else c[y] = c[x];
                            }
                        }
                    if (OUTDEBUG)
                        {
                        c[y] = '\0';  // after length, so no problem
                        printf("DEBUG: serial <==");
                        printDebugString(c, y);
                        }
                    result = write(serialfd, c, y);
                    if (OUTDEBUG)
                        {
                        printf("DEBUG: wrote %d/%d\n", result, y);
                        }
                    }
                else break;             /* Failed */
                }
                        
            /* There's stuff to read on SERIAL */
            if (FD_ISSET(serialfd,&rset))
                {
                if ((csize = read(serialfd, c, BUFFER_SIZE)) >= 1)
                    {
                    if (STRIP==1)
                        {
                        for(x = 0 ; x < csize; x++)
                            {
                            if (c[x] == '\r' )  { // get rid of it
                                c[x] = '\n';
                                if (OUTDEBUG) printf ("DEBUG: **STRIPPED**\n");
                                }
                            else c[y] = c[x];
                            }
                        }
                    if (INDEBUG)
                        {
                        c[csize] = '\0';  // after length, so no problem
                        printf("DEBUG: serial ==>");
                        printDebugString(c, csize);
                        }
                    result = write(sockfd, c, csize);
                    if (result == EWOULDBLOCK)
                        {
                        if (!blockerror)
                            { 
                            blockerror = 1; 
                            printf("ERROR: dropping bytes writing to socket\n"); 
                            }
                        }
                    else if (INDEBUG)
                        {
                        printf("DEBUG: read %d/%d\n", result, csize);
                        }
                    }
                else break;             /* Failed */     
                }
            }

        /* Restart connection-wait loop */
        printf("Restarting\n");
        close(sockfd);  /* clean up */
        }
    }