server.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. /*
  2. MSP430 Emulator
  3. Copyright (C) 2020 Rudolf Geosits (rgeosits@live.esu.edu)
  4. "MSP430 Emulator" is free software: you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation, either version 3 of the License, or
  7. (at your option) any later version.
  8. "MSP430 Emulator" is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. */
  15. #include "server.h"
  16. struct lws *ws = NULL;
  17. struct lws_context *context;
  18. pid_t emulator_pids[1000] = {0};
  19. void handle_sigchld(int sig)
  20. {
  21. int saved_errno = errno;
  22. while (waitpid((pid_t)(-1), 0, WNOHANG) > 0) {}
  23. errno = saved_errno;
  24. }
  25. void signal_callback_handler(int signum)
  26. {
  27. printf("Caught signal %d\n", signum);
  28. // Cleanup and close up stuff here
  29. int saved_errno = errno;
  30. while (waitpid((pid_t)(-1), 0, WNOHANG) > 0) {}
  31. errno = saved_errno;
  32. // Terminate program
  33. exit(signum);
  34. }
  35. void web_send (char *buf)
  36. {
  37. int len;
  38. char *msg, *begin;
  39. // send message
  40. len = strlen(buf);
  41. msg = (char *) malloc(len + LWS_SEND_BUFFER_PRE_PADDING
  42. + LWS_SEND_BUFFER_POST_PADDING);
  43. begin = msg + LWS_SEND_BUFFER_PRE_PADDING;
  44. strncpy(begin, buf, len);
  45. int n = lws_write(ws, begin, len, LWS_WRITE_TEXT);
  46. printf("sent %d bytes of %d len\n", n, len);
  47. free(msg);
  48. }
  49. int callback_http (
  50. struct lws *wsi,
  51. enum lws_callback_reasons reason,
  52. void *user, void *in, size_t len)
  53. {
  54. ws = wsi;
  55. return 0;
  56. }
  57. int callback_emu ( struct lws *wsi,
  58. enum lws_callback_reasons reason,
  59. void *user, void *in, size_t len )
  60. {
  61. static unsigned new_ws_port = 9001;
  62. char port_str[100] = {0};
  63. switch (reason) {
  64. case LWS_CALLBACK_PROTOCOL_INIT: {
  65. ws = wsi;
  66. break;
  67. };
  68. case LWS_CALLBACK_SERVER_WRITEABLE: {
  69. pid_t pid;
  70. sprintf(port_str, "%u", new_ws_port);
  71. // Child (pty)
  72. if( !(pid = fork()) ) {
  73. printf("Child: Got pid #%u\n", pid);
  74. char * const args[] = {
  75. "nice", "-20", "./MSP430", port_str,
  76. //"./MSP430", port_str,
  77. //"gdb", "-ex", "run", "--args", "./MSP430", port_str,
  78. NULL
  79. };
  80. setpgid(0, 0);
  81. execvp(args[0], args);
  82. exit(1);
  83. }
  84. // Parent
  85. printf("Parent: Got pid #%u\n", pid);
  86. usleep(1000);
  87. web_send(port_str);
  88. ++new_ws_port;
  89. lws_close_reason(wsi, 0, NULL, 0);
  90. break;
  91. };
  92. case LWS_CALLBACK_ESTABLISHED: {
  93. puts("connection established");
  94. lws_callback_on_writable(wsi);
  95. break;
  96. }
  97. default: {
  98. printf("Some other thing: %d\n", reason);
  99. break;
  100. ws = wsi;
  101. }
  102. }
  103. return 0;
  104. }
  105. int main (int argc, char **argv)
  106. {
  107. int port = 9000;
  108. struct lws_context_creation_info context_info =
  109. {
  110. .port = port,
  111. .iface = NULL,
  112. .protocols = protocols,
  113. .ssl_cert_filepath = NULL,
  114. .ssl_private_key_filepath = NULL,
  115. .ssl_ca_filepath = NULL,
  116. .gid = -1,
  117. .uid = -1,
  118. .max_http_header_pool = 1,
  119. .options = 0,
  120. };
  121. // create lws context representing this server
  122. context = lws_create_context(&context_info);
  123. if (context == NULL)
  124. {
  125. puts("lws init failed\n");
  126. return -1;
  127. }
  128. signal(SIGINT, signal_callback_handler);
  129. // Setup child reaping handler
  130. struct sigaction sa;
  131. sa.sa_handler = &handle_sigchld;
  132. sigemptyset(&sa.sa_mask);
  133. sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
  134. if (sigaction(SIGCHLD, &sa, 0) == -1)
  135. {
  136. perror(0);
  137. exit(1);
  138. }
  139. printf("starting server...\n");
  140. while (true)
  141. {
  142. lws_service(context, 10); // ms
  143. //lws_callback_on_writable_all_protocol(context, &protocols[1]);
  144. usleep(1000);
  145. }
  146. lws_context_destroy(context);
  147. return 0;
  148. }