/********************************************************************\ Interface to the sky quality monitor (essentially a socket interface) Terminate with CTRL-c. Note that socket is closed automatically by exit(). Oliver Grimm, September 2009 \********************************************************************/ #include #include #include #include #include #include #define SERVER_NAME "SQM" // Name to use in DIM #include "Evidence.h" #define READ_CMD "rx" // Command to read from device #define BUF_SIZE 1000 // Read and text buffer size // Main program int main() { int SocketDescriptor; struct sockaddr_in SocketAddress; fd_set ReadFileDescriptor; time_t Time; unsigned int Period; // Start server and request configuration data EvidenceServer Srv(SERVER_NAME); char *Address = Srv.GetConfig(SERVER_NAME " address"); unsigned int Port = atoi(Srv.GetConfig(SERVER_NAME " port")); // Open socket descriptor if ((SocketDescriptor = socket(PF_INET, SOCK_STREAM, 0)) == -1) { Srv.State(Srv.FATAL, "Could not open socket (%s)", strerror(errno)); } // Resolve hostname struct hostent *hostent = gethostbyname(Address); if (hostent==0) { Srv.State(Srv.FATAL, "Could not resolve host name '%s' (%s)", Address, hstrerror(h_errno)); } // Connect to server SocketAddress.sin_family = PF_INET; SocketAddress.sin_port = htons((unsigned short) Port); SocketAddress.sin_addr = *(struct in_addr*) hostent->h_addr; if (connect(SocketDescriptor, (struct sockaddr *) &SocketAddress, sizeof(SocketAddress))==-1) { Srv.State(Srv.FATAL, "Could not connect to server '%s' on port %d (%s)", Address, Port, strerror(errno)); } Srv.State(Srv.INFO, "Connected to server '%s' on port %d", Address, Port); signal(SIGPIPE,SIG_IGN); // Do not kill process if writing to closed socket // Create DIM services double sqm_reading=0.0; char Buffer[BUF_SIZE]; DimService SQM_Brightness(SERVER_NAME"/NSB", sqm_reading); DimService SQM_Response(SERVER_NAME"/Response", NO_LINK); while(!EvidenceServer::ExitRequest) { // Request measurement period Period = atoi(Srv.GetConfig(SERVER_NAME " period")); // Write read command to socket if ((write(SocketDescriptor, READ_CMD, strlen(READ_CMD)))<1) { Srv.State(Srv.ERROR, "Could not write read command '%s' to socket.", READ_CMD); } // Wait for response (minimum 100 ms) usleep(100000); FD_ZERO(&ReadFileDescriptor); FD_SET(SocketDescriptor, &ReadFileDescriptor); struct timeval WaitTime = {Period, 0}; if (select(((int) SocketDescriptor)+1, &ReadFileDescriptor, NULL, NULL, &WaitTime)==-1) { Srv.State(Srv.FATAL, "Error with select() (%s)", strerror(errno)); } if (!FD_ISSET(SocketDescriptor, &ReadFileDescriptor)) { Srv.State(Srv.WARN, "Time-out of %d seconds expired before receiving response from socket", Period); continue; } memset(Buffer, 0, BUF_SIZE); if(read(SocketDescriptor, Buffer, BUF_SIZE) == 0) { Srv.State(Srv.FATAL, "Server not existing anymore, exiting...\n"); } // Update full textual response and brightness reading for (int i=0; i