#include #include #include #include #include #include #include #include #include #include #include "temperature.h" #include "rpc.h" #define BACKLOG 4 static int socketfd; void runcommand(int command, int clientfd) { char buf[32]; float temp; switch(command) { case CMD_TEMP_SISA: temp = get_temperature_sisa(); memcpy(buf, &temp, sizeof(float)); send(clientfd, buf, sizeof(float), 0); break; case CMD_TEMP_ULKO: temp = get_temperature_ulko(); memcpy(buf, &temp, sizeof(float)); send(clientfd, buf, sizeof(float), 0); break; case CMD_HUM_SISA: temp = get_humidity_sisa(); memcpy(buf, &temp, sizeof(float)); send(clientfd, buf, sizeof(float), 0); break; } } void server_handle(int clientfd) { int command; if (recv(clientfd, &command, sizeof(command), MSG_WAITALL) != sizeof(command)) return; runcommand(command, clientfd); } /* Public functions */ void server_initialize() { struct sockaddr_in servaddr; socketfd = socket(AF_INET, SOCK_STREAM, 0); memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = RPC_ADDR; servaddr.sin_port = RPC_PORT; // Set socket to reuse address, even if old instance has still // connections waiting. int on = 1; setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); if (bind(socketfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) != 0) { perror("bind"); exit(1); } listen(socketfd, BACKLOG); fcntl(socketfd, F_SETFL, O_NONBLOCK); } void server_do() { int clientfd; while (1) { clientfd = accept(socketfd, NULL, NULL); if (clientfd == -1 && errno == EAGAIN) { // No connections waiting return; } else if (clientfd == -1) { perror("socket_receive"); return; } server_handle(clientfd); close(clientfd); } } void server_dolong(int timeout) { int endtime = time(NULL) + timeout; struct pollfd sfd_poll; sfd_poll.fd = socketfd; sfd_poll.events = POLLIN; while (time(NULL) < endtime) { if (poll(&sfd_poll, 1, (endtime - time(NULL)) * 1000)) server_do(); } }