Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

di_source.c

Go to the documentation of this file.
00001 
00021 #include <sys/types.h>
00022 #include <sys/socket.h>
00023 #include <netinet/in.h>
00024 #include <arpa/inet.h>
00025 #include <netdb.h>
00026 
00027 #include <stdlib.h>
00028 #include <math.h>
00029 #include <unistd.h>
00030 #include <stdint.h>
00031 
00032 #include "di194.h"
00033 
00034 /* Globals */
00036 const int SRV_PORT = 31337;
00038 const int QUEUE_LENGTH = 64;
00040 bool do_exit;
00041 
00050 int socket_make(void)
00051 {
00052     struct sockaddr_in  serv_in;
00053     struct protoent     *ppe = NULL;
00054     int                 itmp;
00055     int                 k_socket = 0;
00056     const int           no_socket = -1;
00057     int                 so_reuseaddr = 1;
00058     struct linger       so_linger;
00059 
00060     
00061     ppe = getprotobyname("tcp");
00062     if(ppe == NULL)
00063     {
00064         perror("Error on getprotobyname");
00065         return(no_socket);
00066     }
00067     
00068     itmp = socket(PF_INET, SOCK_STREAM, ppe->p_proto);
00069         
00070     // Socket returns -1 on an error
00071     if(itmp < 0)
00072     {
00073         perror("Error on socket creation; server running?");
00074         return(no_socket);
00075     }
00076     else
00077         k_socket = itmp;
00078 
00079     // ------------------------------------------------------
00080     // Set socket options - see LSPBE book for details
00081     itmp = setsockopt(k_socket, SOL_SOCKET, SO_REUSEADDR,
00082                       &so_reuseaddr, sizeof(so_reuseaddr));
00083     if(itmp != 0)
00084         perror("Warning; failure on setsockopt");
00085 
00086     // Set linger to true so that close waits for flush
00087     so_linger.l_onoff = true;
00088     so_linger.l_linger = 5;    // 5 second timeout on close(2)
00089     itmp = setsockopt(k_socket, SOL_SOCKET, SO_LINGER,
00090                       &so_linger, sizeof(so_linger));
00091     if(itmp != 0)
00092         perror("Warning; failure on setsockopt");
00093     
00094     // Set up servers' address
00095     serv_in.sin_family = AF_INET;
00096     serv_in.sin_addr.s_addr = INADDR_ANY;
00097     serv_in.sin_port = htons(SRV_PORT);
00098         
00099     // Bind the socket to address
00100     itmp = bind(k_socket, (struct sockaddr *) &serv_in, sizeof(serv_in));
00101         
00102     // bind also returns -1 on an error
00103     if(itmp < 0)
00104     {
00105         perror("Unable to bind to local port; server already running?");
00106 
00107         close(k_socket);
00108         return(no_socket);
00109     }
00110         
00111     // enable incoming connections
00112     // No max queue length in linux >= 2.2, not sure about other unixes -
00113     // this is a side benefit of the syn flood fixes
00114     itmp = listen(k_socket, QUEUE_LENGTH);
00115     if(itmp < 0)
00116     {
00117         perror("Listen failure");
00118         close(k_socket);
00119         
00120         return(no_socket);
00121     }
00122 
00123     printf("\nNetwork setup completed OK on port %d\n", SRV_PORT);
00124 
00125     return(k_socket);
00126 }
00127 
00128 // ---------------------------------------------------------------------
00139 void sighandler(int signal)
00140 {
00141     char    me[] = "sighandler";
00142 
00143     fprintf(stderr, "\n%s: Got signal %d, exiting\n", me, signal);
00144     fflush(stderr);
00145     
00146     do_exit = true;
00147 
00148     return;
00149 }
00150 
00159 int daq_loop(const int CLIENT_SOCKET, const int USEC_DELAY)
00160 {
00161     int           rc, s_len;
00162     char          asc_buf[128];
00163     daq_reading_t data;
00164     int           DI_FD = -1;
00165     int           num_bits = 8;
00166     
00167     DI_FD = di_open(getenv("DI194_PORT"), &num_bits);
00168     if(DI_FD <= 0)
00169     {
00170         fprintf(stderr, "\nError %d opening device\n", rc);
00171         di_close(DI_FD);
00172         close(CLIENT_SOCKET);
00173         
00174         return(rc);
00175     }
00176     
00177     rc = di_start(DI_FD);
00178     if(rc != 0)
00179     {
00180         fprintf(stderr, "\nError %d starting DAQ\n", rc);
00181         di_close(DI_FD);
00182         close(CLIENT_SOCKET);
00183         
00184         return(rc);
00185     }
00186 
00187     rc = di_daq_sync(DI_FD);
00188     if(rc != 0)
00189     {
00190         fprintf(stderr, "\nError %d syncing DAQ\n", rc);
00191         close(CLIENT_SOCKET);
00192         di_close(DI_FD);
00193         
00194         return(rc);
00195     }
00196     
00197     // Loop until signal handler sets 'do_exit' flag on ctrl-c
00198     while(do_exit == false)
00199     {
00200         // Read data from DI-194
00201         rc = di_read(DI_FD, &data, num_bits);
00202         if(rc != 0)
00203         {
00204             fprintf(stderr, "\nError %d reading data", rc);
00205             break;
00206         }
00207         
00208         sprintf(asc_buf, "%5.2f %d\n%5.2f %d\n%5.2f %d\n%5.2f\n",
00209                 data.analog[0],
00210                 data.digital[0],
00211                 data.analog[1],
00212                 data.digital[1],
00213                 data.analog[2],
00214                 data.digital[2],
00215                 data.analog[3]);
00216 
00217 
00218         // Write it out the TCP port
00219         s_len = strlen(asc_buf);
00220         rc = write(CLIENT_SOCKET, asc_buf, (size_t) s_len);
00221         if(rc != s_len)
00222         {
00223             fprintf(stderr, "\nError sending data: '%s'",
00224                     strerror(errno));
00225             break;
00226         }
00227         //      usleep(USEC_DELAY);
00228     }
00229     
00230     di_close(DI_FD);
00231     close(CLIENT_SOCKET);
00232     return(0);
00233 }
00234 
00240 void main_loop(const int usec_delay)
00241 {
00242     int                rc, itmp;
00243     int                client_socket = -1;
00244     struct sockaddr_in fsin;
00245     int                addr_len = sizeof(fsin);
00246     int                k_socket = -1;
00247     struct sockaddr    client_info;
00248     struct sockaddr_in *so = (struct sockaddr_in *) &client_info;
00249     struct hostent     *cl_hostent = NULL;
00250     char               remote_hostname[128] = "";
00251     
00252 
00253     // Setup the network; bail if failure
00254     k_socket = socket_make();
00255     if(k_socket <= 0)
00256         return;
00257 
00258     while(do_exit == false)
00259     {
00260         // Off we go
00261         printf("\nWaiting for client connection...");
00262         fflush(stdout);
00263     
00264         client_socket = accept(k_socket, 
00265                                (struct sockaddr *) &fsin, &addr_len);
00266 
00267         // Check who connected
00268         itmp = sizeof(struct sockaddr);
00269         rc = getpeername(client_socket, &client_info, &itmp);
00270         if((rc != 0) || (itmp < 0))
00271         {
00272             perror("Error getting peer information");
00273             continue;
00274         }
00275         
00276         // Do reverse DNS lookup
00277         cl_hostent = gethostbyaddr((char *) &so->sin_addr.s_addr,
00278                                    sizeof(so->sin_addr.s_addr), AF_INET);
00279         if(cl_hostent == NULL)
00280         {
00281             perror("Reverse DNS lookup failed");
00282             strcpy(remote_hostname, inet_ntoa(so->sin_addr));
00283         }
00284         else
00285             strcpy(remote_hostname, cl_hostent->h_name);
00286         
00287         printf("\nClient '%s' (%s) connected\n", 
00288                remote_hostname, inet_ntoa(so->sin_addr));
00289         
00290         // Call loop that does read'n'send
00291         daq_loop(client_socket, usec_delay);
00292     }
00293     
00294     return;
00295 }
00296         
00297 //***********************************************************************
00318 int main(int argc, char *argv[])
00319 {
00320     char          me[] = "main";
00321     const int     usec_delay = 1000;
00322     
00323 
00324     printf("%s: Installing signal handler.\n", me);
00325     do_exit = false;
00326     signal(SIGINT, sighandler);
00327     signal(SIGPIPE, sighandler);
00328     
00329     // Call main routine
00330     main_loop(usec_delay);
00331     
00332     return(0);
00333 }

Generated on Thu May 1 11:31:45 2003 for DI-194 driver by doxygen1.3