networking.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #include <random>
  2. #include <algorithm>
  3. #include <iostream>
  4. #include <cstring>
  5. #include "networking.hpp"
  6. std::string random_string(std::default_random_engine& generator, size_t length)
  7. {
  8. auto randchar = [&]() -> char
  9. {
  10. const char charset[] =
  11. "0123456789_-"
  12. "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  13. "abcdefghijklmnopqrstuvwxyz";
  14. const size_t max_index = (sizeof(charset) - 1);
  15. std::uniform_int_distribution<int> dist(0, max_index - 1);
  16. return charset[ dist(generator) ];
  17. };
  18. std::string str(length,0);
  19. std::generate_n(str.begin(), length, randchar);
  20. return str;
  21. }
  22. char *set_temp_filename(
  23. std::default_random_engine& generator,
  24. struct mg_connection *conn)
  25. {
  26. std::string filename = random_string(generator, TMP_FILE_SIZE);
  27. char *c_filename = new char[TMP_FILE_SIZE+TMP_DIR_SIZE+1];
  28. strncpy(c_filename, TMP_DIR, TMP_DIR_SIZE);
  29. for (size_t i = 0; i < TMP_FILE_SIZE; i++)
  30. c_filename[i + TMP_DIR_SIZE] = filename[i];
  31. c_filename[TMP_DIR_SIZE + TMP_FILE_SIZE] = 0;
  32. if (conn)
  33. mg_set_user_connection_data(conn, c_filename);
  34. return c_filename;
  35. }
  36. bool RemoteControlHandler::handleGet(CivetServer *server, struct mg_connection *conn)
  37. {
  38. std::unique_lock<std::mutex> lck(sync->mtx);
  39. mg_printf(conn,
  40. "HTTP/1.1 200 OK\r\nContent-Type: "
  41. "text/plain\r\nConnection: close\r\n\r\n");
  42. if (message.empty())
  43. mg_printf(conn, "Event triggered.\n");
  44. else
  45. mg_printf(conn, "%s\n", message.c_str());
  46. sync->val++;
  47. sync->cv.notify_all();
  48. return true;
  49. }
  50. bool AltRemoteControlHandler::handleGet(CivetServer *server, struct mg_connection *conn)
  51. {
  52. std::unique_lock<std::mutex> lck(sync->mtx);
  53. const struct mg_request_info *info = mg_get_request_info(conn);
  54. if (info->query_string)
  55. query = info->query_string;
  56. mg_printf(conn,
  57. "HTTP/1.1 200 OK\r\nContent-Type: "
  58. "text/plain\r\nConnection: close\r\n\r\n");
  59. if (message.empty())
  60. mg_printf(conn, "Event triggered.\n");
  61. else
  62. mg_printf(conn, "%s\n", message.c_str());
  63. sync->val2 = value;
  64. sync->cv.notify_all();
  65. return true;
  66. }
  67. std::string AltRemoteControlHandler::getQuery() const
  68. {
  69. return query;
  70. }
  71. int empty_websocket_data_handler(
  72. struct mg_connection *conn,
  73. int bits,
  74. char *data,
  75. size_t data_len,
  76. void *user_data)
  77. { return false; }
  78. void empty_websocket_close_handler(
  79. const struct mg_connection *conn,
  80. void *user_data)
  81. { /* */ }
  82. int synchro_websocket_data_handler(
  83. struct mg_connection *conn,
  84. int bits,
  85. char *data,
  86. size_t data_len,
  87. void *user_data)
  88. {
  89. if ((bits & 0xf) == MG_WEBSOCKET_OPCODE_CONNECTION_CLOSE)
  90. return false;
  91. if ((bits & 0xf) == MG_WEBSOCKET_OPCODE_DATACOMPLETE)
  92. {
  93. struct synchronization_tool *sync = (struct synchronization_tool *) user_data;
  94. std::unique_lock<std::mutex> lck(sync->mtx);
  95. sync->val++;
  96. return false;
  97. }
  98. std::cerr << "Unknown response when trying to get update lock." << std::endl;
  99. return false;
  100. }
  101. void synchro_websocket_close_handler(
  102. const struct mg_connection *conn,
  103. void *user_data)
  104. {
  105. struct synchronization_tool *synch = (struct synchronization_tool *) user_data;
  106. std::unique_lock<std::mutex> lck(synch->mtx);
  107. synch->val2 = 1;
  108. synch->cv.notify_all();
  109. }
  110. int file_websocket_data_handler(
  111. struct mg_connection *conn,
  112. int bits,
  113. char *data,
  114. size_t data_len,
  115. void *user_data)
  116. {
  117. if ((bits & 0xf) == MG_WEBSOCKET_OPCODE_CONNECTION_CLOSE || (bits & 0xf) == MG_WEBSOCKET_OPCODE_DATACOMPLETE)
  118. return false;
  119. if ((bits & 0xf) != MG_WEBSOCKET_OPCODE_BINARY && (bits & 0xf) != MG_WEBSOCKET_OPCODE_CONTINUATION)
  120. {
  121. std::cerr << "Unknown opcode: failing." << std::endl;
  122. return false;
  123. }
  124. struct synchronization_tool *sync = (struct synchronization_tool *) user_data;
  125. char *filename = (char *) mg_get_user_connection_data(conn);
  126. std::unique_lock<std::mutex> lck(sync->mtx);
  127. FILE *currFile = fopen(filename, "ab");
  128. fwrite(data, sizeof(char), data_len, currFile);
  129. fclose(currFile);
  130. return true;
  131. }
  132. void file_websocket_close_handler(
  133. const struct mg_connection *conn,
  134. void *user_data)
  135. {
  136. struct synchronization_tool *sync = (struct synchronization_tool *) user_data;
  137. std::unique_lock<std::mutex> lck(sync->mtx);
  138. sync->val = 1;
  139. sync->val2 = 1;
  140. sync->cv.notify_all();
  141. }