diff --git a/Makefile b/Makefile index e9fd873..e7a3eb5 100644 --- a/Makefile +++ b/Makefile @@ -31,10 +31,14 @@ PATHR = build/results/ BUILD_PATHS = $(PATHB) $(PATHD) $(PATHO) $(PATHR) $(PATHL) COMPILE = gcc -c +CROSSCOMPILE = arm-linux-gnueabihf-gcc -c + LINK = gcc +CROSSLINK = arm-linux-gnueabihf-gcc + DEPEND = gcc -MM -MG -MF -CFLAGS = -I. -I$(PATHU) -I$(PATHS) -I$(PATHL) -DTEST +CFLAGS = -I. -I$(PATHU) -I$(PATHS) -I$(PATHL) -DTEST -DUNITY_OUTPUT_COLOR CFLAGS += -std=c99 CFLAGS += -Wall CFLAGS += -Wextra @@ -50,6 +54,39 @@ CFLAGS += -Wstrict-prototypes CFLAGS += -Wundef CFLAGS += -Wold-style-definition +CROSSFLAGS = -I. -I$(PATHS) -I$(PATHL) -D_POSIX_C_SOURCE +CROSSFLAGS += -std=c99 +CROSSFLAGS += -march=armv6 +CROSSFLAGS += -mfloat-abi=hard +CROSSFLAGS += -mfpu=vfp +CROSSFLAGS += -Wall +CROSSFLAGS += -Wextra +CROSSFLAGS += -Wpointer-arith +CROSSFLAGS += -Wcast-align +# CROSSFLAGS += -Wwrite-strings +CROSSFLAGS += -Wswitch-default +CROSSFLAGS += -Wunreachable-code +CROSSFLAGS += -Winit-self +CROSSFLAGS += -Wmissing-field-initializers +CROSSFLAGS += -Wno-unknown-pragmas +CROSSFLAGS += -Wstrict-prototypes +CROSSFLAGS += -Wundef +CROSSFLAGS += -Wold-style-definition + +release: TARCOMPILE = $(CROSSCOMPILE) +test: TARCOMPILE = $(COMPILE) + +release: TARLINK = $(CROSSLINK) +test: TARLINK = $(LINK) + +release: TARFLAGS = $(CROSSFLAGS) +test: TARFLAGS = $(CFLAGS) + +RELEASE = $(PATHB)zaqar.$(TARGET_EXTENSION) +RELEASEDEPS = $(patsubst $(PATHL)%.c,$(PATHO)%.o, $(wildcard $(PATHL)*.c)) + +release: test $(RELEASEDEPS) $(RELEASE) + RUNNERS = $(patsubst $(PATHT)%.c,$(PATHTR)%_Runner.c, $(wildcard $(PATHT)*.c)) runners: $(RUNNERS) test @@ -69,28 +106,34 @@ test: $(BUILD_PATHS) $(RESULTS) $(DEPS) @echo "$(FAIL)" @echo "---------------PASSED---------------" @echo "$(PASSED)" - @echo "\nDONE" + @echo "\n===============DONE===============\n" $(PATHR)%.txt: $(PATHB)%.$(TARGET_EXTENSION) -./$< > $@ 2>&1 -$(PATHB)test_%.$(TARGET_EXTENSION): $(PATHO)test_%.o $(PATHO)test_%_Runner.o $(PATHO)%.o $(PATHU)unity.o #$(PATHD)test_%.d - $(LINK) -o $@ $^ +$(PATHB)test_%.$(TARGET_EXTENSION): $(PATHO)test_%.o $(PATHO)test_%_Runner.o $(PATHO)%.t.o $(PATHU)unity.o + $(TARLINK) -o $@ $^ $(PATHO)%.o: $(PATHTR)%.c - $(COMPILE) $(CFLAGS) $< -o $@ + $(TARCOMPILE) $(TARFLAGS) $< -o $@ $(PATHO)%.o:: $(PATHT)%.c - $(COMPILE) $(CFLAGS) $< -o $@ + $(TARCOMPILE) $(TARFLAGS) $< -o $@ -$(PATHO)%.o:: $(PATHS)%.c - $(COMPILE) $(CFLAGS) $< -o $@ +$(PATHB)zaqar.$(TARGET_EXTENSION):: $(PATHO)zaqar.o $(RELEASEDEPS) + $(TARLINK) -o $@ $^ + +$(PATHO)zaqar.o:: $(PATHS)zaqar.c + $(TARCOMPILE) $(TARFLAGS) $< -o $@ $(PATHO)%.o:: $(PATHL)%.c - $(COMPILE) $(CFLAGS) $< -o $@ + $(TARCOMPILE) $(TARFLAGS) $< -o $@ + +$(PATHO)%.t.o:: $(PATHL)%.c + $(TARCOMPILE) $(TARFLAGS) $< -o $@ $(PATHO)%.o:: $(PATHU)%.c $(PATHU)%.h - $(COMPILE) $(CFLAGS) $< -o $@ + $(TARCOMPILE) $(TARFLAGS) $< -o $@ $(PATHD)%.d:: $(PATHT)%.c $(DEPEND) $@ $< @@ -121,5 +164,6 @@ cleandep: .PRECIOUS: $(PATHB)test_%.$(TARGET_EXTENSION) .PRECIOUS: $(PATHD)%.d +.PRECIOUS: $(PATHO)%.t.o .PRECIOUS: $(PATHO)%.o .PRECIOUS: $(PATHR)%.txt diff --git a/lib/helpers.c b/lib/helpers.c new file mode 100644 index 0000000..4f3a289 --- /dev/null +++ b/lib/helpers.c @@ -0,0 +1,56 @@ +#include "helpers.h" + +int create_socket(uint16_t port) { + int sock; + struct sockaddr_in socket_name; + + // Creates the socket + sock = socket (PF_INET, SOCK_STREAM, 0); //TODO: check if PF_INET is the right one + if (sock < 0) { + perror("Couldn't create the socket."); + exit(EXIT_FAILURE); + } + + // Gives the socket a name + socket_name.sin_family = AF_INET; + socket_name.sin_port = htons(port); + socket_name.sin_addr.s_addr = htonl(INADDR_ANY); + + // Binds own address structure to socket + if (bind(sock, (struct sockaddr *) &socket_name, sizeof(socket_name)) < 0) { + perror("Couldn't bind the address structure to the socket."); + exit(EXIT_FAILURE); + } + + return sock; +} + +int read_from_client(int file_des, uint16_t max_line) { + char buffer[max_line]; + int nbytes; + + nbytes = read(file_des, buffer, sizeof(buffer)); + if (nbytes < 0) { + perror("Couldn't read from client."); + exit(EXIT_FAILURE); + } else if (nbytes == 0) + // End-of-file + return -1; + else { + fprintf(stderr, "Server: got message: `%s'\n", buffer); + return 0; + } +} + +void init_sockaddr(struct sockaddr_in *name, const char *hostname, uint16_t port) { + struct hostent *hostinfo; + + name->sin_family = AF_INET; + name->sin_port = htons(port); + hostinfo = gethostbyname(hostname); + if (hostinfo == NULL) { + fprintf(stderr, "Unknown host %s.\n", hostname); + exit(EXIT_FAILURE); + } + name->sin_addr = *(struct in_addr *) hostinfo->h_addr_list[0]; +} diff --git a/lib/helpers.h b/lib/helpers.h new file mode 100644 index 0000000..c3e6f27 --- /dev/null +++ b/lib/helpers.h @@ -0,0 +1,21 @@ +#ifndef HELPERS_H_ +#define HELPERS_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int create_socket(uint16_t port); + +int read_from_client(int file_des, uint16_t max_line); + +void init_sockaddr(struct sockaddr_in *name, const char *hostname, uint16_t port); + +#endif //HELPERS_H_ diff --git a/src/zaqar.c b/src/zaqar.c new file mode 100644 index 0000000..61dc6ac --- /dev/null +++ b/src/zaqar.c @@ -0,0 +1,155 @@ +#include "zaqar.h" + +#define MESSAGE "You got mail!!! xo xo xo" + +volatile sig_atomic_t out_flag = false; + +void write_to_server(int filedes) { + int nbytes; + + nbytes = write(filedes, MESSAGE, strlen(MESSAGE) + 1); + if (nbytes < 0) { + perror("write"); + exit(EXIT_FAILURE); + } +} + +void handle_alarm(int sig) { + if (sig == SIGALRM) { + out_flag = true; + + int sock; + struct sockaddr_in servername; + + printf("GOT_CL1\n"); + + /* Create the socket. */ + sock = socket (PF_INET, SOCK_STREAM, 0); + if (sock < 0) { + perror("socket (client)"); + exit(EXIT_FAILURE); + } + + /* Connect to the server. */ + init_sockaddr (&servername, "10.0.88.79", PORT); + if (connect(sock, (struct sockaddr *) &servername, sizeof (servername))) { + printf("GOT_CL2\n"); + //perror("connect (client)"); + //exit(EXIT_FAILURE); + } else { + printf("GOT_CL3\n"); + /* Send data to the server. */ + write_to_server(sock); + } + + //close (sock); + } +} + +int main(void) { + int sock; + fd_set active_fd_set, read_fd_set; + struct sockaddr_in client_name; + size_t size; + + alarm(0); + //signal(SIGALRM, handle_alarm); + + struct itimerval new; + + new.it_interval.tv_usec = 0; + new.it_interval.tv_sec = 8; + new.it_value.tv_usec = 0; + new.it_value.tv_sec = 8; + + if (setitimer (ITIMER_REAL, &new, NULL) == -1) { + perror("Couldn't set timer."); + exit(EXIT_FAILURE); + } + + sigset_t mask; + int sfd; + struct signalfd_siginfo fdsi; + + sigemptyset(&mask); + sigaddset(&mask, SIGALRM); + /*if (sigprocmask(SIGALRM, &mask, NULL) == -1) + perror("sigprocmask");*/ + + sfd = signalfd(-1, &mask, 0); + if (sfd == -1) + perror("signalfd"); + + // Creates the socket and sets it up to accept connections + sock = create_socket(PORT); + if (listen(sock, BACKLOG_SIZE) < 0) { + perror("Couldn't listen for connections on the socket."); + exit(EXIT_FAILURE); + } + + printf("GOT_SV1\n"); + // Initializes the set of active sockets + // Clears the descriptor set + FD_ZERO(&active_fd_set); + // Sets socket in active readset + FD_SET(sock, &active_fd_set); + FD_SET(sfd, &active_fd_set); + + while (1) { + printf("GOT_SV2\n"); + // Shallow copies the readset + read_fd_set = active_fd_set; + + // Blocks until input arrives on one or more active sockets + if (select(FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0) { + if (out_flag) { + printf("GOT_SV2.1\n"); + out_flag = false; + continue; + } + printf("GOT_SV2.2\n"); + perror("Couldn't initiate synchronous I/O multiplexing."); + exit(EXIT_FAILURE); + } + + // Services all the sockets with input pending + for (int i = 0; i < FD_SETSIZE; ++i) { //TODO: is this needed? + if (FD_ISSET(i, &read_fd_set)) { + printf("GOT_SV3\n"); + if (i == sock) { + // Connection request on original socket + size = sizeof(client_name); + int new = accept(sock, (struct sockaddr *) &client_name, &size); + if (new < 0) { + perror("Couldn't accept the connection."); + exit(EXIT_FAILURE); + } + + fprintf(stderr, "Server: connect from host %s, port %hd.\n", + inet_ntoa(client_name.sin_addr), ntohs(client_name.sin_port)); + FD_SET(new, &active_fd_set); + } else if (i == sfd) { + ssize_t s = read(sfd, &fdsi, sizeof(struct signalfd_siginfo)); + if (s != sizeof(struct signalfd_siginfo)) + perror("read"); + + if (fdsi.ssi_signo == SIGALRM) { + printf("Got SIGALRM\n"); + handle_alarm(SIGALRM); + } else { + printf("Read unexpected signal\n"); + } + } else { + // Data arriving on an already-connected socket + if (read_from_client(i, MAXLINE) < 0) { + close(i); + FD_CLR(i, &active_fd_set); + } + } + } + } + printf("GOT_SV4\n"); + } + + return 0; +} \ No newline at end of file diff --git a/src/zaqar.h b/src/zaqar.h new file mode 100644 index 0000000..f05c668 --- /dev/null +++ b/src/zaqar.h @@ -0,0 +1,27 @@ +#ifndef ZAQAR_H_ +#define ZAQAR_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "helpers.h" + +#define PORT 5000 +#define MAXLINE 1024 +#define BACKLOG_SIZE 2 + +#endif //ZAQAR_H_