/* * server.cpp * * Created on: Jan 4, 2018 * Author: Philipp Hinz * based on: https://gist.github.com/suyash/2488ff6996c98a8ee3a84fe3198a6f85 */ #include #include #include #include #include #include #include #include #include "server.h" #include "logger.h" #include "hal.h" #include "coffee.h" #include "stripe.h" /** * TCP Uses 2 types of sockets, the connection socket and the listen socket. * The Goal is to separate the connection phase from the data exchange phase. * */ int listen_sock; int sock; char buffer_ok[] = "OK\n"; /** * Just sends an ACK message back */ void sendACK() { send(sock, buffer_ok, strlen(buffer_ok), 0); } /** * Main thread to handle networking stuff * @param *threadid Thread ID */ void* serverThread(void* threadid) { sleep(1); // Wait for other components to initialize // socket address used for the server struct sockaddr_in server_address; memset(&server_address, 0, sizeof(server_address)); server_address.sin_family = AF_INET; // htons: host to network short: transforms a value in host byte // ordering format to a short value in network byte ordering format server_address.sin_port = htons(SERVER_PORT); // htonl: host to network long: same as htons but to long server_address.sin_addr.s_addr = htonl(INADDR_ANY); // create a TCP socket, creation returns -1 on failure if ((listen_sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) { logger_error("could not create listen socket\n"); pthread_exit(0); } // bind it to listen to the incoming connections on the created server // address, will return -1 on error if ((bind(listen_sock, (struct sockaddr *) &server_address, sizeof(server_address))) < 0) { logger_error("could not bind socket\n"); pthread_exit(0); } int wait_size = 16; // maximum number of waiting clients, after which // dropping begins if (listen(listen_sock, wait_size) < 0) { logger_error("could not open socket for listening\n"); pthread_exit(0); } logger(V_BASIC, "Now listening for commands on port %d\n", SERVER_PORT); // socket address used to store client address struct sockaddr_in client_address; unsigned int client_address_len = 0; // run indefinitely while (true) { // open a new socket to transmit data per connection if ((sock = accept(listen_sock, (struct sockaddr *) &client_address, &client_address_len)) < 0) { logger_error("could not open a socket to accept data\n"); pthread_exit(0); } int n = 0; int len = 0, maxlen = 100, lastlen = 0; char buffer[maxlen]; char cmd[maxlen]; char *pcmd = cmd; char *pbuffer = buffer; strncpy(buffer, "", maxlen); strncpy(cmd, "", maxlen); logger(V_HAL, "client connected with ip address: %s\n", inet_ntoa(client_address.sin_addr)); // keep running as long as the client keeps the connection open while ((n = recv(sock, pbuffer, maxlen, 0)) > 0) { pbuffer += n; maxlen -= n; len += n; strncpy(cmd, buffer, len - 1); cmd[len - 1] = '\0'; pcmd = &cmd[lastlen]; logger(V_SPI, "received %d bytes: '%s' (cmd: %s)\n", len, buffer, pcmd); if (!strcmp(SERVER_CMD_ON, pcmd)) { if (getState() == STATE_OFF) { halSendSignal(SigInt0Rls); sendACK(); } } else if (!strcmp(SERVER_CMD_OFF, pcmd)) { if (getState() != STATE_OFF) { halSendSignal(SigInt1RlsLong); sendACK(); } } else if (!strcmp(SERVER_CMD_BREW, pcmd)) { if (getState() == STATE_IDLE || getState() == STATE_HEATING) { halSendSignal(SigInt1Rls); sendACK(); } } else if (!strcmp(SERVER_CMD_STATUS, pcmd)) { char tmp[] = "0\n"; tmp[0] += getState(); send(sock, tmp, sizeof(tmp), 0); } else if (!strcmp(SERVER_CMD_STRIPEON, pcmd)) { stripeOn(); sendACK(); } else if (!strcmp(SERVER_CMD_STRIPEOFF, pcmd)) { stripeOff(); sendACK(); } lastlen = len; // echo received content back //send(sock, buffer, len, 0); } close(sock); } close(listen_sock); pthread_exit(EXIT_SUCCESS); } /** * Closes all active connections */ void serverTerminate() { close(sock); close(listen_sock); }