/* * Copyright (c) 2021 Clementine Computing LLC. * * This file is part of PopuFare. * * PopuFare is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * PopuFare is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with PopuFare. If not, see . * */ /* * PIU interface server. * piumsgd is in charge of passing messages from the underlying system * to the passenger via a websocket connection. * * piumsgd also acts as the web server to serve the local passenger * interface HTML/CSS/JS files. */ #include #include #include #include #include #include "mongoose.h" struct mg_mgr g_mgr; //char s_web_directory[] = "."; char s_web_directory[] = "/home/bus/config/html"; /* void ws_send(struct mg_mgr *mgr, char *msg) { struct mg_connection *conn; for (conn = mg_next(mgr, NULL); conn; conn = mg_next(mgr, conn)) { if (!is_websocket(conn)) { continue; } mg_send_websocket_frame(conn, WEBSOCKET_OP_TEXT, msg, strlen(msg)); } } */ void _ws_send(struct mg_mgr *mgr, char *msg, size_t msg_n) { int i; struct mg_connection *con; printf(" ... "); for (i=0; iconns; con; con = con->next) { printf(" ...con %i %i\n", con->is_websocket, con->is_client); //if (con->is_websocket && con->is_client) { if (con->is_websocket && con->is_accepted) { printf(" !!\n"); mg_ws_send(con, msg, msg_n, WEBSOCKET_OP_TEXT); } } } /* void _ws_send_str(struct mg_connection *mgc, char *msg) { size_t msg_n; msg_n = strlen(msg); _ws_send(mgc, msg, msg_n); } */ static void _cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { int i; size_t n; struct mg_http_message *hm = NULL; if (ev == MG_EV_HTTP_MSG) { printf("bang\n"); fflush(stdout); hm = (struct mg_http_message *) ev_data; //DEBUG //ptr len /* printf("body:\n"); for (i=0; ibody.len; i++) { printf("%i (%c)\n", hm->body.ptr[i], hm->body.ptr[i]); } printf("message:\n"); for (i=0; imessage.len; i++) { printf("%c", hm->message.ptr[i], hm->message.ptr[i]); } printf("\n\n"); */ if (mg_http_match_uri(hm, "/ws")) { // Upgrade to websocket. From now on, a connection is a full-duplex // Websocket connection, which will receive MG_EV_WS_MSG events. // printf("ws request?\n"); fflush(stdout); mg_ws_upgrade(c, hm, NULL); } else if (mg_http_match_uri(hm, "/")) { printf("html request? (1)\n"); fflush(stdout); struct mg_http_serve_opts opts = {.root_dir = s_web_directory}; mg_http_serve_dir(c, hm, &opts); } else if (mg_http_match_uri(hm, "/rest")) { printf("other req?\n"); // Serve REST response // mg_http_reply(c, 200, "", "{\"result\": %d}\n", 123); } else { printf("cp x\n"); // Serve static files // struct mg_http_serve_opts opts = {.root_dir = s_web_directory}; mg_http_serve_dir(c, (mg_http_message *)ev_data, &opts); } } else if (ev == MG_EV_WS_MSG) { // Got websocket frame. Received data is wm->data. Echo it back! // struct mg_ws_message *wm = (struct mg_ws_message *) ev_data; printf(">>> "); for (int i=0; idata.len; i++) { printf("%c", *(wm->data.ptr + i)); } printf("\n"); fflush(stdout); n = strlen("relay "); if (wm->data.len < n) { n = wm->data.len; } if (n < wm->data.len) { if (strncmp("relay ", (char *)(wm->data.ptr), n)==0) { _ws_send(&g_mgr, ((char *)(wm->data.ptr)) + n, wm->data.len - n); } } mg_ws_send(c, wm->data.ptr, wm->data.len, WEBSOCKET_OP_TEXT); mg_iobuf_delete(&c->recv, c->recv.len); printf("broadcasting...\n"); n = strlen("broadcast"); _ws_send(&g_mgr, (char *)"broadcast", n); } (void) fn_data; } int main(int argc, char **argv) { //struct pollfd fds[32]; int nfd=0; int poll_return; int read_return; time_t now; struct mg_conneciton *nc; // setup mongoose web server // mg_mgr_init(&g_mgr); //mg_http_listen(&g_mgr, "http://127.0.0.1:8001", _cb, NULL); mg_http_listen(&g_mgr, "http://0.0.0.0:8001", _cb, NULL); for (;;) { mg_mgr_poll(&g_mgr, 200); } mg_mgr_free(&g_mgr); return 0; }