From 89a2bae5c0df5403dc049a61f6ea5527bef205e7 Mon Sep 17 00:00:00 2001
From: pehladik <pehladik@gmail.com>
Date: Thu, 19 Mar 2020 15:27:25 +0100
Subject: [PATCH] update simulator with watchdog, ping, reset, poweroff and
 relaod commands

---
 software/simulateur/main.cpp | 154 ++++++++++++++++++++++++++++-------
 1 file changed, 125 insertions(+), 29 deletions(-)

diff --git a/software/simulateur/main.cpp b/software/simulateur/main.cpp
index b486d46..88ec86c 100644
--- a/software/simulateur/main.cpp
+++ b/software/simulateur/main.cpp
@@ -27,8 +27,14 @@ const char LABEL_ROBOT_SEPARATOR_CHAR = '=';
 const char LABEL_ROBOT_ENDING_CHAR = 0x0D;
 
 int server_fd, new_socket, valread;
+struct sockaddr_in address;
+int addrlen;
 #define PORT 6699
 
+int status = 0;
+int noerr = 0;
+int isWD = 0;
+
 long int ellapse(struct timespec ref, struct timespec cur) {
     long int e;
     e = cur.tv_sec - ref.tv_sec;
@@ -47,13 +53,13 @@ void print_time(struct timespec start_time) {
 int simulate_error() {
     int r = rand() % 1000;
     if (r > 950) {
-        printf(">>> I don't understand what you said (-1)\n");
+        printf("[I don't understand what you said (-1)]\n");
         return -1;
     } else if (r > 900) {
-        printf(">>> I don't want to respond (-2)\n");
+        printf("[I'm mute, because I never got your message (-2)]\n");
         return -2;
     }
-    printf(">>> WILCO (0)\n");
+    printf("[WILCO (0)] ");
     return 0;
 }
 
@@ -62,12 +68,8 @@ void simulate_transmission_time() {
 }
 
 void open_server() {
-    struct sockaddr_in address;
+
     int opt = 1;
-    int addrlen = sizeof (address);
-
-    srand(time(NULL));
-
     // Creating socket file descriptor 
     if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
         perror("socket failed");
@@ -80,11 +82,11 @@ void open_server() {
         perror("setsockopt");
         exit(EXIT_FAILURE);
     }
-    address.sin_family = AF_INET;
-    address.sin_addr.s_addr = INADDR_ANY;
-    address.sin_port = htons(PORT);
 
-    cout << "<<< simulator >>>" << endl;
+    cout << "<<< simulator >>>" << endl;    
+    cout << ">>> Hello, I'm Mr " ;
+    if (noerr) cout << "perfect ";
+    cout << "Robot" << endl;
 
     // Forcefully attaching socket to the port 8080 
     if (bind(server_fd, (struct sockaddr *) &address,
@@ -94,13 +96,16 @@ void open_server() {
     }
     cout << ">>> I create a server" << endl;
     cout << ">>> ..." << endl;
-    cout << ">>> I'm waiting a client" << endl;
+
+}
+
+void wait_connection() {
     if (listen(server_fd, 3) < 0) {
         perror("listen");
         exit(EXIT_FAILURE);
     }
 
-    cout << ">>> Hello, I'm Robot" << endl;
+    cout << ">>> I'm waiting a client" << endl;
     if ((new_socket = accept(server_fd, (struct sockaddr *) &address,
             (socklen_t*) & addrlen)) < 0) {
         perror("accept");
@@ -108,33 +113,97 @@ void open_server() {
     }
 }
 
+void reset(){
+    isWD = 0;
+    status = 0;   
+    cout << ">>> XX I stop XX" << endl;
+}
+
 int main(int argc, char const *argv[]) {
+    if (argc != 1){
+        if (argv[1] == std::string("noerror")){
+            noerr = 1;
+        }
+    }
 
     char buffer[1024] = {0};
+    addrlen = sizeof (address);
+    address.sin_family = AF_INET;
+    address.sin_addr.s_addr = INADDR_ANY;
+    address.sin_port = htons(PORT);
+
+    srand(time(NULL));
+
     open_server();
+    wait_connection();
     cout << ">>> I'm ready to receive something" << endl;
     struct timespec start_time;
     clock_gettime(CLOCK_REALTIME, &start_time);
+    struct timespec start_wd;
+
+
+    struct timespec t;
+
+    long int e;
+    struct timespec last_call;
+    clock_gettime(CLOCK_REALTIME, &last_call);
+    isWD = 0;
+
+    while (status < 3) {
+
+        if (isWD) {
+            clock_gettime(CLOCK_REALTIME, &t);
+            e = ellapse(last_call, t);
+            if ((e / 1000000000) > 3) {
+                cout << ">>> You break my heart, you never talk at the right time." << endl;
+                break;
+            }
+        }
+
 
-    while (1) {
         valread = read(new_socket, buffer, 1024);
-        if (valread <= 0)
-            break;
-        print_time(start_time);
-        printf(" >>> I received a message : %s\n", buffer);
+        if (valread <= 0) {
+            if (errno == EAGAIN) {
+                status = 3;
+                cout << ">>> You break my heart, I've been waiting too long for you." << endl;
+                break;
+            } else {
+                cout << ">>> Why did you hang up? Please, contact me again." << endl;
+                reset();
+                wait_connection();
+                clock_gettime(CLOCK_REALTIME, &last_call);
+            }
+        }
         string s = "";
-        int error = simulate_error();
+        int error = 0;
+        
+        if (!noerr) error = simulate_error();
+        
         if (error == 0) {
-            struct timespec t;
-            long int e;
+
+            print_time(start_time);
+            printf(": I received a message %s\n", buffer);
             switch (buffer[0]) {
                 case LABEL_ROBOT_START_WITHOUT_WD:
                     cout << ">>> I start without watchdog" << endl;
                     s += LABEL_ROBOT_OK;
                     break;
-                case LABEL_ROBOT_START_WITH_WD:
+                case LABEL_ROBOT_PING:
+                    cout << ">>> ...Pong" << endl;
                     s += LABEL_ROBOT_OK;
                     break;
+                case LABEL_ROBOT_START_WITH_WD:
+                    clock_gettime(CLOCK_REALTIME, &start_wd);
+                    clock_gettime(CLOCK_REALTIME, &last_call);
+                    struct timeval tv;
+                    tv.tv_sec = 3;
+                    tv.tv_usec = 0;
+                    setsockopt(new_socket, SOL_SOCKET, SO_RCVTIMEO, (const char*) &tv, sizeof tv);
+
+                    cout << ">>> I start with watchdog" << endl;
+                    s += LABEL_ROBOT_OK;
+                    isWD = 1;
+                    break;
                 case LABEL_ROBOT_MOVE:
                     switch (buffer[2]) {
                         case '0':
@@ -175,11 +244,37 @@ int main(int argc, char const *argv[]) {
                     }
                     break;
                 case LABEL_ROBOT_RELOAD_WD:
-                    cout << ">>> I start with watchdog" << endl;
-                    s += LABEL_ROBOT_OK;
+                    clock_gettime(CLOCK_REALTIME, &t);
+                    e = ellapse(start_wd, t);
+                    e = (e / 1000000) % 1000;
+                    if (isWD) {
+                        if ((e < 50) || (e > 950)) {
+                            cout << ">>> Just in time for a reload " << e << "ms" << endl;
+                            last_call = t;
+                            status = 0;
+                            s += LABEL_ROBOT_OK;
+                        } else {
+                            status++;
+                            cout << ">>> You missed the date, -1 point " << e << "ms (" << status << ")" << endl;
+
+                            s += LABEL_ROBOT_UNKNOWN_COMMAND;
+                        }
+                    } else {
+                        cout << "Why you said that, I do nothing" << endl;
+                    }
                     break;
                 case LABEL_ROBOT_POWEROFF:
-                    cout << ">>> Bye bye" << endl;
+                    cout << ">>> Bye bye, see you soon" << endl;
+                    s += LABEL_ROBOT_OK;
+                    status = 10;
+                    break;
+                case LABEL_ROBOT_RESET:
+                    cout << ">>> I reset" << endl;
+                    s += LABEL_ROBOT_OK;
+                    reset();
+                    break;
+                case LABEL_ROBOT_GET_STATE:
+                    cout << ">>> I'm fine, thank you" << endl;
                     s += LABEL_ROBOT_OK;
                     break;
                 default:
@@ -188,15 +283,16 @@ int main(int argc, char const *argv[]) {
             }
             simulate_transmission_time();
             send(new_socket, s.c_str(), s.length(), 0);
-        } else if (error == -1){
+        } else if (error == -1) {
             s += LABEL_ROBOT_UNKNOWN_COMMAND;
             simulate_transmission_time();
             send(new_socket, s.c_str(), s.length(), 0);
-        } else if (error == -2){
+        } else if (error == -2) {
             /* Do nothing */
         }
     }
-    cout << "The robot is dead. End of story. " << endl;
+
+    cout << "The robot is out. End of story. " << endl;
     cout << " /\\_/\\" << endl << "( o.o )" << endl << " > ^ <" << endl;
     return 0;
 } 
\ No newline at end of file