Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

di_tempd.c

Go to the documentation of this file.
00001 
00017 #include <sys/types.h>
00018 #include <sys/socket.h>
00019 #include <netinet/in.h>
00020 #include <arpa/inet.h>
00021 #include <netdb.h>
00022 
00023 #include <stdlib.h>
00024 #include <math.h>
00025 #include <unistd.h>
00026 #include <stdint.h>
00027 
00028 #include "di194.h"
00029 
00030 /* Globals */
00032 const int SRV_PORT = 51307;
00034 const int QUEUE_LENGTH = 64;
00036 bool do_exit;
00037 
00046 int socket_make(void)
00047 {
00048     struct sockaddr_in  serv_in;
00049     struct protoent     *ppe = NULL;
00050     int                 itmp;
00051     int                 k_socket = 0;
00052     const int           no_socket = -1;
00053     int                 so_reuseaddr = 1;
00054     struct linger       so_linger;
00055 
00056     
00057     ppe = getprotobyname("tcp");
00058     if(ppe == NULL)
00059     {
00060         perror("Error on getprotobyname");
00061         return(no_socket);
00062     }
00063     
00064     itmp = socket(PF_INET, SOCK_STREAM, ppe->p_proto);
00065         
00066     // Socket returns -1 on an error
00067     if(itmp < 0)
00068     {
00069         perror("Error on socket creation; server running?");
00070         return(no_socket);
00071     }
00072     else
00073         k_socket = itmp;
00074 
00075     // ------------------------------------------------------
00076     // Set socket options - see LSPBE book for details
00077     itmp = setsockopt(k_socket, SOL_SOCKET, SO_REUSEADDR,
00078                       &so_reuseaddr, sizeof(so_reuseaddr));
00079     if(itmp != 0)
00080         perror("Warning; failure on setsockopt");
00081 
00082     // Set linger to true so that close waits for flush
00083     so_linger.l_onoff = true;
00084     so_linger.l_linger = 5;    // 5 second timeout on close(2)
00085     itmp = setsockopt(k_socket, SOL_SOCKET, SO_LINGER,
00086                       &so_linger, sizeof(so_linger));
00087     if(itmp != 0)
00088         perror("Warning; failure on setsockopt");
00089     
00090     // Set up servers' address
00091     serv_in.sin_family = AF_INET;
00092     serv_in.sin_addr.s_addr = INADDR_ANY;
00093     serv_in.sin_port = htons(SRV_PORT);
00094         
00095     // Bind the socket to address
00096     itmp = bind(k_socket, (struct sockaddr *) &serv_in, sizeof(serv_in));
00097         
00098     // bind also returns -1 on an error
00099     if(itmp < 0)
00100     {
00101         perror("Unable to bind to local port; server already running?");
00102 
00103         close(k_socket);
00104         return(no_socket);
00105     }
00106         
00107     // enable incoming connections
00108     // No max queue length in linux >= 2.2, not sure about other unixes -
00109     // this is a side benefit of the syn flood fixes
00110     itmp = listen(k_socket, QUEUE_LENGTH);
00111     if(itmp < 0)
00112     {
00113         perror("Listen failure");
00114         close(k_socket);
00115         
00116         return(no_socket);
00117     }
00118 
00119     printf("\nNetwork setup completed OK on port %d\n", SRV_PORT);
00120 
00121     return(k_socket);
00122 }
00123 
00124 // ---------------------------------------------------------------------
00135 void sighandler(int signal)
00136 {
00137     char    me[] = "sighandler";
00138 
00139     fprintf(stderr, "\n%s: Got signal %d, exiting\n", me, signal);
00140     fflush(stderr);
00141     
00142     do_exit = true;
00143 
00144     return;
00145 }
00146 
00153 int daq_loop(const int CLIENT_SOCKET, const int USEC_DELAY)
00154 {
00155     int           rc, s_len;
00156     char          asc_buf[128];
00157     daq_reading_t data;
00158     int           DI_FD = -1;
00159     float         temp_c = 0.0;
00160     time_t        t_now;
00161         
00162     DI_FD = di_open(getenv("DI194_PORT"));
00163     if(DI_FD <= 0)
00164     {
00165         fprintf(stderr, "\nError %d opening device\n", rc);
00166         di_close(DI_FD);
00167         close(CLIENT_SOCKET);
00168         
00169         return(rc);
00170     }
00171     
00172     rc = di_start(DI_FD);
00173     if(rc != 0)
00174     {
00175         fprintf(stderr, "\nError %d starting DAQ\n", rc);
00176         di_close(DI_FD);
00177         close(CLIENT_SOCKET);
00178         
00179         return(rc);
00180     }
00181     rc = di_daq_sync(DI_FD);
00182     if(rc != 0)
00183     {
00184         fprintf(stderr, "\nError %d syncing DAQ\n", rc);
00185         close(CLIENT_SOCKET);
00186         di_close(DI_FD);
00187         
00188         return(rc);
00189     }
00190 
00191     // Read one value
00192     rc = di_read(DI_FD, &data);
00193     if(rc != 0)
00194     {
00195         fprintf(stderr, "\nError %d reading data", rc);
00196         return(rc);
00197     }
00198     
00199     // Fixed format output - sensor is 10mV per degree C
00200     temp_c = (float) data.analog[0] * 100.0;
00201     
00202     sprintf(asc_buf, "%5.2f Celsius\n", temp_c);
00203 
00204     // Write it out the TCP port
00205     s_len = strlen(asc_buf);
00206     rc = write(CLIENT_SOCKET, asc_buf, (size_t) s_len);
00207     if(rc != s_len)
00208             fprintf(stderr, "\nError sending data: '%s'",
00209                     strerror(errno));
00210 
00211     printf("Reading: %5.2f volts ==> %5.2f Celsius, %5.2f F", 
00212            data.analog[0], temp_c,
00213            ((9.0 / 5.0) * temp_c) + 32.0);
00214     t_now = time(NULL);
00215     printf(" at %s", asctime(localtime(&t_now)));
00216         
00217     di_close(DI_FD);
00218     close(CLIENT_SOCKET);
00219     return(rc);
00220 }
00221 
00227 void main_loop(const int usec_delay)
00228 {
00229     int                rc, itmp;
00230     int                client_socket = -1;
00231     struct sockaddr_in fsin;
00232     int                addr_len = sizeof(fsin);
00233     int                k_socket = -1;
00234     struct sockaddr    client_info;
00235     struct sockaddr_in *so = (struct sockaddr_in *) &client_info;
00236     struct hostent     *cl_hostent = NULL;
00237     char               remote_hostname[128] = "";
00238     
00239 
00240     // Setup the network; bail if failure
00241     k_socket = socket_make();
00242     if(k_socket <= 0)
00243         return;
00244 
00245     while(do_exit == false)
00246     {
00247         // Off we go
00248         printf("\nWaiting for client connection...");
00249         fflush(stdout);
00250     
00251         client_socket = accept(k_socket, 
00252                                (struct sockaddr *) &fsin, &addr_len);
00253 
00254         // Check who connected
00255         itmp = sizeof(struct sockaddr);
00256         rc = getpeername(client_socket, &client_info, &itmp);
00257         if((rc != 0) || (itmp < 0))
00258         {
00259             perror("Error getting peer information");
00260             continue;
00261         }
00262         
00263         // Do reverse DNS lookup
00264         cl_hostent = gethostbyaddr((char *) &so->sin_addr.s_addr,
00265                                    sizeof(so->sin_addr.s_addr), AF_INET);
00266         if(cl_hostent == NULL)
00267         {
00268             perror("Reverse DNS lookup failed");
00269             strcpy(remote_hostname, inet_ntoa(so->sin_addr));
00270         }
00271         else
00272             strcpy(remote_hostname, cl_hostent->h_name);
00273         
00274         printf("\nClient '%s' (%s) connected", 
00275                remote_hostname, inet_ntoa(so->sin_addr));
00276         
00277         // Call loop that does read'n'send
00278         daq_loop(client_socket, usec_delay);
00279     }
00280     
00281     return;
00282 }
00283         
00284 //***********************************************************************
00305 int main(int argc, char *argv[])
00306 {
00307     char          me[] = "main";
00308     const int     usec_delay = 1000;
00309     
00310 
00311     printf("%s: Installing signal handler.\n", me);
00312     do_exit = false;
00313     signal(SIGINT, sighandler);
00314     signal(SIGPIPE, sighandler);
00315     
00316     // Call main routine
00317     main_loop(usec_delay);
00318     
00319     return(0);
00320 }

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