diff --git a/trick_sims/Cannon/SIM_cannon_numeric/S_define b/trick_sims/Cannon/SIM_cannon_numeric/S_define
index e63fd141..54566b93 100644
--- a/trick_sims/Cannon/SIM_cannon_numeric/S_define
+++ b/trick_sims/Cannon/SIM_cannon_numeric/S_define
@@ -5,11 +5,25 @@ LIBRARY DEPENDENCIES:
(
(cannon/gravity/src/cannon_init.c)
(cannon/gravity/src/cannon_numeric.c)
+ (mongoose_httpd/src/http_server.cpp)
)
*************************************************************/
#include "sim_objects/default_trick_sys.sm"
##include "cannon/gravity/include/cannon_numeric.h"
+##include "mongoose_httpd/include/http_server.h"
+
+class HttpSimObject : public Trick::SimObject {
+
+ public:
+ HTTP_Server http_server ;
+
+ HttpSimObject() {
+ ("default_data") http_default_data( &http_server ) ;
+ ("initialization") http_init( &http_server ) ;
+ ("shutdown") http_shutdown( &http_server ) ;
+ }
+} ;
class CannonSimObject : public Trick::SimObject {
@@ -27,6 +41,7 @@ class CannonSimObject : public Trick::SimObject {
// Instantiations
CannonSimObject dyn ;
+HttpSimObject http ;
IntegLoop dyn_integloop (0.01) dyn;
diff --git a/trick_sims/Cannon/SIM_cannon_numeric/S_overrides.mk b/trick_sims/Cannon/SIM_cannon_numeric/S_overrides.mk
index a2eff6d4..3a3073fb 100644
--- a/trick_sims/Cannon/SIM_cannon_numeric/S_overrides.mk
+++ b/trick_sims/Cannon/SIM_cannon_numeric/S_overrides.mk
@@ -1,4 +1,7 @@
-TRICK_CFLAGS += -I../models
-TRICK_CXXFLAGS += -I../models
+TRICK_CFLAGS += -I/usr/include -I../models
+TRICK_CXXFLAGS += -I/usr/include -I../models
+
+TRICK_LDFLAGS += -L/usr/local/lib
+TRICK_USER_LINK_LIBS += -lmongoose
diff --git a/trick_sims/Cannon/SIM_cannon_numeric/www/apps/alloc_info.html b/trick_sims/Cannon/SIM_cannon_numeric/www/apps/alloc_info.html
new file mode 100644
index 00000000..04bfb75c
--- /dev/null
+++ b/trick_sims/Cannon/SIM_cannon_numeric/www/apps/alloc_info.html
@@ -0,0 +1,156 @@
+
+
+
+
+Trick Memory Allocations
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/trick_sims/Cannon/SIM_cannon_numeric/www/apps/vs_connections.html b/trick_sims/Cannon/SIM_cannon_numeric/www/apps/vs_connections.html
new file mode 100644
index 00000000..90dd01a5
--- /dev/null
+++ b/trick_sims/Cannon/SIM_cannon_numeric/www/apps/vs_connections.html
@@ -0,0 +1,74 @@
+
+
+
+ Variable Server Connections
+
+
+
+
+
+
+
+
diff --git a/trick_sims/Cannon/SIM_cannon_numeric/www/apps/wsexp.html b/trick_sims/Cannon/SIM_cannon_numeric/www/apps/wsexp.html
new file mode 100644
index 00000000..322b70c2
--- /dev/null
+++ b/trick_sims/Cannon/SIM_cannon_numeric/www/apps/wsexp.html
@@ -0,0 +1,41 @@
+
+
+
+ WS Experiments
+
+
+
+
+
+
+
+
diff --git a/trick_sims/Cannon/SIM_cannon_numeric/www/index.html b/trick_sims/Cannon/SIM_cannon_numeric/www/index.html
new file mode 100644
index 00000000..cdb04443
--- /dev/null
+++ b/trick_sims/Cannon/SIM_cannon_numeric/www/index.html
@@ -0,0 +1,28 @@
+
+
+
+ Trick Simulation Pages
+
+
+
+
+
SIM_cannon_numeric
+
+
+
+
+
+
+
+
diff --git a/trick_sims/Cannon/models/mongoose_httpd/include/http_server.h b/trick_sims/Cannon/models/mongoose_httpd/include/http_server.h
new file mode 100644
index 00000000..90efbeca
--- /dev/null
+++ b/trick_sims/Cannon/models/mongoose_httpd/include/http_server.h
@@ -0,0 +1,33 @@
+/*************************************************************************
+PURPOSE: (Represent the state and initial conditions of an http server)
+**************************************************************************/
+#ifndef HTTP_SERVER_H
+#define HTTP_SERVER_H
+
+#include
+#include
+#include
+#include
+#include
+
+typedef struct {
+
+ struct mg_mgr mgr; /* ** mongoose */
+ struct mg_connection *nc; /* ** mongoose */
+ const char* port;
+ pthread_t server_thread; /* ** */
+ bool shutting_down;
+
+} HTTP_Server ;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ int http_default_data(HTTP_Server * S) ;
+ int http_init(HTTP_Server * S) ;
+ int http_shutdown(HTTP_Server * S) ;
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/trick_sims/Cannon/models/mongoose_httpd/src/http_server.cpp b/trick_sims/Cannon/models/mongoose_httpd/src/http_server.cpp
new file mode 100644
index 00000000..7300cb9b
--- /dev/null
+++ b/trick_sims/Cannon/models/mongoose_httpd/src/http_server.cpp
@@ -0,0 +1,150 @@
+/************************************************************************
+PURPOSE: (Represent the state and initial conditions of an http server)
+**************************************************************************/
+#include "../include/http_server.h"
+#include
+
+#include "trick/VariableServer.hh"
+extern Trick::VariableServer * the_vs ;
+#include "trick/MemoryManager.hh"
+extern Trick::MemoryManager* trick_MM;
+
+static const struct mg_str s_get_method = MG_MK_STR("GET");
+static const struct mg_str s_put_method = MG_MK_STR("PUT");
+static const struct mg_str s_delele_method = MG_MK_STR("DELETE");
+
+int getIntegerQueryValue(struct http_message *hm, const char* key, int defaultVal) {
+ char value_text[100];
+ if ( mg_get_http_var(&(hm->query_string), key, value_text, sizeof(value_text)) > 0) {
+ return atoi(value_text);
+ } else {
+ return defaultVal;
+ }
+}
+
+void handle_vs_connections_call(struct mg_connection *nc, struct http_message *hm) {
+ /* Send headers */
+ mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
+ std::stringstream ss;
+ ss << *the_vs << std::endl;
+ std::string tmp = ss.str();
+ mg_printf_http_chunk(nc, "%s", tmp.c_str());
+ mg_send_http_chunk(nc, "", 0);
+}
+
+void handle_alloc_info_call(struct mg_connection *nc, struct http_message *hm) {
+ int start = getIntegerQueryValue(hm, "start", 0);
+ int count = getIntegerQueryValue(hm, "count", 10);
+ mg_printf(nc, "%s", "HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n");
+ std::stringstream ss;
+ trick_MM->write_JSON_alloc_list(ss, start, count);
+ std::string tmp = ss.str();
+ mg_printf_http_chunk(nc, "%s", tmp.c_str());
+ mg_send_http_chunk(nc, "", 0);
+}
+
+static int has_prefix(const struct mg_str *uri, const struct mg_str *prefix) {
+ return uri->len > prefix->len && memcmp(uri->p, prefix->p, prefix->len) == 0;
+}
+
+static int is_equal(const struct mg_str *s1, const struct mg_str *s2) {
+ return s1->len == s2->len && memcmp(s1->p, s2->p, s2->len) == 0;
+}
+
+static struct mg_serve_http_opts http_server_options;
+static const struct mg_str api_prefix = MG_MK_STR("/api/v1");
+
+static void ev_handler(struct mg_connection *nc, int ev, void *ev_data) {
+
+ http_message *hm = (struct http_message *)ev_data;
+
+ switch(ev) {
+ case MG_EV_WEBSOCKET_HANDSHAKE_DONE: {
+ printf("DEBUG: Event MG_EV_WEBSOCKET_HANDSHAKE_DONE.\n");
+ const char* s = "Bingo boingo.";
+ mg_send_websocket_frame(nc, WEBSOCKET_OP_TEXT, s, strlen(s));
+ } break;
+ case MG_EV_WEBSOCKET_FRAME: {
+ printf("DEBUG: Event MG_EV_WEBSOCKET_FRAME.\n");
+ } break;
+ case MG_EV_CONNECT: {
+ printf("DEBUG: Event MG_EV_CONNECT.\n");
+ } break;
+ // case MG_EV_RECV: {
+ // printf("DEBUG: Event MG_EV_RECV.\n");
+ // } break;
+ // case MG_EV_SEND: {
+ // printf("DEBUG: Event MG_EV_SEND.\n");
+ // } break;
+ case MG_EV_CLOSE: {
+ printf("DEBUG: Event MG_EV_CLOSE.\n");
+ } break;
+ // case MG_EV_POLL: {
+ // printf("DEBUG: Event MG_EV_POLL.\n");
+ // } break;
+ case MG_EV_HTTP_REQUEST: {
+ printf("DEBUG: Event MG_EV_HTTP_REQUEST.\n");
+ char * s = strndup(hm->uri.p, hm->uri.len);
+ printf("DEBUG: URI = \"%s\"\n", s);
+ free(s);
+ if (has_prefix(&hm->uri, &api_prefix)) {
+ struct mg_str key;
+ key.p = hm->uri.p + api_prefix.len;
+ key.len = hm->uri.len - api_prefix.len;
+
+ if (is_equal(&hm->method, &s_get_method)) {
+ printf("DEBUG: HTTP GET method.\n");
+ if (mg_vcmp(&key, "/vs_connections") == 0) {
+ handle_vs_connections_call(nc, hm);
+ } else if (mg_vcmp(&key, "/alloc_info") == 0) {
+ handle_alloc_info_call(nc, hm);
+ }
+ } else if (is_equal(&hm->method, &s_put_method)) {
+ printf("DEBUG: HTTP PUT method.\n");
+ } else if (is_equal(&hm->method, &s_delele_method)) {
+ printf("DEBUG: HTTP DELETE method.\n");
+ }
+ } else {
+ mg_serve_http(nc, (struct http_message *) ev_data, http_server_options);
+ }
+ } break;
+ default: {
+ } break;
+ }
+}
+
+void* service_connections (void* arg) {
+ HTTP_Server *S = (HTTP_Server*)arg;
+ while(!S->shutting_down) {
+ mg_mgr_poll(&S->mgr, 1000);
+ }
+ return NULL;
+}
+
+int http_default_data(HTTP_Server *S) {
+ S->port = "8888";
+ S->shutting_down = false;
+ return 0;
+}
+
+int http_init(HTTP_Server *S) {
+ http_server_options.document_root = "www";
+ http_server_options.enable_directory_listing = "yes";
+ mg_mgr_init(&S->mgr, NULL);
+ printf("Starting web server on port %s\n", S->port);
+ S->nc = mg_bind(&S->mgr, S->port, ev_handler);
+ if (S->nc == NULL) {
+ printf("Failed to create listener.\n");
+ return 1;
+ }
+ mg_set_protocol_http_websocket(S->nc);
+ pthread_create( &S->server_thread, NULL, service_connections, (void*)S);
+ return 0;
+}
+
+int http_shutdown(HTTP_Server *S) {
+ printf("Shutting down web server on port %s\n", S->port);
+ S->shutting_down = true;
+ pthread_join(S->server_thread, NULL);
+ return 0;
+}