No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.cpp 9.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. #include <unistd.h>
  2. #include <stdio.h>
  3. #include <sys/socket.h>
  4. #include <stdlib.h>
  5. #include <netinet/in.h>
  6. #include <string.h>
  7. #include <iostream>
  8. #include <time.h>
  9. using namespace std;
  10. const char LABEL_ROBOT_PING = 'p';
  11. const char LABEL_ROBOT_RESET = 'r';
  12. const char LABEL_ROBOT_START_WITH_WD = 'W';
  13. const char LABEL_ROBOT_START_WITHOUT_WD = 'u';
  14. const char LABEL_ROBOT_RELOAD_WD = 'w';
  15. const char LABEL_ROBOT_MOVE = 'M';
  16. const char LABEL_ROBOT_TURN = 'T';
  17. const char LABEL_ROBOT_GET_BATTERY = 'v';
  18. const char LABEL_ROBOT_GET_STATE = 'b';
  19. const char LABEL_ROBOT_POWEROFF = 'z';
  20. const char LABEL_ROBOT_OK = 'O';
  21. const char LABEL_ROBOT_ERROR = 'E';
  22. const char LABEL_ROBOT_UNKNOWN_COMMAND = 'C';
  23. const char LABEL_ROBOT_SEPARATOR_CHAR = '=';
  24. const char LABEL_ROBOT_ENDING_CHAR = 0x0D;
  25. int server_fd, new_socket, valread;
  26. struct sockaddr_in address;
  27. int addrlen;
  28. #define PORT 6699
  29. int status = 0;
  30. int noerr = 0;
  31. int isWD = 0;
  32. long int ellapse(struct timespec ref, struct timespec cur) {
  33. long int e;
  34. e = cur.tv_sec - ref.tv_sec;
  35. e *= 1000000000;
  36. e += cur.tv_nsec - ref.tv_nsec;
  37. return e;
  38. }
  39. void print_time(struct timespec start_time) {
  40. struct timespec t;
  41. clock_gettime(CLOCK_REALTIME, &t);
  42. long int e = ellapse(start_time, t);
  43. fprintf(stdout, "%9ld", e / 1000000);
  44. }
  45. int simulate_error() {
  46. int r = rand() % 1000;
  47. if (r > 950) {
  48. printf("[I don't understand what you said (-1)]\n");
  49. return -1;
  50. } else if (r > 900) {
  51. printf("[I'm mute, because I never got your message (-2)]\n");
  52. return -2;
  53. }
  54. printf("[WILCO (0)] ");
  55. return 0;
  56. }
  57. void simulate_transmission_time() {
  58. usleep((rand() % 30) * 1000);
  59. }
  60. void open_server() {
  61. int opt = 1;
  62. // Creating socket file descriptor
  63. if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
  64. perror("socket failed");
  65. exit(EXIT_FAILURE);
  66. }
  67. // Forcefully attaching socket to the port 8080
  68. if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
  69. &opt, sizeof (opt))) {
  70. perror("setsockopt");
  71. exit(EXIT_FAILURE);
  72. }
  73. cout << "<<< simulator >>>" << endl;
  74. cout << ">>> Hello, I'm Mr " ;
  75. if (noerr) cout << "perfect ";
  76. cout << "Robot" << endl;
  77. // Forcefully attaching socket to the port 8080
  78. if (bind(server_fd, (struct sockaddr *) &address,
  79. sizeof (address)) < 0) {
  80. perror("bind failed");
  81. exit(EXIT_FAILURE);
  82. }
  83. cout << ">>> I create a server" << endl;
  84. cout << ">>> ..." << endl;
  85. }
  86. void wait_connection() {
  87. if (listen(server_fd, 3) < 0) {
  88. perror("listen");
  89. exit(EXIT_FAILURE);
  90. }
  91. cout << ">>> I'm waiting a client" << endl;
  92. if ((new_socket = accept(server_fd, (struct sockaddr *) &address,
  93. (socklen_t*) & addrlen)) < 0) {
  94. perror("accept");
  95. exit(EXIT_FAILURE);
  96. }
  97. }
  98. void reset(){
  99. isWD = 0;
  100. status = 0;
  101. cout << ">>> XX I stop XX" << endl;
  102. }
  103. int main(int argc, char const *argv[]) {
  104. if (argc != 1){
  105. if (argv[1] == std::string("noerror")){
  106. noerr = 1;
  107. }
  108. }
  109. char buffer[1024] = {0};
  110. addrlen = sizeof (address);
  111. address.sin_family = AF_INET;
  112. address.sin_addr.s_addr = INADDR_ANY;
  113. address.sin_port = htons(PORT);
  114. srand(time(NULL));
  115. open_server();
  116. wait_connection();
  117. cout << ">>> I'm ready to receive something" << endl;
  118. struct timespec start_time;
  119. clock_gettime(CLOCK_REALTIME, &start_time);
  120. struct timespec start_wd;
  121. struct timespec t;
  122. long int e;
  123. struct timespec last_call;
  124. clock_gettime(CLOCK_REALTIME, &last_call);
  125. isWD = 0;
  126. while (status < 3) {
  127. if (isWD) {
  128. clock_gettime(CLOCK_REALTIME, &t);
  129. e = ellapse(last_call, t);
  130. if ((e / 1000000000) > 3) {
  131. cout << ">>> You break my heart, you never talk at the right time." << endl;
  132. break;
  133. }
  134. }
  135. valread = read(new_socket, buffer, 1024);
  136. if (valread <= 0) {
  137. if (errno == EAGAIN) {
  138. status = 3;
  139. cout << ">>> You break my heart, I've been waiting too long for you." << endl;
  140. break;
  141. } else {
  142. cout << ">>> Why did you hang up? Please, contact me again." << endl;
  143. reset();
  144. wait_connection();
  145. clock_gettime(CLOCK_REALTIME, &last_call);
  146. }
  147. }
  148. string s = "";
  149. int error = 0;
  150. if (!noerr) error = simulate_error();
  151. if (error == 0) {
  152. print_time(start_time);
  153. printf(": I received a message %s\n", buffer);
  154. switch (buffer[0]) {
  155. case LABEL_ROBOT_START_WITHOUT_WD:
  156. cout << ">>> I start without watchdog" << endl;
  157. s += LABEL_ROBOT_OK;
  158. break;
  159. case LABEL_ROBOT_PING:
  160. cout << ">>> ...Pong" << endl;
  161. s += LABEL_ROBOT_OK;
  162. break;
  163. case LABEL_ROBOT_START_WITH_WD:
  164. clock_gettime(CLOCK_REALTIME, &start_wd);
  165. clock_gettime(CLOCK_REALTIME, &last_call);
  166. struct timeval tv;
  167. tv.tv_sec = 3;
  168. tv.tv_usec = 0;
  169. setsockopt(new_socket, SOL_SOCKET, SO_RCVTIMEO, (const char*) &tv, sizeof tv);
  170. cout << ">>> I start with watchdog" << endl;
  171. s += LABEL_ROBOT_OK;
  172. isWD = 1;
  173. break;
  174. case LABEL_ROBOT_MOVE:
  175. switch (buffer[2]) {
  176. case '0':
  177. cout << ">>> XX I stop XX" << endl;
  178. break;
  179. case '-':
  180. cout << ">>> \\/ I move backward \\/" << endl;
  181. break;
  182. default:
  183. cout << ">>> /\\ I move forward /\\" << endl;
  184. break;
  185. }
  186. s += LABEL_ROBOT_OK;
  187. break;
  188. case LABEL_ROBOT_TURN:
  189. switch (buffer[2]) {
  190. case '-':
  191. cout << ">>> << I turn to the left <<" << endl;
  192. break;
  193. default:
  194. cout << ">>> >> I turn to the right >>" << endl;
  195. break;
  196. }
  197. s += LABEL_ROBOT_OK;
  198. break;
  199. case LABEL_ROBOT_GET_BATTERY:
  200. cout << ">>> I give you my battery level :-o" << endl;
  201. clock_gettime(CLOCK_REALTIME, &t);
  202. e = ellapse(start_time, t);
  203. if (e > 20000000000) {
  204. s += '0';
  205. } else {
  206. if (e > 10000000000) {
  207. s += '1';
  208. } else {
  209. s += '2';
  210. }
  211. }
  212. break;
  213. case LABEL_ROBOT_RELOAD_WD:
  214. clock_gettime(CLOCK_REALTIME, &t);
  215. e = ellapse(start_wd, t);
  216. e = (e / 1000000) % 1000;
  217. if (isWD) {
  218. if ((e < 50) || (e > 950)) {
  219. cout << ">>> Just in time for a reload " << e << "ms" << endl;
  220. last_call = t;
  221. status = 0;
  222. s += LABEL_ROBOT_OK;
  223. } else {
  224. status++;
  225. cout << ">>> You missed the date, -1 point " << e << "ms (" << status << ")" << endl;
  226. s += LABEL_ROBOT_UNKNOWN_COMMAND;
  227. }
  228. } else {
  229. cout << "Why you said that, I do nothing" << endl;
  230. }
  231. break;
  232. case LABEL_ROBOT_POWEROFF:
  233. cout << ">>> Bye bye, see you soon" << endl;
  234. s += LABEL_ROBOT_OK;
  235. status = 10;
  236. break;
  237. case LABEL_ROBOT_RESET:
  238. cout << ">>> I reset" << endl;
  239. s += LABEL_ROBOT_OK;
  240. reset();
  241. break;
  242. case LABEL_ROBOT_GET_STATE:
  243. cout << ">>> I'm fine, thank you" << endl;
  244. s += LABEL_ROBOT_OK;
  245. break;
  246. default:
  247. //msg = new Message(MESSAGE_ANSWER_ROBOT_ERROR);
  248. cerr << "[" << __PRETTY_FUNCTION__ << "] Unknown message received from robot (" << buffer << ")" << endl << flush;
  249. }
  250. simulate_transmission_time();
  251. send(new_socket, s.c_str(), s.length(), 0);
  252. } else if (error == -1) {
  253. s += LABEL_ROBOT_UNKNOWN_COMMAND;
  254. simulate_transmission_time();
  255. send(new_socket, s.c_str(), s.length(), 0);
  256. } else if (error == -2) {
  257. /* Do nothing */
  258. }
  259. }
  260. cout << "The robot is out. End of story. " << endl;
  261. cout << " /\\_/\\" << endl << "( o.o )" << endl << " > ^ <" << endl;
  262. return 0;
  263. }