diuhttp.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. //
  2. // gcc mongoose.c diuhttp.c -o diuhttp
  3. //
  4. #include "mongoose.h"
  5. #include <sys/time.h>
  6. #define _SLEN 1024
  7. static const char *s_http_port = "60535";
  8. static struct mg_serve_http_opts s_http_server_opts;
  9. static int is_websocket(const struct mg_connection *nc) {
  10. return nc->flags & MG_F_IS_WEBSOCKET;
  11. }
  12. long long int _get_usec_time() {
  13. struct timeval tv;
  14. gettimeofday(&tv,NULL);
  15. return (long long int)tv.tv_usec + (1000000 * (long long int)tv.tv_sec);
  16. }
  17. //
  18. // ui wants status information
  19. //
  20. static void handle_status_input(struct mg_connection *nc, struct http_message *hm) {
  21. char buf[_SLEN];
  22. char msg[][_SLEN] = {
  23. "fail error",
  24. "ok .",
  25. };
  26. //DEBUG sample message
  27. snprintf(buf, _SLEN, "ok msg=status\nroute=%s|trip=%s|stop=%s|gps=%i|tunnel=%i|date=%s|eqiupno=%s|nmsg=%s|last_token=%s|config=%s|firmware=%s|imei=%s|imsi=%s|eth0=%s",
  28. "9900", "1", "0",
  29. 1, 1,
  30. "2019-08-13 09;23:00",
  31. "9999", "0",
  32. "",
  33. "20190730v403 2019-11-05 02:36:43",
  34. "1.11 2019-07-30 16:33:08",
  35. "356136074279052",
  36. "310260877138191",
  37. "00:80:66:10:E8:8A");
  38. /*
  39. printf(">> status:\nbuf(%i):\n%s\n", (int)strlen(buf), buf);
  40. //snprintf(buf, _SLEN, "ok xxx=foo bar;yyy=baz qux;...");
  41. printf(">> status\n");
  42. */
  43. mg_printf(nc, "HTTP/1.1 200 OK\r\nContent-Length: %lu\r\n\r\n%s",
  44. (unsigned long)strlen(buf), buf);
  45. }
  46. // driver logout
  47. //
  48. static void handle_logout_input(struct mg_connection *nc, struct http_message *hm) {
  49. char msg[][_SLEN] = {
  50. "fail error",
  51. "ok .",
  52. };
  53. printf(">> logout\n");
  54. mg_printf(nc, "HTTP/1.1 200 OK\r\nContent-Length: %lu\r\n\r\n%s",
  55. (unsigned long)strlen(msg[1]), msg[1]);
  56. }
  57. // (manual) next stop pressed
  58. //
  59. static void handle_nextstop_input(struct mg_connection *nc, struct http_message *hm) {
  60. char msg[][_SLEN] = {
  61. "fail error",
  62. "ok .",
  63. };
  64. printf(">> nextstop\n");
  65. mg_printf(nc, "HTTP/1.1 200 OK\r\nContent-Length: %lu\r\n\r\n%s",
  66. (unsigned long)strlen(msg[1]), msg[1]);
  67. }
  68. // (manual) previous stop pressed
  69. //
  70. static void handle_prevstop_input(struct mg_connection *nc, struct http_message *hm) {
  71. char msg[][_SLEN] = {
  72. "fail error",
  73. "ok .",
  74. };
  75. printf(">> prevstop\n");
  76. mg_printf(nc, "HTTP/1.1 200 OK\r\nContent-Length: %lu\r\n\r\n%s",
  77. (unsigned long)strlen(msg[1]), msg[1]);
  78. }
  79. // generic fare input
  80. //
  81. static void handle_fare_input(struct mg_connection *nc, struct http_message *hm) {
  82. int ret;
  83. char s_fare[_SLEN], s_count[_SLEN];
  84. char msg[][_SLEN] = {
  85. "fail error",
  86. "ok .",
  87. };
  88. ret = mg_get_http_var(&(hm->body), "fare", s_fare, _SLEN);
  89. if (ret<=0) { mg_http_send_error(nc, 404, NULL); return; }
  90. printf("got fare %s\n", s_fare);
  91. ret = mg_get_http_var(&(hm->body), "count", s_count, _SLEN);
  92. if (ret<=0) { mg_http_send_error(nc, 404, NULL); return; }
  93. printf("got count %s\n", s_count);
  94. mg_printf(nc, "HTTP/1.1 200 OK\r\nContent-Length: %lu\r\n\r\n%s",
  95. (unsigned long)strlen(msg[1]), msg[1]);
  96. }
  97. // driver paddle (route) input
  98. //
  99. static void handle_paddle_input(struct mg_connection *nc, struct http_message *hm) {
  100. int ret;
  101. char s_paddle[_SLEN];
  102. char msg[][_SLEN] = {
  103. "fail paddle_unknown",
  104. "ok paddle",
  105. };
  106. ret = mg_get_http_var(&(hm->body), "paddle", s_paddle, _SLEN);
  107. if (ret<=0) { mg_http_send_error(nc, 404, NULL); return; }
  108. //DEBUG
  109. printf("#got paddle %s\n", s_paddle);
  110. //DEBUG
  111. if (strncmp(s_paddle,"9900", strlen("9900"))!=0) {
  112. mg_printf(nc, "HTTP/1.1 200 OK\r\nContent-Length: %lu\r\n\r\n%s",
  113. (unsigned long)strlen(msg[0]), msg[0]);
  114. return;
  115. }
  116. mg_printf(nc, "HTTP/1.1 200 OK\r\nContent-Length: %lu\r\n\r\n%s",
  117. (unsigned long)strlen(msg[1]), msg[1]);
  118. }
  119. // driver login
  120. //
  121. static void handle_driver_login(struct mg_connection *nc, struct http_message *hm) {
  122. int ret;
  123. char s_driver[_SLEN], s_pin[_SLEN];
  124. char msg[][_SLEN] = {
  125. "fail driver_not_found",
  126. "fail pin_invalid",
  127. "ok driver",
  128. "ok admin",
  129. };
  130. ret = mg_get_http_var(&(hm->body), "driver", s_driver, _SLEN);
  131. if (ret<=0) { mg_http_send_error(nc, 404, NULL); return; }
  132. ret = mg_get_http_var(&(hm->body), "pin", s_pin, _SLEN);
  133. if (ret<=0) { mg_http_send_error(nc, 404, NULL); return; }
  134. //DEBUG
  135. printf("#got %s %s\n", s_driver, s_pin);
  136. //DEBUG
  137. if (strncmp(s_driver,"81000", strlen("81000"))!=0) {
  138. mg_printf(nc, "HTTP/1.1 200 OK\r\nContent-Length: %lu\r\n\r\n%s",
  139. (unsigned long)strlen(msg[0]), msg[0]);
  140. return;
  141. }
  142. if (strncmp(s_pin,"81000", strlen("81000"))!=0) {
  143. mg_printf(nc, "HTTP/1.1 200 OK\r\nContent-Length: %lu\r\n\r\n%s",
  144. (unsigned long)strlen(msg[1]), msg[1]);
  145. return;
  146. }
  147. mg_printf(nc, "HTTP/1.1 200 OK\r\nContent-Length: %lu\r\n\r\n%s",
  148. (unsigned long)strlen(msg[3]), msg[3]);
  149. }
  150. // api point
  151. //
  152. static void handle_req(struct mg_connection *nc, struct http_message *hm) {
  153. int ret;
  154. char s_action[_SLEN];
  155. char _default_msg[_SLEN] = "";
  156. struct mg_str hdr;
  157. ret = mg_get_http_var(&(hm->body), "action", s_action, _SLEN);
  158. if (ret==0) {
  159. printf(">>> %p\n", s_action);
  160. mg_http_send_error(nc, 404, NULL);
  161. return;
  162. }
  163. printf("#req: action: (%s)\n", s_action);
  164. if (strncmp(s_action, "driverlogin", strlen("driverlogin"))==0) {
  165. handle_driver_login(nc, hm);
  166. }
  167. else if (strncmp(s_action, "paddleinput", strlen("paddleinput"))==0) {
  168. handle_paddle_input(nc, hm);
  169. }
  170. else if (strncmp(s_action, "prevstop", strlen("prevstop"))==0) {
  171. handle_prevstop_input(nc, hm);
  172. }
  173. else if (strncmp(s_action, "nextstop", strlen("nextstop"))==0) {
  174. handle_nextstop_input(nc, hm);
  175. }
  176. else if (strncmp(s_action, "status", strlen("status"))==0) {
  177. handle_status_input(nc, hm);
  178. }
  179. else if (strncmp(s_action, "logout", strlen("logout"))==0) {
  180. handle_logout_input(nc, hm);
  181. }
  182. else if (strncmp(s_action, "fare", strlen("fare"))==0) {
  183. handle_fare_input(nc, hm);
  184. }
  185. else {
  186. mg_http_send_error(nc, 404, NULL);
  187. }
  188. }
  189. static void process_ws_message(struct websocket_message *ws_msg) {
  190. int i;
  191. char *data;
  192. data = (char *)(ws_msg->data);
  193. printf("#ws, got(%i)\n:", (int)(ws_msg->size));
  194. for (i=0; i<ws_msg->size; i++) {
  195. printf("%c", data[i]);
  196. }
  197. printf("\n");
  198. }
  199. static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
  200. struct http_message *hm = (struct http_message *) ev_data;
  201. int debug_print = 0;
  202. int i;
  203. char buf[1024];
  204. if (debug_print) {
  205. mg_sock_addr_to_str(&(nc->sa), buf, 1023, MG_SOCK_STRINGIFY_IP);
  206. printf("%s\n", buf);
  207. }
  208. switch (ev){
  209. case MG_EV_HTTP_REQUEST:
  210. if (mg_vcmp(&hm->uri, "/req")==0) {
  211. handle_req(nc, (struct http_message *)ev_data);
  212. }
  213. else {
  214. mg_serve_http(nc, (struct http_message *) ev_data, s_http_server_opts);
  215. }
  216. break;
  217. case MG_EV_WEBSOCKET_HANDSHAKE_DONE:
  218. printf("ws handshake done\n");
  219. break;
  220. case MG_EV_WEBSOCKET_FRAME:
  221. process_ws_message((struct websocket_message *)ev_data);
  222. break;
  223. case MG_EV_CLOSE:
  224. if (is_websocket(nc)) {
  225. printf("ws closed\n");
  226. }
  227. break;
  228. default:
  229. //printf("? %i\n", ev);
  230. break;
  231. }
  232. }
  233. static void foo(struct mg_mgr *mgr) {
  234. int n;
  235. char buf[_SLEN];
  236. struct mg_connection *c;
  237. for (c=mg_next(mgr, NULL); c ; c = mg_next(mgr, c)) {
  238. printf("...\n");
  239. snprintf(buf, _SLEN, "hello");
  240. n = strlen(buf);
  241. mg_send_websocket_frame(c, WEBSOCKET_OP_TEXT, buf, n);
  242. }
  243. }
  244. static void send_ws_heartbeat(struct mg_connection *nc) {
  245. int n;
  246. char buf[_SLEN];
  247. struct mg_connection *c;
  248. for (c=mg_next(nc->mgr, NULL); c ; c = mg_next(nc->mgr, c)) {
  249. if (c==nc) { continue; }
  250. if (!is_websocket(c)) { continue; }
  251. printf("...\n");
  252. snprintf(buf, _SLEN, "hello");
  253. n = strlen(buf);
  254. mg_send_websocket_frame(c, WEBSOCKET_OP_TEXT, buf, n);
  255. }
  256. }
  257. int main(void) {
  258. struct mg_mgr mgr;
  259. struct mg_connection *nc;
  260. struct timeval tv_now, tv_prv;
  261. long long int _tnow, _tprv;
  262. mg_mgr_init(&mgr, NULL);
  263. printf("Starting web server on port %s\n", s_http_port);
  264. nc = mg_bind(&mgr, s_http_port, ev_handler);
  265. if (nc == NULL) {
  266. printf("Failed to create listener\n");
  267. return 1;
  268. }
  269. // Set up HTTP server parameters
  270. mg_set_protocol_http_websocket(nc);
  271. s_http_server_opts.document_root = "html";
  272. s_http_server_opts.enable_directory_listing = "no";
  273. _tprv = _get_usec_time();
  274. for (;;) {
  275. mg_mgr_poll(&mgr, 1000);
  276. _tnow = _get_usec_time();
  277. if ((_tnow - _tprv) > 1000) {
  278. send_ws_heartbeat(nc);
  279. _tprv = _tnow;
  280. }
  281. //foo(&mgr);
  282. }
  283. mg_mgr_free(&mgr);
  284. return 0;
  285. }