From 7a9101faf101c195fbf1712b89a8618bf1d45fb7 Mon Sep 17 00:00:00 2001
From: Philippe PITTOLI
Date: Fri, 23 Dec 2016 01:33:52 +0100
Subject: [PATCH] pongd fonctionnel
---
core/communication.c | 47 +++++++++++---
core/communication.h | 5 +-
core/msg.h | 11 ++--
core/process.c | 30 ++++++---
core/process.h | 6 +-
core/usocket.c | 8 +--
pong/app/Makefile | 4 ++
pong/app/pingpong.c | 108 --------------------------------
pong/app/pong.c | 117 +++++++++++++++++++++++++++++++++++
pong/app/pongd.c | 144 +++++++++++++++++++++++++++++++++++++++++++
10 files changed, 342 insertions(+), 138 deletions(-)
delete mode 100644 pong/app/pingpong.c
create mode 100644 pong/app/pong.c
create mode 100644 pong/app/pongd.c
diff --git a/core/communication.c b/core/communication.c
index b754b1f..e458c0c 100644
--- a/core/communication.c
+++ b/core/communication.c
@@ -69,6 +69,14 @@ int srv_close (struct service *srv)
int srv_close_proc (struct process *p)
{
+ // struct msg m_ack_dis;
+ // memset (&m_ack_dis, 0, sizeof (struct msg));
+ // m_ack_dis.type = MSG_TYPE_ACK_DIS;
+
+ // if (msg_write (p->proc_fd, &m_ack_dis) < 0) {
+ // handle_err ("srv_close_proc", "msg_write < 0");
+ // }
+
return usock_close (p->proc_fd);
}
@@ -128,6 +136,7 @@ int app_connection (int argc, char **argv, char **env
return 0;
}
+// send a DIS message then close the socket
int app_close (struct service *srv)
{
struct msg m;
@@ -137,6 +146,14 @@ int app_close (struct service *srv)
handle_err ("app_close", "msg_write < 0");
}
+ // if (msg_read (srv->service_fd, &m) < 0) {
+ // handle_err ("app_close", "msg_read < 0");
+ // }
+
+ // if (m.type != MSG_TYPE_ACK) {
+ // handle_err ("app_close", "msg received != ACK");
+ // }
+
return usock_close (srv->service_fd);
}
@@ -165,8 +182,14 @@ int app_write (struct service *srv, const struct msg *m)
*/
int srv_select (struct array_proc *ap, struct service *srv
- , struct process **proc)
+ , struct array_proc *proc)
{
+ assert (ap != NULL);
+ assert (proc != NULL);
+
+ // delete previous read process array
+ array_proc_free (proc);
+
int i, j;
/* master file descriptor list */
fd_set master;
@@ -183,14 +206,17 @@ int srv_select (struct array_proc *ap, struct service *srv
/* add the listener to the master set */
FD_SET(listener, &master);
- for(i=0; i < ap->size; i++) {
+ for (i=0; i < ap->size; i++) {
FD_SET(ap->tab_proc[i]->proc_fd, &master);
}
/* keep track of the biggest file descriptor */
fdmax = getMaxFd(ap) > srv->service_fd ? getMaxFd(ap) : srv->service_fd;
- while (1) {
+ int is_listener = 0;
+
+ do {
+ // printf ("loop srv_select main_loop\n");
readf = master;
if(select(fdmax+1, &readf, NULL, NULL, NULL) == -1) {
perror("select");
@@ -199,20 +225,27 @@ int srv_select (struct array_proc *ap, struct service *srv
/*run through the existing connections looking for data to be read*/
for (i = 0; i <= fdmax; i++) {
+ // printf ("loop srv_select inner loop\n");
if (FD_ISSET(i, &readf)) {
if (i == listener) {
- return CONNECTION;
+ is_listener = 1;
} else {
for(j = 0; j < ap->size; j++) {
+ // printf ("loop srv_select inner inner loop\n");
if(i == ap->tab_proc[j]->proc_fd ) {
- *proc = ap->tab_proc[j];
- return APPLICATION;
+ add_proc (proc, ap->tab_proc[j]);
}
}
}
}
}
- }
+ } while (0);
+
+ if (proc->size > 0 && is_listener)
+ return CON_APP;
+ if (proc->size > 0)
+ return APPLICATION;
+ return CONNECTION;
}
/*calculer le max filedescriptor*/
diff --git a/core/communication.h b/core/communication.h
index 5a7bb82..ad10601 100644
--- a/core/communication.h
+++ b/core/communication.h
@@ -18,8 +18,9 @@
#define PATH_MAX BUFSIZ
-#define CONNECTION 0
+#define CONNECTION 0
#define APPLICATION 1
+#define CON_APP 2
struct service {
unsigned int version;
@@ -42,7 +43,7 @@ int srv_accept (struct service *srv, struct process *p);
int srv_read (const struct process *, struct msg *m);
int srv_write (const struct process *, const struct msg *m);
-int srv_select(struct array_proc *, struct service *, struct process **);
+int srv_select (struct array_proc *, struct service *, struct array_proc *);
int getMaxFd(struct array_proc *);
diff --git a/core/msg.h b/core/msg.h
index c2c904b..70cd632 100644
--- a/core/msg.h
+++ b/core/msg.h
@@ -5,11 +5,12 @@
#include
#include
-#define MSG_TYPE_CON 1
-#define MSG_TYPE_DIS 2
-#define MSG_TYPE_ERR 3
-#define MSG_TYPE_ACK 4
-#define MSG_TYPE_DATA 5
+#define MSG_TYPE_CON 1
+#define MSG_TYPE_DIS 2
+#define MSG_TYPE_ERR 3
+#define MSG_TYPE_ACK 4
+#define MSG_TYPE_DATA 5
+#define MSG_TYPE_ACK_DIS 6
struct msg {
char type;
diff --git a/core/process.c b/core/process.c
index 507a3ac..4e2f7df 100644
--- a/core/process.c
+++ b/core/process.c
@@ -52,25 +52,36 @@ int add_proc (struct array_proc *aproc, struct process *p)
int del_proc (struct array_proc *aproc, struct process *p)
{
assert(aproc != NULL);
+ assert(aproc->tab_proc != NULL);
assert(p != NULL);
+ if (aproc->tab_proc == NULL) {
+ return -1;
+ }
+
int i;
for (i = 0; i < aproc->size; i++) {
if (aproc->tab_proc[i] == p) {
aproc->tab_proc[i] = aproc->tab_proc[aproc->size-1];
aproc->size--;
- aproc->tab_proc = realloc(aproc->tab_proc
- , sizeof(struct process) * aproc->size);
-
- if (aproc->tab_proc == NULL) {
- return -1;
+ if (aproc->size == 0) {
+ array_proc_free (aproc);
}
+ else {
+ aproc->tab_proc = realloc(aproc->tab_proc
+ , sizeof(struct process) * aproc->size);
+
+ if (aproc->tab_proc == NULL) {
+ return -2;
+ }
+ }
+
return 0;
}
}
- return -2;
+ return -3;
}
void process_print (struct process *p)
@@ -91,6 +102,9 @@ void array_proc_print (struct array_proc *ap)
void array_proc_free (struct array_proc *ap)
{
- if (ap->tab_proc != NULL)
- free (ap->tab_proc), ap->tab_proc = NULL;
+ if (ap->tab_proc != NULL) {
+ free (ap->tab_proc);
+ ap->tab_proc = NULL;
+ }
+ ap->size = 0;
}
diff --git a/core/process.h b/core/process.h
index f6ed0fe..cf65f45 100644
--- a/core/process.h
+++ b/core/process.h
@@ -12,11 +12,9 @@ struct array_proc {
int size;
};
-// TODO
-// tout revoir
-int add_proc(struct array_proc *, struct process *);
+int add_proc (struct array_proc *, struct process *);
-int del_proc(struct array_proc *, struct process *);
+int del_proc (struct array_proc *aproc, struct process *p);
void array_proc_print (struct array_proc *);
void array_proc_free (struct array_proc *);
diff --git a/core/usocket.c b/core/usocket.c
index 4a6a12b..908d79e 100644
--- a/core/usocket.c
+++ b/core/usocket.c
@@ -10,8 +10,8 @@
int usock_send (const int fd, const char *buf, const int msize)
{
- print_hexa ("msg send", (unsigned char *)buf, msize);
- fflush(stdout);
+ // print_hexa ("msg send", (unsigned char *)buf, msize);
+ // fflush(stdout);
int ret = 0;
//printf ("%ld bytes to write\n", msize);
@@ -53,8 +53,8 @@ int usock_recv (const int fd, char **buf, size_t *msize)
return ret;
}
*msize = (size_t) ret;
- print_hexa ("msg recv", (unsigned char *)*buf, *msize);
- fflush(stdout);
+ // print_hexa ("msg recv", (unsigned char *)*buf, *msize);
+ // fflush(stdout);
return ret;
}
diff --git a/pong/app/Makefile b/pong/app/Makefile
index 6972c25..239c6f7 100644
--- a/pong/app/Makefile
+++ b/pong/app/Makefile
@@ -9,6 +9,10 @@ TESTS=$(addsuffix .test, $(EXEC))
all: $(SOURCES) $(EXEC)
+test:
+ rm /tmp/ipc/pongd-0-0
+ ./pongd.bin
+
$(EXEC): $(OBJECTS) $(CFILES)
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJECTS) $@.c -lcbor -o $@.bin
diff --git a/pong/app/pingpong.c b/pong/app/pingpong.c
deleted file mode 100644
index f795018..0000000
--- a/pong/app/pingpong.c
+++ /dev/null
@@ -1,108 +0,0 @@
-#include "../../core/communication.h"
-#include
-#include
-#include "../../core/process.h"
-#include
-
-#define PONGD_SERVICE_NAME "pongd"
-#define handle_error(msg) \
- do { perror(msg); exit(EXIT_FAILURE); } while (0)
-
-
-
-/*
- * main loop
- *
- * opens the application pipes,
- * reads then writes the same message,
- * then closes the pipes
- */
-
-void main_loop (struct service *srv)
-{
-
- size_t msize = BUFSIZ;
- char *buf = NULL;
- if ( (buf = malloc (BUFSIZ)) == NULL) {
- handle_error ("malloc");
- }
- memset (buf, 0, BUFSIZ);
-
- int i,ret, cpt = 0;
-
- struct array_proc ap;
- memset(&ap, 0, sizeof(struct array_proc));
-
- struct process *p2 = malloc(sizeof(struct process));
-
- while(cpt < 5) {
- ret = srv_select(&ap, srv, &p2);
-
- if (ret == CONNECTION) {
- struct process *p = malloc(sizeof(struct process));
- memset(p, 0, sizeof(struct process));
- if (srv_accept (srv, p) < 0) {
- handle_error("srv_accept < 0");
- }else {
- printf("new connection\n");
- }
-
- if (add_proc(&ap, p) < 0) {
- handle_error("add_proc < 0");
- }
- cpt++;
- } else {
- if (srv_read(p2, &buf, &msize) < 0) {
- handle_error("srv_read < 0");
- }
-
- if (srv_write (p2, buf, msize) < 0) {
- handle_error("srv_write < 0");
- }
- }
- }
-
- for (i = 0; i < ap.size; i++) {
- if (srv_close_proc (ap.tab_proc[i]) < 0) {
- handle_error( "srv_close_proc < 0");
- }
- }
-}
-
-
-/*
- * service ping-pong
- *
- * 1. creates the named pipe /tmp/, then listens
- * 2. opens the named pipes in & out
- * 3. talks with the (test) program
- * 4. closes the test program named pipes
- * 5. removes the named pipe /tmp/
- */
-
-int main(int argc, char * argv[], char **env)
-{
- struct service srv;
- memset (&srv, 0, sizeof (struct service));
- srv.index = 0;
- srv.version = 0;
- unlink("/tmp/ipc/pongd-0-0");
- if (srv_init (argc, argv, env, &srv, PONGD_SERVICE_NAME) < 0) {
- handle_error("srv_init < 0");
- return EXIT_FAILURE;
- }
- printf ("Listening on %s.\n", srv.spath);
-
- printf("MAIN: server created\n" );
-
- // the service will loop until the end of time, a specific message, a signal
- main_loop (&srv);
-
- // the application will shut down, and remove the service named pipe
- if (srv_close (&srv) < 0) {
- handle_error("srv_close < 0");
-
- }
-
- return EXIT_SUCCESS;
-}
diff --git a/pong/app/pong.c b/pong/app/pong.c
new file mode 100644
index 0000000..966c91c
--- /dev/null
+++ b/pong/app/pong.c
@@ -0,0 +1,117 @@
+#include
+#include
+#include
+#include
+
+#include "../../core/msg.h"
+#include "../../core/error.h"
+#include "../../core/communication.h"
+
+#define MSG "coucou"
+#define SERVICE_NAME "pongd"
+
+void non_interactive (int argc, char *argv[], char *env[])
+{
+ struct msg m;
+ memset (&m, 0, sizeof (struct msg));
+ struct service srv;
+ memset (&srv, 0, sizeof (struct service));
+
+ // index and version should be filled
+ srv.index = 0;
+ srv.version = 0;
+
+ // init service
+ if (app_connection (argc, argv, env, &srv, SERVICE_NAME, NULL, 0) < 0) {
+ handle_err("main", "srv_init < 0");
+ exit (EXIT_FAILURE);
+ }
+
+ printf ("msg to send: %s\n", MSG);
+ msg_format_data (&m, MSG, strlen(MSG) +1);
+ printf ("msg to send in the client: ");
+ print_msg (&m);
+ if (app_write (&srv, &m) < 0) {
+ handle_err("main", "app_write < 0");
+ exit (EXIT_FAILURE);
+ }
+ msg_free (&m);
+
+ if (app_read (&srv, &m) < 0) {
+ handle_err("main", "app_read < 0");
+ exit (EXIT_FAILURE);
+ }
+
+ printf ("msg recv: %s\n", m.val);
+ msg_free (&m);
+
+ if (app_close (&srv) < 0) {
+ handle_err("main", "app_close < 0");
+ exit (EXIT_FAILURE);
+ }
+}
+
+void interactive (int argc, char *argv[], char *env[])
+{
+ struct msg m;
+ memset (&m, 0, sizeof (struct msg));
+ struct service srv;
+ memset (&srv, 0, sizeof (struct service));
+
+ char buf[BUFSIZ];
+ memset (buf, 0, BUFSIZ);
+ int n;
+
+ // index and version should be filled
+ srv.index = 0;
+ srv.version = 0;
+
+ // init service
+ if (app_connection (argc, argv, env, &srv, SERVICE_NAME, NULL, 0) < 0) {
+ handle_err ("main", "srv_init < 0");
+ exit (EXIT_FAILURE);
+ }
+
+ while (1) {
+ printf ("msg to send: ");
+ fflush (stdout);
+ n = read (0, buf, BUFSIZ);
+
+ if (n == 0 || strncmp (buf, "exit", 4) == 0)
+ break;
+
+ msg_format_data (&m, buf, strlen(buf) +1);
+ memset (buf, 0, BUFSIZ);
+
+ // print_msg (&m);
+
+ if (app_write (&srv, &m) < 0) {
+ handle_err("main", "app_write < 0");
+ exit (EXIT_FAILURE);
+ }
+ msg_free (&m);
+
+ if (app_read (&srv, &m) < 0) {
+ handle_err("main", "app_read < 0");
+ exit (EXIT_FAILURE);
+ }
+
+ printf ("msg recv: %s", m.val);
+ msg_free (&m);
+ }
+
+ if (app_close (&srv) < 0) {
+ handle_err("main", "app_close < 0");
+ exit (EXIT_FAILURE);
+ }
+}
+
+int main (int argc, char *argv[], char *env[])
+{
+ if (argc == 1)
+ non_interactive (argc, argv, env);
+ else
+ interactive (argc, argv, env);
+
+ return EXIT_SUCCESS;
+}
diff --git a/pong/app/pongd.c b/pong/app/pongd.c
new file mode 100644
index 0000000..de9adcf
--- /dev/null
+++ b/pong/app/pongd.c
@@ -0,0 +1,144 @@
+#include "../../core/communication.h"
+#include "../../core/process.h"
+#include "../../core/error.h"
+
+#include
+#include
+#include
+
+#define PONGD_SERVICE_NAME "pongd"
+
+int cpt = 0;
+
+void handle_new_connection (struct service *srv, struct array_proc *ap)
+{
+ struct process *p = malloc(sizeof(struct process));
+ memset(p, 0, sizeof(struct process));
+
+ if (srv_accept (srv, p) < 0) {
+ handle_error("srv_accept < 0");
+ } else {
+ printf("new connection\n");
+ }
+
+ if (add_proc (ap, p) < 0) {
+ handle_error("add_proc < 0");
+ }
+
+ cpt++;
+ printf ("%d client(s)\n", cpt);
+}
+
+void handle_new_msg (struct array_proc *ap, struct array_proc *proc_to_read)
+{
+ struct msg m;
+ memset (&m, 0, sizeof (struct msg));
+ int i;
+ for (i = 0; i < proc_to_read->size; i++) {
+ // printf ("loop handle_new_msg\n");
+ if (srv_read (proc_to_read->tab_proc[i], &m) < 0) {
+ handle_error("srv_read < 0");
+ }
+
+ // close the process then delete it from the process array
+ if (m.type == MSG_TYPE_DIS) {
+ cpt--;
+ printf ("disconnection => %d client(s) remaining\n", cpt);
+
+ if (srv_close_proc (proc_to_read->tab_proc[i]) < 0)
+ handle_error( "srv_close_proc < 0");
+ if (del_proc (ap, proc_to_read->tab_proc[i]) < 0)
+ handle_error( "del_proc < 0");
+ if (del_proc (proc_to_read, proc_to_read->tab_proc[i]) < 0)
+ handle_err( "handle_new_msg", "del_proc < 0");
+ i--;
+ continue;
+ }
+
+ printf ("new message : %s", m.val);
+ if (srv_write (proc_to_read->tab_proc[i], &m) < 0) {
+ handle_error("srv_write < 0");
+ }
+ }
+}
+
+/*
+ * main loop
+ *
+ * accept new application connections
+ * read a message and send it back
+ * close a connection if MSG_TYPE_DIS received
+ */
+
+void main_loop (struct service *srv)
+{
+ int i, ret = 0;
+
+ struct array_proc ap;
+ memset(&ap, 0, sizeof(struct array_proc));
+
+ struct array_proc proc_to_read;
+ memset(&proc_to_read, 0, sizeof(struct array_proc));
+
+ while(1) {
+ ret = srv_select (&ap, srv, &proc_to_read);
+ // printf ("on peut lire ces process:\n");
+ // array_proc_print (&proc_to_read);
+ // printf ("-- \n\n");
+
+ if (ret == CONNECTION) {
+ handle_new_connection (srv, &ap);
+ } else if (ret == APPLICATION) {
+ handle_new_msg (&ap, &proc_to_read);
+ } else { // both new connection and new msg from at least one client
+ handle_new_connection (srv, &ap);
+ handle_new_msg (&ap, &proc_to_read);
+ }
+ array_proc_free (&proc_to_read);
+ }
+
+ for (i = 0; i < ap.size; i++) {
+ if (srv_close_proc (ap.tab_proc[i]) < 0) {
+ handle_error( "srv_close_proc < 0");
+ }
+ }
+}
+
+
+/*
+ * service ping-pong
+ *
+ * 1. creates the named pipe /tmp/, then listens
+ * 2. opens the named pipes in & out
+ * 3. talks with the (test) program
+ * 4. closes the test program named pipes
+ * 5. removes the named pipe /tmp/
+ */
+
+int main(int argc, char * argv[], char **env)
+{
+ struct service srv;
+ memset (&srv, 0, sizeof (struct service));
+ srv.index = 0;
+ srv.version = 0;
+
+ // unlink("/tmp/ipc/pongd-0-0");
+
+ if (srv_init (argc, argv, env, &srv, PONGD_SERVICE_NAME) < 0) {
+ handle_error("srv_init < 0");
+ return EXIT_FAILURE;
+ }
+ printf ("Listening on %s.\n", srv.spath);
+
+ printf("MAIN: server created\n" );
+
+ // the service will loop until the end of time, a specific message, a signal
+ main_loop (&srv);
+
+ // the application will shut down, and remove the service named pipe
+ if (srv_close (&srv) < 0) {
+ handle_error("srv_close < 0");
+ }
+
+ return EXIT_SUCCESS;
+}