//server program for final project
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/time.h>
#include <rtai.h>
#include <rtai_lxrt.h>
#include <rtai_fifos.h>


#define MSG_SIZE 20			// message size
#define MSG1 "ACTIVATE1"		//first message
#define MSG2 "ACTIVATE2"    //second message
#define MSG3 "DEACTIVATE1"		//first message
#define MSG4 "DEACTIVATE2"
#define MSG5 "STATUS"

void error(const char *msg)
{
    perror(msg);
    exit(0);
}

int main(int argc, char *argv[])
{
	int room = 1;

	char *msg1 = "ON ROOM1";
	char *msg2 = "ON ROOM2";
	char *msg3 = "OFF ROOM1";
	char *msg4 = "OFF ROOM2";
	char *msg5 = "WARMINGUP ROOM1";
	char *msg6 = "WARMINGUP ROOM2";
	char *msg7 = "WARNING ROOM1";
	char *msg8 = "WARNING ROOM2";
	char *msg9 = "NORMAL ROOM1";
	char *msg10 = "NORMAL ROOM2";
	char *msg11 = "UPDATING";


	int status = 0;
	int sock, length,n;
	int boolval = 1;		// for a socket option
	socklen_t fromlen;
	struct sockaddr_in server;
	struct sockaddr_in addr;
	char buf[MSG_SIZE];
	char message[MSG_SIZE];
	int warmup = 0;
	int active = 0;
	int fd_fifo_in;
	fd_fifo_in = open("/dev/rtf/2",O_RDWR);

    if (argc < 2)
    {
       fprintf(stderr, "ERROR, no port provided\n");
       exit(0);
    }

    sock = socket(AF_INET, SOCK_DGRAM, 0); // Creates socket. Connectionless.
    if (sock < 0)
	    error("Opening socket");

    length = sizeof(server);			// length of structure
    bzero(&server,length);			// sets all values to zero. memset() could be used
    server.sin_family = AF_INET;		// symbol constant for Internet domain
    server.sin_addr.s_addr = INADDR_ANY;		// IP address of the machine on which
											// the server is running
    server.sin_port = htons(atoi(argv[1]));	// port number

    // binds the socket to the address of the host and the port number
    if (bind(sock, (struct sockaddr *)&server, length) < 0)
        error("binding");

    // set broadcast option
    if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &boolval, sizeof(boolval)) < 0)
    	{
    		printf("error setting socket options\n");
   	 	exit(-1);
   	 }

    fromlen = sizeof(struct sockaddr_in);	// size of structure


    while(1){

    	bzero(message, MSG_SIZE);
    	bzero(buf, MSG_SIZE);

		n = recvfrom(sock, buf, MSG_SIZE, 0, (struct sockaddr *)&addr, &fromlen); //get message from client
			if (n < 0){
				error("recvfrom");
	        }

		if(strncmp(buf,MSG1, 9) == 0 && room == 1){
			//turn on
			strcpy(message, msg1);
			n = sendto(sock, message, MSG_SIZE, 0, (struct sockaddr *)&addr, fromlen);
			active = 1;
		}

		else if(strncmp(buf,MSG2, 9) == 0 && room == 2){
			//turn on
			strcpy(message, msg2);
			n = sendto(sock, message, MSG_SIZE, 0, (struct sockaddr *)&addr, fromlen);
			active = 1;
		}

		else if(strncmp(buf,MSG3, 11) == 0 && room == 1){
			//turn off
			strcpy(message, msg3);
			n = sendto(sock, message, MSG_SIZE, 0, (struct sockaddr *)&addr, fromlen);
			active = 0;
			warmup = 0;
		}

		else if(strncmp(buf,MSG4, 11) == 0 && room == 2){
			//turn off
			strcpy(message, msg4);
			n = sendto(sock, message, MSG_SIZE, 0, (struct sockaddr *)&addr, fromlen);
			active = 0;
			warmup = 0;
		}

		else if(strncmp(buf,MSG5, 6) == 0){
			if(room == 1){
				if(active == 0){
					strcpy(message, msg3);
					n = sendto(sock, message, MSG_SIZE, 0, (struct sockaddr *)&addr, fromlen);
					warmup = 0;
				}

				if(active == 1){
					if(warmup < 40){
						strcpy(message, msg5);
						n = sendto(sock, message, MSG_SIZE, 0, (struct sockaddr *)&addr, fromlen);
					}

					if(warmup >= 40){
						read(fd_fifo_in,&status,sizeof(status));
							if(status == 1){
								strcpy(message, msg7);
								n = sendto(sock, message, MSG_SIZE, 0, (struct sockaddr *)&addr, fromlen);
							}else
								strcpy(message, msg9);
								n = sendto(sock, message, MSG_SIZE, 0, (struct sockaddr *)&addr, fromlen);

						}

					}


			}

			if(room == 2){
				if(active == 0){
					strcpy(message, msg4);
					n = sendto(sock, message, MSG_SIZE, 0, (struct sockaddr *)&addr, fromlen);
					warmup = 0;
				}

				if(active == 1){
					if(warmup < 40){
						strcpy(message, msg6);
						n = sendto(sock, message, MSG_SIZE, 0, (struct sockaddr *)&addr, fromlen);
					}

					if(warmup >= 40){
						read(fd_fifo_in,&status,sizeof(status));

							if(status == 1){
								strcpy(message, msg8);
								n = sendto(sock, message, MSG_SIZE, 0, (struct sockaddr *)&addr, fromlen);
							}else
								strcpy(message, msg10);
							n = sendto(sock, message, MSG_SIZE, 0, (struct sockaddr *)&addr, fromlen);


					}
				}
			}

		}

		else{
			strcpy(message, msg11);
			n = sendto(sock, message, MSG_SIZE, 0, (struct sockaddr *)&addr, fromlen);
		}


    warmup++;
    }
}