Main Page | Data Structures | File List | Data Fields | Globals

server.c

Go to the documentation of this file.
00001 /* serialT_proxy.c --- 
00002  * 
00003  * Filename: serialT_proxy.c
00004  * Description: 
00005  * Author: Bryce Himebaugh
00006  * Maintainer: 
00007  * Created: Tue Sep  5 08:46:53 2006
00008  * Version: 
00009  * Last-Updated: 
00010  *           By: 
00011  *     Update #: 0
00012  * Keywords: 
00013  * Compatibility: 
00014  * 
00015  */
00016 
00017 /* Commentary: 
00018  * 
00019  * 
00020  * 
00021  */
00022 
00023 /* Change log:
00024  * 
00025  * 
00026  */
00027 
00028 /* This program is free software; you can redistribute it and/or modify
00029  * it under the terms of the GNU General Public License as published by
00030  * the Free Software Foundation; either version 2, or (at your option)
00031  * any later version.
00032  * 
00033  * This program is distributed in the hope that it will be useful,
00034  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00035  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00036  * GNU General Public License for more details.
00037  * 
00038  * You should have received a copy of the GNU General Public License
00039  * along with this program; see the file COPYING.  If not, write to the
00040  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00041  * Boston, MA 02111-1307, USA.
00042  */
00043 
00044 /* Code: */
00045 
00046 /* A simple server in the internet domain using TCP
00047    The port number is passed as an argument */
00048 
00049 #include <stdio.h>
00050 #include <sys/types.h> 
00051 #include <sys/socket.h>
00052 #include <netinet/in.h>
00053 #include <strings.h>
00054 #include <string.h>
00055 #include <arpa/inet.h>
00056 #include <stdlib.h>
00057 #include <unistd.h>
00058 #include <signal.h>
00059 #include <errno.h>
00060 
00061 #include "ftdi_helper.h"
00062 #include "server_command_line_parser.h"
00063 
00064 #define STATE_DELAY_US 10000
00065 
00066 void error(char *msg) {
00067     perror(msg);
00068     exit(1);
00069 }
00070 
00071 int delay_uS(int);
00072 
00073 void sigproc();
00074 void quitproc();
00075 int print_sock_error(int);
00076 
00077 int sockfd, portno, clilen;
00078 int newsockfd=0;
00079 
00080 
00081 int main(int argc, char *argv[]) {
00082   char buffer[256];
00083   struct sockaddr_in serv_addr, cli_addr;
00084   int n;
00085   
00086   int select_status;
00087   fd_set readfds;
00088   struct timeval to;
00089   
00090   enum {EUNCONNECTED,EREAD,FTDI,EWRITE};
00091   static int bridge_state=EUNCONNECTED; 
00092 
00093   char local_buffer[QUEUE_LENGTH];
00094   int read_chars=0;
00095   int write_chars=0;
00096 
00097   command_options_t options;
00098   unsigned int yes=1;
00099 
00100   // Setup signal handlers 
00101   signal(SIGINT,sigproc);
00102   signal(SIGQUIT,quitproc);
00103 
00104   // Handle Command Line Options
00105   init_command_line_options(&options);
00106   command_line_parser (argc, argv, &options);
00107   
00108   // Initialize the FTDI console channel 
00109   if (ftd2xx_init(ftd2xx_console_desc,!options.attach)) {
00110     printf("Initialization Failed\n");
00111     return (1);
00112   }
00113  
00114   // Setup to listen on the socket
00115   sockfd = socket(AF_INET, SOCK_STREAM, 0);        // Load file descriptor, sockfd
00116   if (sockfd < 0) {
00117     error("ERROR opening socket");
00118   }
00119   
00120 /*   if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(yes))<0) { */
00121 /*     perror("Reusing ADDR failed"); */
00122 /*     exit(1); */
00123 /*   } */
00124   bzero((char *) &serv_addr, sizeof(serv_addr));   // zero the 
00125   serv_addr.sin_family = AF_INET;
00126   serv_addr.sin_addr.s_addr = INADDR_ANY;
00127   serv_addr.sin_port = htons(options.port);
00128   if (bind(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) {
00129     error("ERROR on binding");
00130   }
00131   listen(sockfd,5);
00132   
00133   while (1) {
00134     switch (bridge_state) {
00135     case EUNCONNECTED:
00136       printf("Waiting for a connection on port %d...",options.port);
00137       fflush(stdout);
00138       newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr, &clilen);
00139       printf("Connection Accepted from %s\n",inet_ntoa(cli_addr.sin_addr));
00140       purge_ftdi();
00141       init_queue(&ftdi_tx_queue);
00142       init_queue(&ftdi_rx_queue);
00143       bridge_state=EREAD;
00144       break;
00145     case EREAD:
00146       bzero(buffer,256);
00147       FD_ZERO(&readfds);                    // clear the read file descriptor set
00148       FD_SET(newsockfd,&readfds);           // listen to the new socket for data 
00149       to.tv_sec = 0;
00150       to.tv_usec = 1000;    
00151       select_status=select(newsockfd+1,&readfds,NULL,NULL,&to);
00152       switch (select_status) {
00153       case -1:
00154         printf("Select Error\n");
00155         bridge_state=EUNCONNECTED;
00156         close(newsockfd);
00157         break;
00158       case 0:
00159         bridge_state=FTDI;
00160         break;
00161       default:
00162         bridge_state=FTDI;
00163         if (FD_ISSET(newsockfd,&readfds)) {
00164           n = read(newsockfd,buffer,255);
00165           if (n) {
00166             enqueue(&ftdi_tx_queue,buffer,n);
00167           } 
00168           else {
00169             bridge_state=EUNCONNECTED;
00170             close(newsockfd);
00171           }
00172         }
00173       }
00174       break;
00175     case FTDI:
00176       eval_ftdi_console();
00177       bridge_state=EWRITE;
00178       break;
00179     case EWRITE:
00180       bzero(local_buffer,QUEUE_LENGTH);
00181       if ((read_chars=dequeue(&ftdi_rx_queue,local_buffer,FTDI_RX_TRANSFER_SIZE))) {
00182         write_chars=write(newsockfd,local_buffer,read_chars);
00183       }
00184       bridge_state=EREAD;
00185       break;
00186     default:
00187       printf("Error: Unknown Communication State\n");
00188       exit(1);
00189       break;
00190     }
00191     delay_uS(STATE_DELAY_US);
00192   }
00193   return 0; 
00194 }
00195 
00196 int delay_uS(int uS) {
00197   struct timeval to;
00198   to.tv_sec = 0;
00199   to.tv_usec = uS;    
00200   select(0,NULL,NULL,NULL,&to);
00201   return (0);
00202 }
00203 
00204 void sigproc() {
00205   close(newsockfd);
00206   close(sockfd);
00207   exit(0);
00208 }
00209 
00210 void quitproc() {
00211   close(newsockfd);
00212   close(sockfd);
00213   exit(0);
00214 }
00215 
00216 int print_sock_error(int sock_error) {
00217   switch (sock_error) {
00218   case EBADF:
00219     printf("EBADF: The socket argument is not a valid file descriptor.\n");
00220     break;
00221   case EINVAL:
00222     printf("EINVAL: The socket shutdown method argument is  invalid.\n");
00223     break;
00224   case ENOTCONN:
00225     printf("ENOTCONN: The socket is not connected.\n");
00226     break;
00227   case ENOTSOCK:
00228     printf("ENOTCONN: The socket argument does not refer to a socket.\n");
00229     break;
00230   default:
00231     printf("%d:Unrecognized Socket Error\n",sock_error);
00232   }
00233   return(0);
00234 }
00235 
00236 /* server.c ends here */

Generated on Fri Nov 3 15:24:51 2006 for ERT1 Communication Server by  doxygen 1.3.9.1