From 06c81dd08d272583a0427c80a7cda900e05ca1b3 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 10 Jun 2017 14:18:09 +1000 Subject: [PATCH 001/124] Makefile: correct mavlink generation --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6764fbf..e9c0c95 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ all: files/embedded.c mavlink web_server mavlink: generated/mavlink/ardupilotmega/mavlink.h generated/mavlink/ardupilotmega/mavlink.h: - mavgen.py --lang C ../mavlink/message_definitions/v1.0/ardupilotmega.xml -o generated/mavlink --wire-protocol=2.0 + mavgen.py --lang C modules/mavlink/message_definitions/v1.0/ardupilotmega.xml -o generated/mavlink --wire-protocol=2.0 web_server: $(OBJ) files/embedded.c $(CC) -o web_server $(OBJ) $(LIBS) From c92697c30e4c19b3c0e45192558d370dc54a17d2 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 10 Jun 2017 14:22:10 +1000 Subject: [PATCH 002/124] main: make serial port, broadcast and http port optional --- web_server.c | 115 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 68 insertions(+), 47 deletions(-) diff --git a/web_server.c b/web_server.c index 48e67a8..32b0bd2 100644 --- a/web_server.c +++ b/web_server.c @@ -14,7 +14,11 @@ static pthread_mutex_t lock; static int num_sockets_open; static int debug_level; -static int mavlink_fd; +static int serial_port_fd = -1; + +#ifndef bool +#define bool int +#endif void web_server_set_debug(int level) { @@ -144,7 +148,9 @@ void connection_destroy(struct connection_state *c) */ void mavlink_fc_write(const uint8_t *buf, size_t size) { - write(mavlink_fd, buf, size); + if (serial_port_fd != -1) { + write(serial_port_fd, buf, size); + } } /* @@ -152,7 +158,7 @@ void mavlink_fc_write(const uint8_t *buf, size_t size) */ void mavlink_fc_send(mavlink_message_t *msg) { - _mavlink_resend_uart(MAVLINK_COMM_FC, msg); + _mavlink_resend_uart(MAVLINK_COMM_FC, msg); } /* @@ -224,26 +230,33 @@ static void *web_server_connection_process(void *arg) /* main select loop */ -static void select_loop(int tcp_socket, int udp_socket, int mavlink_fd) +static void select_loop(int http_socket_fd, int udp_socket_fd) { while (1) { fd_set fds; struct timeval tv; - int numfd = tcp_socket+1; + int numfd = 0; FD_ZERO(&fds); - FD_SET(tcp_socket, &fds); - FD_SET(udp_socket, &fds); - FD_SET(mavlink_fd, &fds); - - if (udp_socket >= numfd) { - numfd = udp_socket+1; + if (http_socket_fd != -1) { + FD_SET(http_socket_fd, &fds); + if (http_socket_fd >= numfd) { + numfd = http_socket_fd+1; + } } - if (mavlink_fd >= numfd) { - numfd = mavlink_fd+1; + if (udp_socket_fd != -1) { + FD_SET(udp_socket_fd, &fds); + if (udp_socket_fd >= numfd) { + numfd = udp_socket_fd+1; + } } - - + if (serial_port_fd != -1) { + FD_SET(serial_port_fd, &fds); + if (serial_port_fd >= numfd) { + numfd = serial_port_fd+1; + } + } + tv.tv_sec = 1; tv.tv_usec = 0; @@ -253,8 +266,8 @@ static void select_loop(int tcp_socket, int udp_socket, int mavlink_fd) } // check for new incoming tcp connection - if (FD_ISSET(tcp_socket, &fds)) { - int fd = accept(tcp_socket, NULL,0); + if (FD_ISSET(http_socket_fd, &fds)) { + int fd = accept(http_socket_fd, NULL,0); if (fd == -1) continue; // use a thread per connection. This allows for sending MAVLink messages @@ -269,20 +282,21 @@ static void select_loop(int tcp_socket, int udp_socket, int mavlink_fd) } // check for incoming UDP packet - if (FD_ISSET(udp_socket, &fds)) { + if (FD_ISSET(udp_socket_fd, &fds)) { // we have data pending uint8_t buf[300]; - ssize_t nread = read(udp_socket, buf, sizeof(buf)); + ssize_t nread = read(udp_socket_fd, buf, sizeof(buf)); if (nread > 0) { // send the data straight to the flight controller - write(mavlink_fd, buf, nread); + write(serial_port_fd, buf, nread); } } // check for incoming bytes from flight controller - if (FD_ISSET(mavlink_fd, &fds)) { + if (serial_port_fd != -1 || + FD_ISSET(serial_port_fd, &fds)) { uint8_t buf[200]; - ssize_t nread = read(mavlink_fd, buf, sizeof(buf)); + ssize_t nread = read(serial_port_fd, buf, sizeof(buf)); if (nread <= 0) { printf("Read error from flight controller\n"); // we should re-open serial port @@ -294,7 +308,7 @@ static void select_loop(int tcp_socket, int udp_socket, int mavlink_fd) if (mavlink_parse_char(MAVLINK_COMM_FC, buf[i], &msg, &status)) { if (!mavlink_handle_msg(&msg)) { // forward to network connection as a udp broadcast packet - mavlink_broadcast(udp_socket, &msg); + mavlink_broadcast(udp_socket_fd, &msg); } } } @@ -396,17 +410,18 @@ static int udp_open(void) /* main program, start listening and answering queries */ int main(int argc, char *argv[]) { - int port = 80; + int http_port = -1; extern char *optarg; int opt; const char *serial_port = NULL; unsigned baudrate = 57600; - const char *usage = "Usage: web_server -p port -b baudrate -s serial_port -d debug_level"; - - while ((opt=getopt(argc, argv, "p:s:b:hd:")) != -1) { + const char *usage = "Usage: web_server -p http_port -b baudrate -s serial_port -d debug_level -u"; + bool do_udp_broadcast = 0; + + while ((opt=getopt(argc, argv, "p:s:b:hd:u")) != -1) { switch (opt) { case 'p': - port = atoi(optarg); + http_port = atoi(optarg); break; case 's': serial_port = optarg; @@ -417,6 +432,9 @@ int main(int argc, char *argv[]) case 'd': web_server_set_debug(atoi(optarg)); break; + case 'u': + do_udp_broadcast = 1; + break; case 'h': default: printf("%s\n", usage); @@ -427,31 +445,34 @@ int main(int argc, char *argv[]) pthread_mutex_init(&lock, NULL); - if (!serial_port) { - printf("You must supply a serial port with the -s option\n"); - exit(1); + if (serial_port) { + serial_port_fd = mavlink_serial_open(serial_port, baudrate); + if (serial_port_fd == -1) { + printf("Failed to open mavlink serial port %s\n", serial_port); + exit(1); + } } - mavlink_fd = mavlink_serial_open(serial_port, baudrate); - if (mavlink_fd == -1) { - printf("Failed to open mavlink serial port %s\n", serial_port); - exit(1); + int udp_socket_fd = -1; + if (do_udp_broadcast) { + udp_socket_fd = udp_open(); + if (udp_socket_fd == -1) { + printf("Failed to open UDP socket\n"); + exit(1); + } } - int udp_socket = udp_open(); - if (udp_socket == -1) { - printf("Failed to open UDP socket\n"); - exit(1); + int http_socket_fd = -1; + if (http_port != -1) { + http_socket_fd = tcp_open(http_port); + if (http_socket_fd == -1) { + printf("Failed to open TCP socket\n"); + exit(1); + } } - int tcp_socket = tcp_open(port); - if (tcp_socket == -1) { - printf("Failed to open TCP socket\n"); - exit(1); - } - - select_loop(tcp_socket, udp_socket, mavlink_fd); - + select_loop(http_socket_fd, udp_socket_fd); + return 0; } From 16cdbb8875a2daf500e35ea67cf9f48d1849f99f Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 10 Jun 2017 14:23:18 +1000 Subject: [PATCH 003/124] main: option to receive fc data via UDP rather than serial --- web_server.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 97 insertions(+), 6 deletions(-) diff --git a/web_server.c b/web_server.c index 32b0bd2..d05fd7a 100644 --- a/web_server.c +++ b/web_server.c @@ -15,6 +15,10 @@ static pthread_mutex_t lock; static int num_sockets_open; static int debug_level; static int serial_port_fd = -1; +static int fc_udp_in_fd = -1; + +struct sockaddr_in fc_addr; +socklen_t fc_addrlen; #ifndef bool #define bool int @@ -151,6 +155,11 @@ void mavlink_fc_write(const uint8_t *buf, size_t size) if (serial_port_fd != -1) { write(serial_port_fd, buf, size); } + if (fc_udp_in_fd != -1) { + if (fc_addrlen != 0) { + sendto(fc_udp_in_fd, buf, size, 0, (struct sockaddr*)&fc_addr, fc_addrlen); + } + } } /* @@ -158,7 +167,14 @@ void mavlink_fc_write(const uint8_t *buf, size_t size) */ void mavlink_fc_send(mavlink_message_t *msg) { - _mavlink_resend_uart(MAVLINK_COMM_FC, msg); + if (serial_port_fd != -1) { + _mavlink_resend_uart(MAVLINK_COMM_FC, msg); + } + if (fc_udp_in_fd != -1) { + uint8_t buf[600]; + uint16_t len = mavlink_msg_to_send_buffer(buf, msg); + mavlink_fc_write(buf, len); + } } /* @@ -257,6 +273,13 @@ static void select_loop(int http_socket_fd, int udp_socket_fd) } } + if (fc_udp_in_fd != -1) { + FD_SET(fc_udp_in_fd, &fds); + if (fc_udp_in_fd >= numfd) { + numfd = fc_udp_in_fd+1; + } + } + tv.tv_sec = 1; tv.tv_usec = 0; @@ -281,14 +304,35 @@ static void select_loop(int http_socket_fd, int udp_socket_fd) pthread_attr_destroy(&thread_attr); } - // check for incoming UDP packet + // check for incoming UDP packet (broadcast) if (FD_ISSET(udp_socket_fd, &fds)) { // we have data pending uint8_t buf[300]; ssize_t nread = read(udp_socket_fd, buf, sizeof(buf)); if (nread > 0) { // send the data straight to the flight controller - write(serial_port_fd, buf, nread); + mavlink_fc_write(buf, nread); + } + } + + if (FD_ISSET(fc_udp_in_fd, &fds) || true) { + // we have data pending + uint8_t buf[3000]; + fc_addrlen = sizeof(fc_addr); + ssize_t nread = recvfrom(fc_udp_in_fd, buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr*)&fc_addr, &fc_addrlen); + if (nread <= 0) { + /* printf("Read error from flight controller\n"); */ + } else { + mavlink_message_t msg; + mavlink_status_t status; + for (uint16_t i=0; i Date: Sun, 11 Jun 2017 10:10:04 +1000 Subject: [PATCH 004/124] OSX compatability. osx defines the reboot function as int reboot(int) which is incompatible with the void reboot(void) used here, so I rename the local one to __reboot --- functions.c | 2 +- linux/util_linux.c | 9 +++++++-- linux/util_linux.h | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/functions.c b/functions.c index 421faf9..38e05f5 100644 --- a/functions.c +++ b/functions.c @@ -320,7 +320,7 @@ static void mavlink_message_send(struct template_state *tmpl, const char *name, static void reboot_companion(struct template_state *tmpl, const char *name, const char *value, int argc, char **argv) { console_printf("rebooting ...\n"); - reboot(); + __reboot(); } extern void snx_nvram_bootup_upgrade(void); diff --git a/linux/util_linux.c b/linux/util_linux.c index 1f3bc87..4f3e4b1 100644 --- a/linux/util_linux.c +++ b/linux/util_linux.c @@ -65,9 +65,14 @@ bool toggle_recording(void) return false; } -void reboot(void) +void __reboot(void) { - printf("reboot not implemented\n"); + #if __APPLE__ + printf("reboot OSX implemented, but disabled for now.\n"); + //reboot(0); + #else + printf("reboot not implemented\n"); + #endif } diff --git a/linux/util_linux.h b/linux/util_linux.h index ed656e6..35577d1 100644 --- a/linux/util_linux.h +++ b/linux/util_linux.h @@ -20,8 +20,8 @@ uint32_t get_time_boot_ms(); void mdelay(uint32_t ms); bool toggle_recording(void); -void reboot(void); +void __reboot(void); // __ so we don't call the os version of this by mistake. char *print_vprintf(void *ctx, const char *fmt, va_list ap); void *print_printf(void *ctx, const char *fmt, ...); From 2ba008b3069d605534a2d2e40dc9308c0616e393 Mon Sep 17 00:00:00 2001 From: Samuel Dudley Date: Mon, 12 Jun 2017 12:29:59 +0930 Subject: [PATCH 005/124] Readme - added requirement note Added a requirement note for building on Ubuntu 16.04 --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index a11caed..ff130cc 100644 --- a/README.md +++ b/README.md @@ -16,3 +16,8 @@ Some information on the JSON protocol used is here: https://docs.google.com/document/d/12IQFXDRIif06BiriHSCGdiJGZ6zsQ_phQsG_iI6_MAo/edit?usp=sharing + #### Build Notes + _Ubuntu 16.04_ + - libtalloc-dev is required to build this project. You can install the required package with the following command: `sudo apt-get install libtalloc-dev` + + From 52c5a85a5b2ca2c4af39383befcf6eab2b428287 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 21 Jun 2017 17:23:43 +1000 Subject: [PATCH 006/124] Create http threads in detached state --- web_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_server.c b/web_server.c index d05fd7a..f39bf84 100644 --- a/web_server.c +++ b/web_server.c @@ -299,7 +299,7 @@ static void select_loop(int http_socket_fd, int udp_socket_fd) pthread_attr_t thread_attr; pthread_attr_init(&thread_attr); - pthread_attr_setdetachstate(&thread_attr, 0); + pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); pthread_create(&thread_id, &thread_attr, web_server_connection_process, (void*)(intptr_t)fd); pthread_attr_destroy(&thread_attr); } From 58f1545ca7531cdd5cf3f35f40fe4e813630f22f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 27 Oct 2017 17:00:45 +1100 Subject: [PATCH 007/124] fixed select logic --- web_server.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/web_server.c b/web_server.c index f39bf84..d911d00 100644 --- a/web_server.c +++ b/web_server.c @@ -289,7 +289,8 @@ static void select_loop(int http_socket_fd, int udp_socket_fd) } // check for new incoming tcp connection - if (FD_ISSET(http_socket_fd, &fds)) { + if (http_socket_fd != -1 && + FD_ISSET(http_socket_fd, &fds)) { int fd = accept(http_socket_fd, NULL,0); if (fd == -1) continue; @@ -305,7 +306,8 @@ static void select_loop(int http_socket_fd, int udp_socket_fd) } // check for incoming UDP packet (broadcast) - if (FD_ISSET(udp_socket_fd, &fds)) { + if (udp_socket_fd != -1 && + FD_ISSET(udp_socket_fd, &fds)) { // we have data pending uint8_t buf[300]; ssize_t nread = read(udp_socket_fd, buf, sizeof(buf)); @@ -315,14 +317,13 @@ static void select_loop(int http_socket_fd, int udp_socket_fd) } } - if (FD_ISSET(fc_udp_in_fd, &fds) || true) { + if (fc_udp_in_fd != -1 && + FD_ISSET(fc_udp_in_fd, &fds)) { // we have data pending uint8_t buf[3000]; fc_addrlen = sizeof(fc_addr); ssize_t nread = recvfrom(fc_udp_in_fd, buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr*)&fc_addr, &fc_addrlen); - if (nread <= 0) { - /* printf("Read error from flight controller\n"); */ - } else { + if (nread > 0) { mavlink_message_t msg; mavlink_status_t status; for (uint16_t i=0; i Date: Fri, 27 Oct 2017 12:38:48 +1100 Subject: [PATCH 008/124] Add origin checking prevent attacks by malicious javascript on public web pages Originally authored by tridge --- cgi.c | 6 ++++ cgi.h | 2 ++ web_server.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+) diff --git a/cgi.c b/cgi.c index 32bd876..7798476 100644 --- a/cgi.c +++ b/cgi.c @@ -649,6 +649,12 @@ static bool setup_standalone(struct cgi_state *cgi) cgi->content_length = atoi(&line[16]); } else if (strncasecmp(line,"Content-Type: ", 14)==0) { cgi->content_type = talloc_strdup(cgi, &line[14]); + } else if (strncasecmp(line,"Origin: ", 8)==0) { + cgi->origin = talloc_strdup(cgi, &line[8]); + if (cgi->check_origin != NULL && !cgi->check_origin(cgi->origin)) { + cgi->http_error(cgi, "400 Bad Origin", "", + "request with incorrect origin header"); + } } /* ignore all other requests! */ } diff --git a/cgi.h b/cgi.h index 72f991c..19c3bf6 100644 --- a/cgi.h +++ b/cgi.h @@ -41,10 +41,12 @@ struct cgi_state { const char *err, const char *header, const char *info); void (*download)(struct cgi_state *cgi, const char *path); void (*put)(struct cgi_state *cgi, const char *name, const char *value); + bool (*check_origin)(const char *origin); /* data */ struct cgi_var *variables; struct template_state *tmpl; + const char *origin; char *content_type; unsigned long content_length; int request_post; diff --git a/web_server.c b/web_server.c index d911d00..54b877d 100644 --- a/web_server.c +++ b/web_server.c @@ -17,6 +17,9 @@ static int debug_level; static int serial_port_fd = -1; static int fc_udp_in_fd = -1; +// public web-site that will be allowed. Can be edited with NVRAM editor +static const char *public_origin = "fly.example.com"; + struct sockaddr_in fc_addr; socklen_t fc_addrlen; @@ -212,6 +215,75 @@ static void connection_process(struct connection_state *c) connection_destroy(c); } +/* + check origin header to prevent attacks by javascript in other web pages + */ +static bool check_origin(const char *origin) +{ + if (strcmp(origin, "http://192.168.99.1") == 0) { + // always accept + return true; + } + // also allow file:// URLs which produce a 'null' origin + if (strcmp(origin, "null") == 0) { + return true; + } + char *allowed_origin; +#ifdef SYSTEM_FREERTOS + unsigned origin_length = 0; + if (snx_nvram_get_data_len("SkyViper", "AllowedOrigin", &origin_length) != NVRAM_SUCCESS) { + return false; + } + allowed_origin = talloc_zero_size(NULL, origin_length); + if (allowed_origin == NULL) { + return false; + } + if (snx_nvram_string_get("SkyViper", "AllowedOrigin", allowed_origin) != NVRAM_SUCCESS) { + talloc_free(allowed_origin); + return false; + } +#else + allowed_origin = talloc_zero_size(NULL, 1); +#endif + // check for wildcard allowed origin + if (strcmp(allowed_origin, "*") == 0) { + talloc_free(allowed_origin); + return true; + } + + // allow for http:// or https:// + if (strncmp(origin, "http://", 7) == 0) { + origin += 7; + } else if (strncmp(origin, "https://", 8) == 0) { + origin += 8; + } else { + console_printf("Denied origin protocol: [%s]\n", origin); + talloc_free(allowed_origin); + return false; + } + + if (strcmp(allowed_origin, origin) != 0) { + console_printf("Denied origin: [%s] allowed: [%s]\n", origin, allowed_origin); + talloc_free(allowed_origin); + return false; + } + talloc_free(allowed_origin); + return true; +} + +/* + setup AllowedOrigin if not set already + */ +static void setup_origin(const char *origin) +{ +#ifdef SYSTEM_FREERTOS + unsigned origin_length = 0; + if (snx_nvram_get_data_len("SkyViper", "AllowedOrigin", &origin_length) != NVRAM_SUCCESS || + origin_length == 0) { + snx_nvram_string_set("SkyViper", "AllowedOrigin", __DECONST(char *,origin)); + } +#endif +} /* task for web_server @@ -239,6 +311,8 @@ static void *web_server_connection_process(void *arg) return NULL; } + c->cgi->check_origin = check_origin; + connection_process(c); return NULL; } @@ -493,6 +567,9 @@ int main(int argc, char *argv[]) bool do_udp_broadcast = 0; int fc_udp_in_port = -1; + // setup default allowed origin + setup_origin(public_origin); + while ((opt=getopt(argc, argv, "p:s:b:hd:uf:")) != -1) { switch (opt) { case 'p': From e1075bd1bd2f2f2bb3c81b45261c4bec03bed236 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 12:47:05 +1100 Subject: [PATCH 009/124] Add avi mime type Originally authored by tridge --- cgi.c | 1 + cgi.h | 1 + 2 files changed, 2 insertions(+) diff --git a/cgi.c b/cgi.c index 7798476..9d3b079 100644 --- a/cgi.c +++ b/cgi.c @@ -430,6 +430,7 @@ static const struct mime_type { {".txt", "text/plain", MIME_TYPE_TEXT_PLAIN}, {".html", "text/html;charset=UTF-8", MIME_TYPE_TEXT_HTML}, {".mp4", "video/mp4", MIME_TYPE_VIDEO_MP4}, + {".avi", "video/avi", MIME_TYPE_VIDEO_AVI}, {".bin", "data", MIME_TYPE_UNKNOWN}, {".svg", "image/svg+xml", MIME_TYPE_IMAGE_SVG}, {".js", "application/javascript", MIME_TYPE_JAVASCRIPT}, diff --git a/cgi.h b/cgi.h index 19c3bf6..43793f3 100644 --- a/cgi.h +++ b/cgi.h @@ -67,6 +67,7 @@ enum CGI_MIME_TYPE {MIME_TYPE_IMAGE_GIF, MIME_TYPE_TEXT_PLAIN, MIME_TYPE_TEXT_HTML, MIME_TYPE_VIDEO_MP4, + MIME_TYPE_VIDEO_AVI, MIME_TYPE_JAVASCRIPT, MIME_TYPE_JSON, MIME_TYPE_CSS, From f2b011be84828d7290a0b261894732b3240508fc Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 12:54:47 +1100 Subject: [PATCH 010/124] fixed multiple charts for same variable Originally authored by tridge --- files/js/charts.js | 9 ++++++--- files/js/mavlink.js | 4 +++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/files/js/charts.js b/files/js/charts.js index bd6057f..010adb0 100644 --- a/files/js/charts.js +++ b/files/js/charts.js @@ -15,9 +15,12 @@ function create_chart(canvass_name, variables) { yRangeFunction : chart_range }; charts[canvass_name] = new SmoothieChart(settings); for (var i=0; i Date: Fri, 27 Oct 2017 12:58:07 +1100 Subject: [PATCH 011/124] mavlink_statustext for logging Originally authored by tridge --- files/js/mavlink.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/files/js/mavlink.js b/files/js/mavlink.js index 1c611aa..247ad18 100644 --- a/files/js/mavlink.js +++ b/files/js/mavlink.js @@ -10,6 +10,15 @@ var MAV_CMD_PREFLIGHT_CALIBRATION = 241; var MAV_CMD_ACCELCAL_VEHICLE_POS = 42429; var MAV_CMD_DO_START_MAG_CAL = 42424; +var MAV_SEVERITY_EMERGENCY = 0; +var MAV_SEVERITY_ALERT = 1; +var MAV_SEVERITY_CRITICAL = 2; +var MAV_SEVERITY_ERROR = 3; +var MAV_SEVERITY_WARNING = 4; +var MAV_SEVERITY_NOTICE = 5; +var MAV_SEVERITY_INFO = 6; +var MAV_SEVERITY_DEBUG = 7; + // scaling and numdigits table for variables, by regular expression const scaling = { 'RAW_IMU:.acc' : [9.81 * 0.001, 3], 'GPS_RAW_INT:l..' : [1.0e-7, 7], @@ -240,6 +249,15 @@ function mavlink_command_long_send() { } +/* + send a STATUSTEXT for logging +*/ +function mavlink_statustext(severity, text) { + var mavcmd = "mavlink_message_send(STATUSTEXT," + severity + "," + text + ")"; + command_send(mavcmd); +} + + /* send a mavlink command long with a callback giving the result code */ From a16d25f9ed71f794c62df53ed7eab97c2d20088f Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 12:59:48 +1100 Subject: [PATCH 012/124] return true if exception from JSON Originally by tridge --- files/js/mavlink.js | 1 + 1 file changed, 1 insertion(+) diff --git a/files/js/mavlink.js b/files/js/mavlink.js index 247ad18..c7b23f7 100644 --- a/files/js/mavlink.js +++ b/files/js/mavlink.js @@ -330,6 +330,7 @@ function ajax_json_poll(url, callback, refresh_ms=1000) { var json = JSON.parse(responseText); return callback(json); } catch(e) { + return true; } /* on bad json keep going */ return true; From ba735ee687a1a8d0019ccffc43c17442712c4d75 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 13:06:33 +1100 Subject: [PATCH 013/124] mavlink.js: send set_time_utc every 20 seconds Originally authored by tridge --- files/js/mavlink.js | 19 ++++++++++++++----- files/js/ublox.js | 3 --- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/files/js/mavlink.js b/files/js/mavlink.js index c7b23f7..a15190f 100644 --- a/files/js/mavlink.js +++ b/files/js/mavlink.js @@ -372,18 +372,27 @@ function set_message_color(id, color, message) { } } +/* + get utc time in seconds +*/ +function get_utc_sec() { + var d = new Date(); + var dsec = d.getTime() / 1000; + return dsec; +} + /* set the date on the sonix board */ function set_sonix_date() { var d = new Date(); - var dsec = d.getTime() / 1000; + var dsec = get_utc_sec(); var tz_offset = -d.getTimezoneOffset() * 60; d = (dsec+0.5).toFixed(0); - command_send("set_time_utc(" + d + "," + tz_offset + ")"); + var cmd = "set_time_utc(" + d + "," + tz_offset + ")"; + command_send(cmd); } -/* always set the date at connection time */ -set_sonix_date(); - +// set date every 20s +setInterval(set_sonix_date(), 20000); diff --git a/files/js/ublox.js b/files/js/ublox.js index 23fc148..8a179b0 100644 --- a/files/js/ublox.js +++ b/files/js/ublox.js @@ -50,9 +50,6 @@ function set_mga_data(data) { sent_last_pos = true; } - /* send the date again */ - set_sonix_date(); - var xhr = createCORSRequest("POST", drone_url + "/ajax/command.json"); xhr.send(formData); setTimeout(poll_ublox_status, mga_poll_period); From efa44f791f0535cbeba9187d70e09172de7060d7 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 13:08:27 +1100 Subject: [PATCH 014/124] mavlink.js: function to append a colourful message to an element-by-id Originally authored by tridge --- files/js/mavlink.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/files/js/mavlink.js b/files/js/mavlink.js index a15190f..99090d9 100644 --- a/files/js/mavlink.js +++ b/files/js/mavlink.js @@ -372,6 +372,17 @@ function set_message_color(id, color, message) { } } +/* + append a message in a div by id, with given color +*/ +function append_message_color(id, color, message) { + var element = document.getElementById(id); + if (element) { + element.innerHTML += '
' + message + ''; + } + mavlink_statustext(MAV_SEVERITY_INFO, message); +} + /* get utc time in seconds */ From 5471230762c8cad0ac25fcb28cb7f14c3b960355 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 13:12:04 +1100 Subject: [PATCH 015/124] mavlink.js: canonicalise whitespace in JSON before parsing Originally authored by tridge --- files/js/mavlink.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/files/js/mavlink.js b/files/js/mavlink.js index 99090d9..5e0997f 100644 --- a/files/js/mavlink.js +++ b/files/js/mavlink.js @@ -91,8 +91,10 @@ function fill_mavlink_ids(options={}) { xhr.onload = function() { again(); var mavlink; + var text = xhr.responseText; + text = text.replace(/(\r\n|\n|\r)/gm," "); try { - mavlink = JSON.parse(xhr.responseText); + mavlink = JSON.parse(text); } catch(e) { console.log(e); return; From a95946302da6de1f8cf7263d8839c1e77497eea7 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 13:27:16 +1100 Subject: [PATCH 016/124] ublox.js: reduce ublox refresh from 7 to 2 days Also use get_utc_sec function. Originally authored by tridge --- files/js/ublox.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/files/js/ublox.js b/files/js/ublox.js index 8a179b0..433f6f4 100644 --- a/files/js/ublox.js +++ b/files/js/ublox.js @@ -15,7 +15,7 @@ function set_last_pos(pos) { handle downloaded MGA data */ function handle_mga_data(data) { - var utc_sec = new Date().getTime() / 1000; + var utc_sec = get_utc_sec(); var new_data = { timestamp : utc_sec, data : data }; db_store("mga_data", new_data); set_mga_data(new_data); @@ -34,8 +34,10 @@ function download_mga_data() { */ function set_mga_data(data) { console.log("mga_data length " + data.data.byteLength); - var utc_sec = new Date().getTime() / 1000; - if (data.timestamp > utc_sec + 60*60*24*7) { + var utc_sec = get_utc_sec(); + var age_days = (utc_sec - data.timestamp) / (60*60*24); + console.log("mga data age: " + age_days); + if (age_days > 2) { download_mga_data(); } var formData = new FormData(); @@ -64,7 +66,7 @@ function check_mga_status(json) { return; } page_fill_json_html(mga_status); - var utc_sec = new Date().getTime() / 1000; + var utc_sec = get_utc_sec(); if (mga_status.offline_cache_size > 0 && (last_pos == null || sent_last_pos)) { // its all up to date, don't send it the data From b628527d9e2e5a7d8bf0e1e4f2a2f52167eaf9dd Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 13:53:17 +1100 Subject: [PATCH 017/124] files/calibration.html: remove bad element id Originally authored by tridge --- files/calibration.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/calibration.html b/files/calibration.html index e89db1f..7ee0a4f 100644 --- a/files/calibration.html +++ b/files/calibration.html @@ -19,7 +19,7 @@
- +
From 5dacb61239fa02dd0140310ded50e7c3eaf912df Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 13:57:14 +1100 Subject: [PATCH 018/124] files/calibration.html: clarify reboot-after-calibrate comment Originally authored by tridge --- files/calibration.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/files/calibration.html b/files/calibration.html index 7ee0a4f..6cee849 100644 --- a/files/calibration.html +++ b/files/calibration.html @@ -50,7 +50,7 @@

Six-Axis Accelerometer Calibration

flying, or if you find that you get poor results with a simple accelerometer calibration. -

After a six-axis calibration you will need to power cycle your vehicle +

After a six-axis calibration you will need to power cycle your vehicle before you can fly.

@@ -111,7 +111,7 @@

Magnetometer calibration

A progress bar will display to show how far you are through the calibration. -

After a magnetometer calibration you will need to power cycle your vehicle +

After a magnetometer calibration you will need to power cycle your vehicle before you can fly.

From 49e671783cbd2d5416e6bb2a08f63b5732d60ba7 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 13:59:50 +1100 Subject: [PATCH 019/124] files/calibration.html: make mag canvas larger Originally authored by tridge --- files/calibration.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/calibration.html b/files/calibration.html index 6cee849..94fde8a 100644 --- a/files/calibration.html +++ b/files/calibration.html @@ -151,7 +151,7 @@

Sensor State

Magnetometer (X, Y, Z)
-

+

From fdf9943ce8d2f0c7fe1d263d29b6836c78c37374 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 14:00:32 +1100 Subject: [PATCH 020/124] files/calibration.html: include mag offsets in status Originally authored by tridge --- files/calibration.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/files/calibration.html b/files/calibration.html index 94fde8a..9ed0edc 100644 --- a/files/calibration.html +++ b/files/calibration.html @@ -146,6 +146,11 @@

Sensor State

+ Offsets +
+
+
+ From 4c0d6b1a2ea419bbbce252008068e3cb5161fdc1 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 14:06:41 +1100 Subject: [PATCH 021/124] files/calibration.html: ensure color is always set Originally authored by tridge --- files/calibration.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/files/calibration.html b/files/calibration.html index 9ed0edc..bd4c2b1 100644 --- a/files/calibration.html +++ b/files/calibration.html @@ -194,12 +194,12 @@

Sensor State

} function simple_accel_cal_callback(result) { + var color = "red"; if (result == 0) { result = "calibration successful"; color = "green"; } else { result = "calibration failed: " + result; - color = "red"; } set_message_color("simple_accel_message", color, result); } @@ -220,6 +220,7 @@

Sensor State

function six_axis_accel_cal_callback(result) { six_axis_running = false; + var color = "red"; if (result == 0) { // wait for level six_axis_stage = 1; @@ -228,7 +229,6 @@

Sensor State

color = "blue"; } else { result = "calibration failed: " + result; - color = "red"; document.getElementById("continue_div").style.display = "none"; } set_message_color("six_axis_accel_message", color, result); @@ -243,6 +243,7 @@

Sensor State

} function mag_cal_callback(result) { + var color = "red"; if (result == 0) { // wait for level six_axis_stage = 1; @@ -252,7 +253,6 @@

Sensor State

mag_completion_pct = -1; } else { result = "calibration failed: " + result; - color = "red"; document.getElementById("mag_div").style.display = "none"; } set_message_color("mag_message", color, result); From 2dd930b14cb2dd59f739d442a9be973e833af247 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 14:10:29 +1100 Subject: [PATCH 022/124] files/calibration.html: correct fill of calibration parms Originally authored by tridge --- files/calibration.html | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/files/calibration.html b/files/calibration.html index bd4c2b1..6fe1f2d 100644 --- a/files/calibration.html +++ b/files/calibration.html @@ -270,9 +270,15 @@

Sensor State

var name = plist[i].name; var value = plist[i].value; var element = document.getElementById(name); + params[name] = value; if (element != null) { - element.innerHTML = value; - params[name] = value; + element.innerHTML = value.toFixed(1); + } + var elements = document.getElementsByName(name); + if (elements != null) { + for (var j=0; j Date: Fri, 27 Oct 2017 14:13:58 +1100 Subject: [PATCH 023/124] files/filesystem.html: present file count in interface Originally authored by tridge --- files/filesystem.html | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/files/filesystem.html b/files/filesystem.html index fb8809b..bb9193f 100644 --- a/files/filesystem.html +++ b/files/filesystem.html @@ -21,7 +21,7 @@

Index of /

-

Directory size: MByte
+

Directory size: MByte in files
Card Size:  GByte
Card Free:  GByte
Card Label:
@@ -34,10 +34,13 @@

Index of /

From 049dbf2abe90e20bbf60d8a2b05b1b89b69d7843 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 14:15:09 +1100 Subject: [PATCH 025/124] files/filesystem.html: use 'Parent Directory' in place of '' Originally authored by tridge --- files/filesystem.html | 1 + 1 file changed, 1 insertion(+) diff --git a/files/filesystem.html b/files/filesystem.html index a2c08e5..1c43c26 100644 --- a/files/filesystem.html +++ b/files/filesystem.html @@ -88,6 +88,7 @@

Index of /

var link_name; if (v == "..") { link_name = dirname(current_directory); + v = "Parent Directory"; } else { link_name = dir_base + v; } From a2a6fb98eed98c44fed019b475909ec796ee2e14 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 14:18:03 +1100 Subject: [PATCH 026/124] files/nvram.html: correct refresh action Originally authored by tridge --- files/nvram.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/nvram.html b/files/nvram.html index e2a594e..adfbf06 100644 --- a/files/nvram.html +++ b/files/nvram.html @@ -23,7 +23,7 @@

Video Parameters

-

+

From 74560915bd3a11c019493103c96295af9444662f Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 14:21:04 +1100 Subject: [PATCH 027/124] files/parameters.html: fix search show/hide on refresh Originally authored by tridge --- files/parameters.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/files/parameters.html b/files/parameters.html index 88072a3..74e7383 100644 --- a/files/parameters.html +++ b/files/parameters.html @@ -68,7 +68,6 @@ function fill_parameters(json) { var table = document.getElementById("param_table"); - var search = document.getElementById("search").value.toUpperCase(); // delete any existing rows var nrows = table.rows.length; @@ -105,10 +104,10 @@ var c2 = row.insertCell(2); var c3 = row.insertCell(3); var c4 = row.insertCell(4); - show_hide(row, search); byname[rowdata.name] = rowdata.value; } fill_param_docs(); + search_change(); } function refresh() { From 580a440c97ea29c8407abcc93824b79dbd6752d5 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 14:22:48 +1100 Subject: [PATCH 028/124] files/parameters.html: added support for bitmasks in parameters Originally authored by tridge --- files/parameters.html | 76 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/files/parameters.html b/files/parameters.html index 74e7383..38be0d1 100644 --- a/files/parameters.html +++ b/files/parameters.html @@ -124,6 +124,26 @@ if (select != null) { select.value = value; } + set_bitoptions(name, value); + } + + function set_bitoptions(name, value) { + if (param_docs[name] == null || param_docs[name].bitoptions == null) { + return; + } + var bitoptions = param_docs[name].bitoptions; + var nbits = bitoptions.length; + for (var i=0; i' + opt.label + ''; + sel += selopt; + } + cell.innerHTML = sel; + set_bitoptions(name, value); + } + function fill_param_docs() { var table = document.getElementById("param_table"); var nrows = table.rows.length; @@ -185,9 +238,13 @@ if (pdoc) { tr.cells[3].innerHTML = pdoc.humanName; tr.cells[4].innerHTML = pdoc.documentation; + tr.cells[2].innerHTML = ''; if (pdoc.values != null) { fill_select_list(name, tr, pdoc.values); } + if (pdoc.bitoptions != null) { + fill_bitoptions(name, tr, pdoc.bitoptions); + } } } } @@ -218,9 +275,9 @@ nchildren = p.children.length; } for (var j=0; j Date: Fri, 27 Oct 2017 14:30:33 +1100 Subject: [PATCH 029/124] files/status.html: display STATUSTEXT on status page Originally authored by tridge --- files/status.html | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/files/status.html b/files/status.html index 153b0ba..8254f8b 100644 --- a/files/status.html +++ b/files/status.html @@ -27,6 +27,7 @@ +
@@ -326,6 +327,14 @@

Motor Testing

+
+ +
+ +

Flight Controller Messages

+ + +
Refresh rate:  @@ -367,8 +376,29 @@

Motor Testing

// setup default Tab document.getElementById("defaultTab").click(); -// callback for filling in buttons -function button_callback(mavlink) { +last_statustext_seq = -1; + +// callback for filling in mavlink fields +function mavlink_callback(mavlink) { + // pad dates with leading zeros + function two_pad(v) { + if (v >= 10) { + return v; + } + return "0" + v; + } + + if (mavlink.STATUSTEXT != null) { + if (mavlink.STATUSTEXT._seq != last_statustext_seq) { + last_statustext_seq = mavlink.STATUSTEXT._seq; + var d = new Date(); + d.setSeconds(d.getSeconds() - (mavlink.STATUSTEXT._age/1000)); + var tstring = two_pad(d.getHours()) + ":" + two_pad(d.getMinutes()) + ":" + two_pad(d.getSeconds()); + var text = tstring + " " + mavlink.STATUSTEXT.text + "\r\n"; + document.getElementById("STATUSTEXT").value += text; + } + } + // decode buttons from channel values if (mavlink.RC_CHANNELS == null) { return; @@ -393,7 +423,9 @@

Motor Testing

document.getElementById("power_button").innerHTML = pressed_str[power_button]; } -fill_mavlink_ids({ 'chart_lines' : chart_lines, 'callback_fn' : button_callback }); +fill_mavlink_ids({ 'chart_lines' : chart_lines, + 'callback_fn' : mavlink_callback, + 'extra_msgs' : ['STATUSTEXT'] }); // poll system information at 1Hz ajax_json_poll_fill(drone_url + "/ajax/sysinfo.json", 1000); From eaa657d1876dec63c466723129a3b1ac90e128ae Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 14:33:08 +1100 Subject: [PATCH 030/124] files/status.html: show EKF status on GPS page Originally authored by tridge --- files/status.html | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/files/status.html b/files/status.html index 8254f8b..9ee36f0 100644 --- a/files/status.html +++ b/files/status.html @@ -133,6 +133,7 @@

IMU Status

VariableValue FixType
Numsats
+ EKF Status
Latitude (GPS)
Longitude (GPS)
Altitude (AMSL)
@@ -388,6 +389,16 @@

Flight Controller Messages

return "0" + v; } + if (mavlink.EKF_STATUS_REPORT != null) { + var flags = mavlink.EKF_STATUS_REPORT.flags; + var d = document.getElementById("EKF_GPS_STATUS"); + var h = 'bad'; + if ((flags & 0x30) == 0x30) { + h = 'good'; + } + d.innerHTML = h; + } + if (mavlink.STATUSTEXT != null) { if (mavlink.STATUSTEXT._seq != last_statustext_seq) { last_statustext_seq = mavlink.STATUSTEXT._seq; From d6925fdf5477d5e833beb9700aadc0b9101fa141 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 14:57:18 +1100 Subject: [PATCH 031/124] files/status.html: fixes for rc-ok checks Originally authored by tridge --- files/js/mavlink.js | 2 ++ files/status.html | 19 +++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/files/js/mavlink.js b/files/js/mavlink.js index 5e0997f..e9cd65e 100644 --- a/files/js/mavlink.js +++ b/files/js/mavlink.js @@ -10,6 +10,8 @@ var MAV_CMD_PREFLIGHT_CALIBRATION = 241; var MAV_CMD_ACCELCAL_VEHICLE_POS = 42429; var MAV_CMD_DO_START_MAG_CAL = 42424; +var MAV_SYS_STATUS_SENSOR_RC_RECEIVER = 0x10000; + var MAV_SEVERITY_EMERGENCY = 0; var MAV_SEVERITY_ALERT = 1; var MAV_SEVERITY_CRITICAL = 2; diff --git a/files/status.html b/files/status.html index 9ee36f0..5ed66b5 100644 --- a/files/status.html +++ b/files/status.html @@ -179,6 +179,7 @@

IMU Status

+ @@ -418,14 +419,24 @@

Flight Controller Messages

var chan6 = mavlink.RC_CHANNELS.chan6_raw; var chan7 = mavlink.RC_CHANNELS.chan7_raw; var left_button, right_button, left_shoulder_button, right_shoulder_button, power_button; + var rc_ok = (mavlink.SYS_STATUS.onboard_control_sensors_health & MAV_SYS_STATUS_SENSOR_RC_RECEIVER) != 0; + var pressed_str = { false: "off", true: 'on' } + right_button = (chan6 > 1800); left_button = (chan5 > 2050) || (chan5 > 1050 && chan5 < 1150); var bits = Math.round((chan7 - 1000) / 100); - left_shoulder_button = ((bits & 1) != 0); - right_shoulder_button = ((bits & 2) != 0); - power_button = ((bits & 4) != 0); - var pressed_str = { false: "off", true: 'on' } + if (chan7 < 1000 || !rc_ok) { + left_shoulder_button = false; + right_shoulder_button = false; + power_button = false; + document.getElementById("rc_ok").innerHTML = 'OFF'; + } else { + left_shoulder_button = ((bits & 1) != 0); + right_shoulder_button = ((bits & 2) != 0); + power_button = ((bits & 4) != 0); + document.getElementById("rc_ok").innerHTML = 'OK'; + } document.getElementById("left_button").innerHTML = pressed_str[left_button]; document.getElementById("right_button").innerHTML = pressed_str[right_button]; From efb7708ee25fae327c8767abc6ad7bdc331522a2 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 15:26:44 +1100 Subject: [PATCH 032/124] files/status.html: adjust refresh to 4Hz Originally authored by tridge --- files/status.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/files/status.html b/files/status.html index 5ed66b5..d7a2fe7 100644 --- a/files/status.html +++ b/files/status.html @@ -341,10 +341,10 @@

Flight Controller Messages

Refresh rate:  +

Test Power From 5b043a5bcaadae2084df0ff1251189cf178d6dc5 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 15:48:31 +1100 Subject: [PATCH 035/124] rename get_ssid to get_ssid_info Originally authored by tridge --- files/system.html | 2 +- functions.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/files/system.html b/files/system.html index 609acae..00aa730 100644 --- a/files/system.html +++ b/files/system.html @@ -83,7 +83,7 @@

WiFi Setup

} // get the wifi information - command_send('get_ssid()', {filljson : true}); + command_send('get_ssid_info()', {filljson : true});
diff --git a/functions.c b/functions.c index 38e05f5..d7f8c0d 100644 --- a/functions.c +++ b/functions.c @@ -430,7 +430,7 @@ static void set_ssid(struct template_state *tmpl, const char *name, const char * /* get ssid and password */ -static void get_ssid(struct template_state *tmpl, const char *name, const char *value, int argc, char **argv) +static void get_ssid_info(struct template_state *tmpl, const char *name, const char *value, int argc, char **argv) { char ssid[50]="", pass[50]=""; int mode=0, channel=0; @@ -962,7 +962,7 @@ void functions_init(struct template_state *tmpl) tmpl->put(tmpl, "snapshot", "", snapshot); tmpl->put(tmpl, "mjpgvideo", "", mjpg_video); tmpl->put(tmpl, "take_picture", "", take_picture); - tmpl->put(tmpl, "get_ssid", "", get_ssid); + tmpl->put(tmpl, "get_ssid_info", "", get_ssid_info); tmpl->put(tmpl, "set_ssid", "", set_ssid); tmpl->put(tmpl, "sonix_version", "", sonix_version); tmpl->put(tmpl, "file_upload", "", file_upload); From 1d0ef8a616055547c8b5c14cce42f9968e08ef81 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 16:02:26 +1100 Subject: [PATCH 036/124] mavlink_json: whitespace fix --- mavlink_json.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mavlink_json.c b/mavlink_json.c index 295c98a..a9f1b86 100644 --- a/mavlink_json.c +++ b/mavlink_json.c @@ -95,8 +95,8 @@ bool mavlink_json_message(struct sock_buf *sock, const mavlink_message_t *msg, u sock_printf(sock, "\"%s\" : { ", m->name); for (i=0; inum_fields; i++) { print_field(sock, msg, &f[i]); - sock_printf(sock, ","); - } + sock_printf(sock, ","); + } sock_printf(sock, "\"_seq\" : %u, ", msg->seq); sock_printf(sock, "\"_sysid\" : %u, ", msg->sysid); sock_printf(sock, "\"_compid\" : %u, ", msg->compid); @@ -259,5 +259,3 @@ bool mavlink_message_send_args(int argc, char **argv) return true; } - - From 9c9c3e08c3044c0d2e46ce031afbfb4315d57e2e Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 17:39:43 +1100 Subject: [PATCH 037/124] web_server: adjust debug level Originally authored by tridge --- web_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_server.c b/web_server.c index 54b877d..fba9509 100644 --- a/web_server.c +++ b/web_server.c @@ -80,8 +80,8 @@ static int sock_buf_destroy(struct sock_buf *sock) } lock_state(); + web_debug(3,"closing fd %d num_sockets_open=%d\n", sock->fd, num_sockets_open); num_sockets_open--; - web_debug(4,"closing fd %d num_sockets_open=%d\n", sock->fd, num_sockets_open); unlock_state(); close(sock->fd); From b5185b951f2d9191c0ed771894fe34f212127d92 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 17:48:45 +1100 Subject: [PATCH 038/124] web_server.c: freertos compatability --- web_server.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/web_server.c b/web_server.c index fba9509..f7882bf 100644 --- a/web_server.c +++ b/web_server.c @@ -146,10 +146,15 @@ void sock_printf(struct sock_buf *sock, const char *fmt, ...) void connection_destroy(struct connection_state *c) { talloc_free(c); +#ifdef SYSTEM_FREERTOS + vTaskDelete(NULL); +#else pthread_exit(0); +#endif } +#ifndef SYSTEM_FREERTOS /* write some data to the flight controller */ @@ -198,6 +203,7 @@ static void mavlink_broadcast(int fd, mavlink_message_t *msg) sendto(fd, buf, len, 0, (struct sockaddr*)&addr, sizeof(addr)); } } +#endif /* process input on a connection From 539a8627436ec07f08195b00d6720304c0a3bc1c Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 22:50:34 +1100 Subject: [PATCH 039/124] functions.c: deconst some variables in freertos Originally authored by tridge --- functions.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/functions.c b/functions.c index d7f8c0d..72c1975 100644 --- a/functions.c +++ b/functions.c @@ -421,8 +421,8 @@ static void set_ssid(struct template_state *tmpl, const char *name, const char * snx_nvram_integer_set("WIFI_DEV", "AP_AUTH_MODE", auth_mode); snx_nvram_integer_set("WIFI_DEV", "AP_CHANNEL_INFO", ap_channel); - snx_nvram_string_set("WIFI_DEV", "AP_SSID_INFO", ssid); - snx_nvram_string_set("WIFI_DEV", "AP_KEY_INFO", password); + snx_nvram_string_set("WIFI_DEV", "AP_SSID_INFO", __DECONST(char *,ssid)); + snx_nvram_string_set("WIFI_DEV", "AP_KEY_INFO", __DECONST(char *,password)); sock_printf(tmpl->sock, "Set SSID and password"); } From 754fb16bd9dd3e5ac70b7fe979e1de43ad83f9ce Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 27 Oct 2017 22:53:05 +1100 Subject: [PATCH 040/124] functions.c: sync write fh on file upload Originally authored by tridge --- functions.c | 1 + 1 file changed, 1 insertion(+) diff --git a/functions.c b/functions.c index 72c1975..41ce6ce 100644 --- a/functions.c +++ b/functions.c @@ -508,6 +508,7 @@ static void handle_file_upload(struct template_state *tmpl, const char *filename } else { result = "file write failed"; } + f_sync(&fh); f_close(&fh); } else { result = "failed to open file"; From 8c7c8a3ff6656e2c5cb0a7b2b5ab412ac1983309 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 28 Oct 2017 11:32:33 +1100 Subject: [PATCH 041/124] html/functions.c: prettify sonix upgrade messages Originally authored by tridge --- files/system.html | 3 +++ functions.c | 7 +++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/files/system.html b/files/system.html index 00aa730..fdac8a7 100644 --- a/files/system.html +++ b/files/system.html @@ -112,6 +112,9 @@

Factory Reset

your ArduPilot you should change your WiFi password immediately after rebooting.

+

NOTE! You must first power-cycle and then re-calibrate after a + reset or you will not be able to arm.

+


diff --git a/functions.c b/functions.c index 41ce6ce..8054c98 100644 --- a/functions.c +++ b/functions.c @@ -452,12 +452,15 @@ static void handle_sonix_upgrade(struct template_state *tmpl, const char *filena set_upload_message("checking firmware MD5"); set_upload_progress(1); if (check_fw_md5((const unsigned char *)filedata, size)) { - set_upload_message("Good MD5 on image - upgrading. Please reconnect WiFi in 30 seconds"); + set_upload_message("Good MD5 on image"); + mdelay(1000); set_upload_progress(100); // give time for UI to update + set_upload_message("starting upgrade"); mdelay(3000); fw_upgrade(__DECONST(char*,filedata), size); - set_upload_message("rebooting"); + set_upload_message("success - rebooting"); + mdelay(3000); } else { set_upload_message("Bad MD5 on image"); } From 8eb4d8ca18048f44eec096d6c49c314335487cf5 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 28 Oct 2017 11:33:08 +1100 Subject: [PATCH 042/124] functions.c: fix bug in nvram_set_value Originally authored by tridge --- functions.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/functions.c b/functions.c index 8054c98..d74e14a 100644 --- a/functions.c +++ b/functions.c @@ -925,22 +925,30 @@ static void nvram_set_value(struct template_state *tmpl, const char *name, const } uint32_t i; int dtype = -1; + nvram_cfg_name_data_info_t *cfg = NULL; + for (i=0; iname) == 0) { + break; + } + } - cfg_data = talloc_zero_size(cfg_name_info, cfg->data_info.data_len); - if (cfg_data == NULL) { - continue; - } - cfg->data_info.data = cfg_data; - snx_nvram_get_immediately(pack_name, cfg_name, &cfg->data_info); - dtype = cfg->data_info.data_type; + if (i == cfg_cnt) { + goto failed; } + void *cfg_data = talloc_zero_size(cfg_name_info, cfg->data_info.data_len); + if (cfg_data == NULL) { + goto failed; + } + cfg->data_info.data = cfg_data; + snx_nvram_get_immediately(pack_name, cfg_name, &cfg->data_info); + dtype = cfg->data_info.data_type; + switch (dtype) { case NVRAM_DT_STRING: - rc = snx_nvram_string_set(pack_name, cfg_name, svalue); + rc = snx_nvram_string_set(pack_name, cfg_name, __DECONST(char *,svalue)); break; case NVRAM_DT_INT: rc = snx_nvram_integer_set(pack_name, cfg_name, atoi(svalue)); From e351809d32a4e4cafc026310a2c8e913d35ea3a7 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 28 Oct 2017 11:49:06 +1100 Subject: [PATCH 043/124] functions.c: read data length from nvram in nvram_pack_values Originally authored by tridge --- functions.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/functions.c b/functions.c index d74e14a..4c6662d 100644 --- a/functions.c +++ b/functions.c @@ -846,21 +846,27 @@ static void nvram_pack_values(struct template_state *tmpl, const char *name, con while (cfg_cnt--) { nvram_cfg_name_data_info_t *cfg = &cfg_name_info[cfg_cnt]; + unsigned int data_len = 0; cfg_name = cfg->name; + if (snx_nvram_get_data_len(pack_name, cfg_name, &data_len) != NVRAM_SUCCESS || data_len == 0) { + continue; + } if (!first) { sock_printf(tmpl->sock, ", "); } first = false; - sock_printf(tmpl->sock, "{ \"name\" : \"%s\", \"size\" : %u, ", - cfg_name, cfg->data_info.data_len); + sock_printf(tmpl->sock, "{ \"name\" : \"%s\", \"size\" : %u, ", cfg_name, data_len); void *cfg_data = NULL; - cfg_data = talloc_zero_size(cfg_name_info, cfg->data_info.data_len); + cfg_data = talloc_zero_size(cfg_name_info, data_len); if (cfg_data == NULL) { continue; } cfg->data_info.data = cfg_data; snx_nvram_get_immediately(pack_name, cfg_name, &cfg->data_info); + if (cfg->data_info.data_type == NVRAM_DT_BIN_RAW) { + snx_nvram_binary_get(pack_name, cfg_name, cfg_data); + } switch (cfg->data_info.data_type) { case NVRAM_DT_STRING: @@ -891,6 +897,7 @@ static void nvram_pack_values(struct template_state *tmpl, const char *name, con sock_printf(tmpl->sock, "\"type\" : \"unknown\" }"); break; } + talloc_free(cfg_data); cfg_data = NULL; } From e4299570ba0a81b640c6c7d6ae7e2695600deb4f Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 28 Oct 2017 12:20:33 +1100 Subject: [PATCH 044/124] functions.c: add get_ssid function Originally authored by tridge --- functions.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/functions.c b/functions.c index 4c6662d..7067aa7 100644 --- a/functions.c +++ b/functions.c @@ -444,6 +444,18 @@ static void get_ssid_info(struct template_state *tmpl, const char *name, const c ssid, pass, channel, mode); } +/* + get ssid + */ +static void get_ssid(struct template_state *tmpl, const char *name, const char *value, int argc, char **argv) +{ + char ssid[50]=""; + + snx_nvram_string_get("WIFI_DEV", "AP_SSID_INFO", ssid); + + sock_printf(tmpl->sock, "%s", ssid); +} + /* handle sonix fw update */ @@ -998,6 +1010,7 @@ void functions_init(struct template_state *tmpl) tmpl->put(tmpl, "nvram_pack_list", "", nvram_pack_list); tmpl->put(tmpl, "nvram_pack_values", "", nvram_pack_values); tmpl->put(tmpl, "nvram_set_value", "", nvram_set_value); + tmpl->put(tmpl, "get_ssid", "", get_ssid); #endif // SYSTEM_FREERTOS tmpl->put(tmpl, "format_storage", "", format_storage); tmpl->put(tmpl, "factory_reset", "", factory_reset); From b6e01c8bbb95ddbb2112c3c0b2bda46ae74829aa Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 28 Oct 2017 12:33:58 +1100 Subject: [PATCH 045/124] web_server.c: freertos-specific sock_printf functionality Originally authored by tridge --- web_server.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web_server.c b/web_server.c index f7882bf..3bd3a22 100644 --- a/web_server.c +++ b/web_server.c @@ -129,12 +129,16 @@ void sock_printf(struct sock_buf *sock, const char *fmt, ...) va_list ap; va_start(ap, fmt); char *buf2 = print_vprintf(sock, fmt, ap); +#ifdef SYSTEM_FREERTOS + sock_write(sock, buf2, talloc_get_size(buf2)); +#else size_t size = talloc_get_size(buf2); if (buf2 && size > 0 && buf2[size-1] == 0) { // cope with differences in print_vprintf between platforms size--; } sock_write(sock, buf2, size); +#endif talloc_free(buf2); va_end(ap); } From fbf8ada0fc5e609ab9e5dfbaeca5ed59e1c4888c Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 28 Oct 2017 12:50:40 +1100 Subject: [PATCH 046/124] web_server.c: copy in FreeRTOS web_server_connection_process method Originally authored by tridge --- web_server.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/web_server.c b/web_server.c index 3bd3a22..604f0cc 100644 --- a/web_server.c +++ b/web_server.c @@ -298,6 +298,21 @@ static void setup_origin(const char *origin) /* task for web_server */ +#ifdef SYSTEM_FREERTOS +static void web_server_connection_process(void *pvParameters) +{ + struct connection_state *c = pvParameters; + c->cgi = cgi_init(c, c->sock); + if (!c->cgi) { + connection_destroy(c); + return; + } + + c->cgi->check_origin = check_origin; + + connection_process(c); +} +#else static void *web_server_connection_process(void *arg) { int fd = (intptr_t)arg; @@ -326,6 +341,7 @@ static void *web_server_connection_process(void *arg) connection_process(c); return NULL; } +#endif /* main select loop From d7766c63f18aad7560e14e00e72de997e1f0dcce Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 28 Oct 2017 12:54:15 +1100 Subject: [PATCH 047/124] web_server.c: copy in FreeRTOS web_server_task_process Originally authored by tridge --- web_server.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/web_server.c b/web_server.c index 604f0cc..a1c9dd3 100644 --- a/web_server.c +++ b/web_server.c @@ -343,6 +343,83 @@ static void *web_server_connection_process(void *arg) } #endif +#ifdef SYSTEM_FREERTOS +/* + task for web_server +*/ +void web_server_task_process(void *pvParameters) +{ + int listen_sock; + + struct sockaddr_in addr; + + // setup default allowed origin + setup_origin(public_origin); + + if ((listen_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + goto end; + } + + memset(&addr, 0x0, sizeof(addr)); + + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_port = htons(WEB_SERVER_PORT); + + if (bind(listen_sock, (struct sockaddr*)&addr, sizeof(addr)) < 0) { + goto end; + } + + if (listen(listen_sock, 20) < 0) { + goto end; + } + + while (1) + { + fd_set fds; + struct timeval tv; + int numfd = listen_sock+1; + + FD_ZERO(&fds); + FD_SET(listen_sock, &fds); + + tv.tv_sec = 1; + tv.tv_usec = 0; + + int res = select(numfd, &fds, NULL, NULL, &tv); + if (res <= 0) { + continue; + } + + if (FD_ISSET(listen_sock, &fds)) { + // new connection + struct sockaddr_in addr; + int len = sizeof(struct sockaddr_in); + int fd = accept(listen_sock, (struct sockaddr *)&addr, (socklen_t *)&len); + if (fd != -1) { + struct connection_state *c = talloc_zero(NULL, struct connection_state); + if (c == NULL) { + close(fd); + continue; + } + c->sock = talloc_zero(c, struct sock_buf); + if (!c->sock) { + talloc_free(c); + close(fd); + continue; + } + c->sock->fd = fd; + num_sockets_open++; + talloc_set_destructor(c->sock, sock_buf_destroy); + xTaskCreate(web_server_connection_process, "http_connection", STACK_SIZE_4K, c, 10, &c->task); + } + } + } + +end: + vTaskDelete(NULL); +} +#else /* main select loop */ @@ -671,3 +748,4 @@ int main(int argc, char *argv[]) return 0; } +#endif From 3c639deb68ad597010194d94c351d9f06f14d4fd Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 28 Oct 2017 13:11:23 +1100 Subject: [PATCH 048/124] web_server.c: protect POSIX-specific functions, update Sonix includes Originally authored by tridge --- web_server.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/web_server.c b/web_server.c index a1c9dd3..d8efe3f 100644 --- a/web_server.c +++ b/web_server.c @@ -8,21 +8,28 @@ #include "web_server.h" #include "includes.h" #include "web_files.h" - +#ifdef SYSTEM_FREERTOS +#include +#else #include +#endif +#ifndef SYSTEM_FREERTOS static pthread_mutex_t lock; -static int num_sockets_open; -static int debug_level; static int serial_port_fd = -1; static int fc_udp_in_fd = -1; -// public web-site that will be allowed. Can be edited with NVRAM editor -static const char *public_origin = "fly.example.com"; - struct sockaddr_in fc_addr; socklen_t fc_addrlen; +#endif + +static int num_sockets_open; +static int debug_level; + +// public web-site that will be allowed. Can be edited with NVRAM editor +static const char *public_origin = "fly.example.com"; + #ifndef bool #define bool int #endif @@ -43,6 +50,15 @@ void web_debug(int level, const char *fmt, ...) va_end(ap); } +#ifdef SYSTEM_FREERTOS +static void lock_state(void) +{ +} + +static void unlock_state(void) +{ +} +#else static void lock_state(void) { pthread_mutex_lock(&lock); @@ -52,6 +68,7 @@ static void unlock_state(void) { pthread_mutex_unlock(&lock); } +#endif /* destroy socket buffer, writing any pending data From 398a729f6d495fbc4ba5b72d087172f81ae5c8e5 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 28 Oct 2017 13:17:24 +1100 Subject: [PATCH 049/124] web_server.c: origin-checking allows from FreeRTOS get_local_ip Originally authored by tridge --- web_server.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/web_server.c b/web_server.c index d8efe3f..c5c43ac 100644 --- a/web_server.c +++ b/web_server.c @@ -251,6 +251,19 @@ static bool check_origin(const char *origin) // always accept return true; } + +#ifdef SYSTEM_FREERTOS + // could be a different local IP + char local_ip[16]; + get_local_ip(local_ip, sizeof(local_ip)); + if (strncmp(origin, "http://", 7) == 0 && + strcmp(origin+7, local_ip) == 0) { + return true; + } +#else + // TODO: check all IPs on all interfaces? +#endif + // also allow file:// URLs which produce a 'null' origin if (strcmp(origin, "null") == 0) { return true; From 990cd056e559e803e9c75039e3d94dff2c0f278d Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 28 Oct 2017 13:23:48 +1100 Subject: [PATCH 050/124] web_server.h: FreeRTOS support Originally authored by tridge --- web_server.h | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/web_server.h b/web_server.h index 7fe9b17..3dfcc60 100644 --- a/web_server.h +++ b/web_server.h @@ -1,5 +1,12 @@ #pragma once +#ifdef SYSTEM_FREERTOS +#include +#include +#include +#include "../dev_console.h" +#include "../mavlink_wifi.h" +#else #include #include #include @@ -27,6 +34,7 @@ #include #include #include +#endif struct connection_state; @@ -49,21 +57,36 @@ struct sock_buf { state of one connection */ struct connection_state { +#ifdef SYSTEM_FREERTOS + xTaskHandle task; +#endif struct sock_buf *sock; struct cgi_state *cgi; }; -#define FMT_PRINTF(a,b) __attribute__((format(printf, a, b))) - void web_server_task_process(void *pvParameters); void connection_destroy(struct connection_state *c); +#ifdef SYSTEM_FREERTOS +int32_t sock_write(struct sock_buf *sock, const char *s, size_t size); +#else ssize_t sock_write(struct sock_buf *sock, const char *s, size_t size); +#endif +#ifndef SYSTEM_FREERTOS +#define FMT_PRINTF(a,b) __attribute__((format(printf, a, b))) +#endif void sock_printf(struct sock_buf *sock, const char *fmt, ...) FMT_PRINTF(2,3); void web_server_set_debug(int debug); void web_debug(int level, const char *fmt, ...); void mavlink_fc_write(const uint8_t *buf, size_t len); +#ifdef SYSTEM_FREERTOS +void mavlink_rc_write(const uint8_t *buf, uint32_t len); +#endif +#ifndef SYSTEM_FREERTOS #define console_printf printf #define console_vprintf vprintf +#define simple_strtoul strtoul +#define simple_strtol strtol +#endif From 2a096068cf5f34547eed7ed2e50630f803fe67c6 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 28 Oct 2017 13:51:05 +1100 Subject: [PATCH 051/124] fixed misaligned accesses for SERVO_OUTPUT_RAW thanks to Martin for reporting Originally authored by tridge --- mavlink_core.h | 3 +++ mavlink_json.c | 60 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 43 insertions(+), 20 deletions(-) diff --git a/mavlink_core.h b/mavlink_core.h index 2a629e6..051d7a7 100644 --- a/mavlink_core.h +++ b/mavlink_core.h @@ -6,6 +6,9 @@ #define MAVLINK_SEPARATE_HELPERS #define MAVLINK_NO_CONVERSION_HELPERS +// arm processor does not handle misaligned accesses +#define MAVLINK_ALIGNED_FIELDS 0 + #define MAVLINK_SEND_UART_BYTES(chan, buf, len) comm_send_buffer(chan, buf, len) // allow two mavlink ports diff --git a/mavlink_json.c b/mavlink_json.c index a9f1b86..006e99d 100644 --- a/mavlink_json.c +++ b/mavlink_json.c @@ -159,46 +159,66 @@ bool mavlink_message_send_args(int argc, char **argv) } break; - case MAVLINK_TYPE_UINT8_T: - _mav_put_uint8_t(buf, f->wire_offset, strtoul(arg, NULL, 0)); + case MAVLINK_TYPE_UINT8_T: { + uint8_t b = simple_strtoul(arg, NULL, 0); + _mav_put_uint8_t(buf, f->wire_offset, b); break; + } - case MAVLINK_TYPE_UINT16_T: - _mav_put_uint16_t(buf, f->wire_offset, strtoul(arg, NULL, 0)); + case MAVLINK_TYPE_UINT16_T: { + uint16_t b = simple_strtoul(arg, NULL, 0); + _mav_put_uint16_t(buf, f->wire_offset, b); break; + } - case MAVLINK_TYPE_UINT32_T: - _mav_put_uint32_t(buf, f->wire_offset, strtoul(arg, NULL, 0)); + case MAVLINK_TYPE_UINT32_T: { + uint32_t b = simple_strtoul(arg, NULL, 0); + _mav_put_uint32_t(buf, f->wire_offset, b); break; + } - case MAVLINK_TYPE_UINT64_T: - _mav_put_uint64_t(buf, f->wire_offset, strtoull(arg, NULL, 0)); + case MAVLINK_TYPE_UINT64_T: { + uint64_t b = simple_strtoul(arg, NULL, 0); + _mav_put_uint64_t(buf, f->wire_offset, b); break; + } - case MAVLINK_TYPE_INT8_T: - _mav_put_int8_t(buf, f->wire_offset, strtol(arg, NULL, 0)); + case MAVLINK_TYPE_INT8_T: { + int8_t b = simple_strtol(arg, NULL, 0); + _mav_put_int8_t(buf, f->wire_offset, b); break; + } - case MAVLINK_TYPE_INT16_T: - _mav_put_int16_t(buf, f->wire_offset, strtol(arg, NULL, 0)); + case MAVLINK_TYPE_INT16_T: { + int16_t b = strtol(arg, NULL, 0); + _mav_put_int16_t(buf, f->wire_offset, b); break; + } - case MAVLINK_TYPE_INT32_T: - _mav_put_int32_t(buf, f->wire_offset, strtol(arg, NULL, 0)); + case MAVLINK_TYPE_INT32_T: { + int32_t b = strtol(arg, NULL, 0); + _mav_put_int32_t(buf, f->wire_offset, b); break; + } - case MAVLINK_TYPE_INT64_T: - _mav_put_int64_t(buf, f->wire_offset, strtoll(arg, NULL, 0)); + case MAVLINK_TYPE_INT64_T: { + int64_t b = strtol(arg, NULL, 0); + _mav_put_int64_t(buf, f->wire_offset, b); break; + } - case MAVLINK_TYPE_FLOAT: - _mav_put_float(buf, f->wire_offset, atof(arg)); + case MAVLINK_TYPE_FLOAT: { + float b = atof(arg); + _mav_put_float(buf, f->wire_offset, b); break; + } - case MAVLINK_TYPE_DOUBLE: - _mav_put_double(buf, f->wire_offset, atof(arg)); + case MAVLINK_TYPE_DOUBLE: { + double b = atof(arg); + _mav_put_double(buf, f->wire_offset, b); break; } + } } uint8_t msglen = 0; From 949b8df1b0a03f85d7a4f3cc602127bd8e872673 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 28 Oct 2017 13:59:26 +1100 Subject: [PATCH 052/124] include.h: FreeRTOS support Originally authored by tridge --- includes.h | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/includes.h b/includes.h index 61f3705..2586e83 100644 --- a/includes.h +++ b/includes.h @@ -1,8 +1,30 @@ #pragma once +#ifdef SYSTEM_FREERTOS +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "socket_ctrl.h" +#include +#include "../talloc.h" +#include "../dev_console.h" +#include "../util/print_vprintf.h" +#else #include "linux/includes.h" +#include "mavlink_core.h" +#endif #include "cgi.h" #include "template.h" #include "web_files.h" -#include "mavlink_core.h" + + From eba1787a7e4c253a2adb52ab88e9410d758a8001 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 28 Oct 2017 14:01:36 +1100 Subject: [PATCH 053/124] functions.c: update FreeRTOS includes Originally authored by tridge --- functions.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/functions.c b/functions.c index 7067aa7..2fc7f92 100644 --- a/functions.c +++ b/functions.c @@ -10,6 +10,17 @@ #include "cgi.h" #ifdef SYSTEM_FREERTOS +#include "../mavlink_wifi.h" +#include "video_main.h" +#include +#include +#include +#include "../tx_upload.h" +#include "../ublox.h" +#include "files/version.h" +#include +#include + /* get uptime in seconds */ @@ -1026,4 +1037,3 @@ void functions_init(struct template_state *tmpl) tmpl->put(tmpl, "get_param", "", get_param); tmpl->put(tmpl, "get_param_list", "", get_param_list); } - From 9df86d5053d99a614b5f0f0efe0672cc47a776b6 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Sat, 28 Oct 2017 14:05:08 +1100 Subject: [PATCH 054/124] functions.c: FreeRTOS reboot function Originally authored by tridge --- functions.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/functions.c b/functions.c index 2fc7f92..deb718e 100644 --- a/functions.c +++ b/functions.c @@ -331,7 +331,11 @@ static void mavlink_message_send(struct template_state *tmpl, const char *name, static void reboot_companion(struct template_state *tmpl, const char *name, const char *value, int argc, char **argv) { console_printf("rebooting ...\n"); +#ifdef SYSTEM_FREERTOS + reboot(); +#else __reboot(); +#endif } extern void snx_nvram_bootup_upgrade(void); From 680e38ac8a447bcb2540340fd9294aaf2af31cd6 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Tue, 13 Jun 2017 16:34:02 +1000 Subject: [PATCH 055/124] Makefile: conform to gnu99 standards Several sticking points on using c99 standard, most notably cfnetspeed flags --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e9c0c95..6b097e3 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC=gcc -CFLAGS=-Wall -g -Werror +CFLAGS=-Wall -g -Werror -std=gnu99 SRC = $(wildcard *.c) $(wildcard lib/*.c) $(wildcard linux/*.c) OBJ = $(SRC:%.c=%.o) From f7d6efb9b04de38e48be8953d983d29759de1c90 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 14 Jun 2017 10:27:34 +1000 Subject: [PATCH 056/124] Add a .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1c8938c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.o +generated +web_server From 4000bc8337e018becce8e5dfc93056ea75d8db9f Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 18 Aug 2017 14:02:44 +1000 Subject: [PATCH 057/124] files: index.html: adjust welcome message --- files/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/index.html b/files/index.html index 968f313..aa3e555 100644 --- a/files/index.html +++ b/files/index.html @@ -15,7 +15,7 @@

ArduPilot Web Server

-Welcome to the ArduPilot Streaming GPS Drone

+Welcome to the ArduPilot Web Interface!

  • Filesystem access
  • From d6422694ed4f88648285534106ce569c0da83912 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 21 Jun 2017 15:02:01 +1000 Subject: [PATCH 058/124] Use console_printf in place of fprintf --- web_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_server.c b/web_server.c index c5c43ac..164071e 100644 --- a/web_server.c +++ b/web_server.c @@ -733,7 +733,7 @@ int main(int argc, char *argv[]) if (fc_udp_in_port !=-1 && serial_port != NULL) { // don't want to muck around with multiple mavlink channels - fprintf(stderr, "Only one of serial port and udp-in-port (-s and -u) can be supplied"); + console_printf("Only one of serial port and udp-in-port (-s and -u) can be supplied"); exit(1); } From 46c7b8bfd6bfb703e49f1d284cbf9f6f022a1917 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 14 Jun 2017 08:49:43 +1000 Subject: [PATCH 059/124] main: avoid calling mavlink_broadcast with bad fd --- web_server.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/web_server.c b/web_server.c index 164071e..cf7edfb 100644 --- a/web_server.c +++ b/web_server.c @@ -537,7 +537,9 @@ static void select_loop(int http_socket_fd, int udp_socket_fd) if (mavlink_parse_char(MAVLINK_COMM_FC, buf[i], &msg, &status)) { if (!mavlink_handle_msg(&msg)) { // forward to network connection as a udp broadcast packet - mavlink_broadcast(udp_socket_fd, &msg); + if (udp_socket_fd != -1) { + mavlink_broadcast(udp_socket_fd, &msg); + } } } } @@ -560,7 +562,9 @@ static void select_loop(int http_socket_fd, int udp_socket_fd) if (mavlink_parse_char(MAVLINK_COMM_FC, buf[i], &msg, &status)) { if (!mavlink_handle_msg(&msg)) { // forward to network connection as a udp broadcast packet - mavlink_broadcast(udp_socket_fd, &msg); + if (udp_socket_fd != -1) { + mavlink_broadcast(udp_socket_fd, &msg); + } } } } From 41246aa29fc75d1b502db659c91ff815c198d8cc Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 21 Jun 2017 09:57:17 +1000 Subject: [PATCH 060/124] web_server: Add UDP address:port output --- web_server.c | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 2 deletions(-) diff --git a/web_server.c b/web_server.c index cf7edfb..a77ee41 100644 --- a/web_server.c +++ b/web_server.c @@ -11,6 +11,7 @@ #ifdef SYSTEM_FREERTOS #include #else +#include #include #endif @@ -18,10 +19,14 @@ static pthread_mutex_t lock; static int serial_port_fd = -1; static int fc_udp_in_fd = -1; +static int udp_out_fd = -1; struct sockaddr_in fc_addr; socklen_t fc_addrlen; +struct sockaddr_in udp_out_addr; +socklen_t udp_out_addrlen; + #endif static int num_sockets_open; @@ -226,6 +231,21 @@ static void mavlink_broadcast(int fd, mavlink_message_t *msg) } #endif +/* + send a mavlink msg over WiFi to a single target + */ +static void mavlink_send_udp_out(mavlink_message_t *msg) +{ + if (udp_out_fd == -1) { + return; + } + uint8_t buf[300]; + uint16_t len = mavlink_msg_to_send_buffer(buf, msg); + if (len > 0) { + sendto(udp_out_fd, buf, len, 0, (struct sockaddr*)&udp_out_addr, sizeof(udp_out_addr)); + } +} + /* process input on a connection */ @@ -487,6 +507,13 @@ static void select_loop(int http_socket_fd, int udp_socket_fd) } } + if (udp_out_fd != -1) { + FD_SET(udp_out_fd, &fds); + if (udp_out_fd >= numfd) { + numfd = udp_out_fd+1; + } + } + tv.tv_sec = 1; tv.tv_usec = 0; @@ -524,6 +551,21 @@ static void select_loop(int http_socket_fd, int udp_socket_fd) } } + // check for incoming UDP packet from udp-out connection: + if (udp_out_fd != -1 && + FD_ISSET(udp_out_fd, &fds)) { + // we have data pending + uint8_t buf[1024]; + fc_addrlen = sizeof(fc_addr); + ssize_t nread = recvfrom(udp_out_fd, buf, sizeof(buf), MSG_DONTWAIT, (struct sockaddr*)&udp_out_addr, &udp_out_addrlen); + if (nread <= 0) { + /* printf("Read error from udp out connection\n"); */ + } else { + // send to flight controller + mavlink_fc_write(buf, nread); + } + } + if (fc_udp_in_fd != -1 && FD_ISSET(fc_udp_in_fd, &fds)) { // we have data pending @@ -540,6 +582,8 @@ static void select_loop(int http_socket_fd, int udp_socket_fd) if (udp_socket_fd != -1) { mavlink_broadcast(udp_socket_fd, &msg); } + // send to udp-out connection + mavlink_send_udp_out(&msg); } } } @@ -565,6 +609,8 @@ static void select_loop(int http_socket_fd, int udp_socket_fd) if (udp_socket_fd != -1) { mavlink_broadcast(udp_socket_fd, &msg); } + // send to udp-out connection + mavlink_send_udp_out(&msg); } } } @@ -692,6 +738,43 @@ static int udp_in_open(int port) return res; } +static int udp_out_open(const char *ip, const int port) +{ + int one=1; + + // prepare sending socket + struct sockaddr_in send_addr; + + memset(&send_addr,0,sizeof(send_addr)); + + send_addr.sin_port = 0; + send_addr.sin_family = AF_INET; + + int res = socket(AF_INET, SOCK_DGRAM, 0); + if (res == -1) { + return -1; + } + + setsockopt(res,SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one)); + + if (bind(res, (struct sockaddr *)&send_addr, sizeof(send_addr)) < 0) { + return(-1); + } + + // prepare destination address + memset(&udp_out_addr,0x0,sizeof(udp_out_addr)); + udp_out_addr.sin_family = AF_INET; + if (inet_pton(AF_INET, ip, &udp_out_addr.sin_addr.s_addr) != 1) { + printf("Failed to convert IP address\n"); + exit(1); + } + udp_out_addr.sin_family = AF_INET; + udp_out_addr.sin_port = htons(port); + + return res; +} + + /* main program, start listening and answering queries */ int main(int argc, char *argv[]) { @@ -700,14 +783,15 @@ int main(int argc, char *argv[]) int opt; const char *serial_port = NULL; unsigned baudrate = 57600; - const char *usage = "Usage: web_server -p http_port -b baudrate -s serial_port -d debug_level -u -f fc_udp_in"; + const char *usage = "Usage: web_server -p http_port -b baudrate -s serial_port -d debug_level -u -f fc_udp_in -O udp-out-address:port"; bool do_udp_broadcast = 0; int fc_udp_in_port = -1; + const char *udp_out_arg = NULL; // e.g. 1.2.3.4:6543 // setup default allowed origin setup_origin(public_origin); - while ((opt=getopt(argc, argv, "p:s:b:hd:uf:")) != -1) { + while ((opt=getopt(argc, argv, "p:s:b:hd:uf:O:")) != -1) { switch (opt) { case 'p': http_port = atoi(optarg); @@ -727,6 +811,9 @@ int main(int argc, char *argv[]) case 'f': fc_udp_in_port = atoi(optarg); break; + case 'O': + udp_out_arg = optarg; + break; case 'h': default: printf("%s\n", usage); @@ -777,6 +864,20 @@ int main(int argc, char *argv[]) } } + if (udp_out_arg != NULL) { + char *colon = strchr(udp_out_arg, ':'); + if (colon == NULL) { + printf("udp-out address should be e.g. 1.2.3.4:6543\n"); + exit(1); + } + *colon = '\0'; + udp_out_fd = udp_out_open(udp_out_arg, atoi(colon+1)); + if (udp_out_fd == -1) { + printf("Failed to open UDP-out (%s:%u)\n", udp_out_arg, atoi(colon+1)); + exit(1); + } + } + select_loop(http_socket_fd, udp_socket_fd); return 0; From 9c5fab0f5e1050c0e733e89d8bf70c4d48cfb223 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 21 Jun 2017 10:15:55 +1000 Subject: [PATCH 061/124] web_server: allow specification of IP address for TCP listen --- web_server.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/web_server.c b/web_server.c index a77ee41..a527835 100644 --- a/web_server.c +++ b/web_server.c @@ -650,7 +650,7 @@ static int mavlink_serial_open(const char *path, unsigned baudrate) /* open a TCP listening socket */ -static int tcp_open(unsigned port) +static int tcp_open(const char *ip, const unsigned port) { struct sockaddr_in sock; int listen_sock; @@ -659,6 +659,12 @@ static int tcp_open(unsigned port) memset((char *)&sock, 0, sizeof(sock)); sock.sin_port = htons(port); sock.sin_family = AF_INET; + if (ip != NULL) { + if (inet_pton(AF_INET, ip, &sock.sin_addr.s_addr) != 1) { + printf("Failed to convert IP address\n"); + exit(1); + } + } listen_sock = socket(AF_INET, SOCK_STREAM, 0); setsockopt(listen_sock, SOL_SOCKET,SO_REUSEADDR,(char *)&one,sizeof(one)); @@ -778,7 +784,6 @@ static int udp_out_open(const char *ip, const int port) /* main program, start listening and answering queries */ int main(int argc, char *argv[]) { - int http_port = -1; extern char *optarg; int opt; const char *serial_port = NULL; @@ -787,6 +792,7 @@ int main(int argc, char *argv[]) bool do_udp_broadcast = 0; int fc_udp_in_port = -1; const char *udp_out_arg = NULL; // e.g. 1.2.3.4:6543 + const char *http_port_arg = NULL; // e.g. 1.2.3.4:6543 or 6543 // setup default allowed origin setup_origin(public_origin); @@ -794,7 +800,7 @@ int main(int argc, char *argv[]) while ((opt=getopt(argc, argv, "p:s:b:hd:uf:O:")) != -1) { switch (opt) { case 'p': - http_port = atoi(optarg); + http_port_arg = optarg; break; case 's': serial_port = optarg; @@ -848,8 +854,16 @@ int main(int argc, char *argv[]) } int http_socket_fd = -1; - if (http_port != -1) { - http_socket_fd = tcp_open(http_port); + if (http_port_arg != NULL) { + char *colon = strchr(http_port_arg, ':'); + if (colon == NULL) { + // just a port number + http_socket_fd = tcp_open(NULL, atoi(http_port_arg)); + } else { + *colon = '\0'; + http_socket_fd = tcp_open(http_port_arg, atoi(colon+1)); + } + if (http_socket_fd == -1) { printf("Failed to open TCP socket\n"); exit(1); From 208087d01212cd0837ba612f7de474d2aa523c3d Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 21 Jun 2017 10:48:54 +1000 Subject: [PATCH 062/124] web_server: Make serial port read errors non-fatal --- web_server.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/web_server.c b/web_server.c index a527835..0bda4e2 100644 --- a/web_server.c +++ b/web_server.c @@ -596,21 +596,22 @@ static void select_loop(int http_socket_fd, int udp_socket_fd) uint8_t buf[200]; ssize_t nread = read(serial_port_fd, buf, sizeof(buf)); if (nread <= 0) { - printf("Read error from flight controller\n"); + printf("Read error from flight controller: %s\n", strerror(errno)); // we should re-open serial port - exit(1); - } - mavlink_message_t msg; - mavlink_status_t status; - for (uint16_t i=0; i Date: Wed, 21 Jun 2017 13:59:40 +1000 Subject: [PATCH 063/124] web_server: Increase debug on accept failure --- web_server.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/web_server.c b/web_server.c index 0bda4e2..11182fa 100644 --- a/web_server.c +++ b/web_server.c @@ -526,7 +526,10 @@ static void select_loop(int http_socket_fd, int udp_socket_fd) if (http_socket_fd != -1 && FD_ISSET(http_socket_fd, &fds)) { int fd = accept(http_socket_fd, NULL,0); - if (fd == -1) continue; + if (fd == -1) { + fprintf(stderr, "accept failed: %s\n", strerror(errno)); + continue; + }; // use a thread per connection. This allows for sending MAVLink messages // via mavlink_fc_send() from connections From d37c41f3975f6cf6d91d1637bb8dcaf1b8d9ff6f Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 21 Jun 2017 14:27:03 +1000 Subject: [PATCH 064/124] web_server: Move http accept into own function, add error checking --- web_server.c | 53 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/web_server.c b/web_server.c index 11182fa..868a145 100644 --- a/web_server.c +++ b/web_server.c @@ -470,6 +470,43 @@ void web_server_task_process(void *pvParameters) vTaskDelete(NULL); } #else +void do_http_accept(const int sockfd) +{ + int fd = accept(sockfd, NULL,0); + if (fd == -1) { + console_printf("accept failed: %s\n", strerror(errno)); + goto BAD_ACCEPT; + }; + + // use a thread per connection. This allows for sending MAVLink messages + // via mavlink_fc_send() from connections + pthread_t thread_id; + pthread_attr_t thread_attr; + + int perrno; + if ((perrno = pthread_attr_init(&thread_attr)) != 0) { + console_printf("pthread_attr_init failed: %s\n", strerror(perrno)); + goto BAD_PTHREAD_INIT; + } + if ((perrno = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED)) != 0) { + console_printf("pthread_attr_setdetachstate failed: %s\n", strerror(perrno)); + goto BAD_PTHREAD_SETDETEACHSTATE; + } + if ((perrno = pthread_create(&thread_id, &thread_attr, web_server_connection_process, (void*)(intptr_t)fd)) != 0) { + console_printf("pthread_create failed: %s\n", strerror(perrno)); + goto BAD_PTHREAD_CREATE; + } + pthread_attr_destroy(&thread_attr); + return; + +BAD_PTHREAD_CREATE: +BAD_PTHREAD_SETDETEACHSTATE: + pthread_attr_destroy(&thread_attr); +BAD_PTHREAD_INIT: + close(fd); +BAD_ACCEPT: + return; +} /* main select loop */ @@ -525,21 +562,7 @@ static void select_loop(int http_socket_fd, int udp_socket_fd) // check for new incoming tcp connection if (http_socket_fd != -1 && FD_ISSET(http_socket_fd, &fds)) { - int fd = accept(http_socket_fd, NULL,0); - if (fd == -1) { - fprintf(stderr, "accept failed: %s\n", strerror(errno)); - continue; - }; - - // use a thread per connection. This allows for sending MAVLink messages - // via mavlink_fc_send() from connections - pthread_t thread_id; - pthread_attr_t thread_attr; - - pthread_attr_init(&thread_attr); - pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); - pthread_create(&thread_id, &thread_attr, web_server_connection_process, (void*)(intptr_t)fd); - pthread_attr_destroy(&thread_attr); + do_http_accept(http_socket_fd); } // check for incoming UDP packet (broadcast) From 62e75f064d6ac97e1e91702c321dba2b93a50851 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Thu, 31 Aug 2017 14:44:19 +1000 Subject: [PATCH 065/124] files: filesystem.html: option to start in a specific directory --- files/filesystem.html | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/files/filesystem.html b/files/filesystem.html index 1c43c26..96ecbee 100644 --- a/files/filesystem.html +++ b/files/filesystem.html @@ -37,6 +37,26 @@

    Index of /

    var current_directory = "/"; var file_list = []; + // from https://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript + function decode_params() { + var match; + var pl = /\+/g; // Regex for replacing addition symbol with a space + var search = /([^&=]+)=?([^&]*)/g; + var decode = function (s) { return decodeURIComponent(s.replace(pl, " ")); }; + var query = window.location.search.substring(1); + + urlParams = {}; + while (match = search.exec(query)) { + urlParams[decode(match[1])] = decode(match[2]); + } + return urlParams + } + + params = decode_params() + if (params["start_directory"]) { + current_directory = params["start_directory"] + } + function fill_directory(json) { var table = document.getElementById("directory_table"); From de652bf4fbfca86650428adbb60e56dccefdea51 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Thu, 7 Sep 2017 16:21:19 +1000 Subject: [PATCH 066/124] linux: use clock_gettime to reliably get boot time --- linux/util_linux.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/linux/util_linux.c b/linux/util_linux.c index 4f3e4b1..b1a3c95 100644 --- a/linux/util_linux.c +++ b/linux/util_linux.c @@ -39,13 +39,11 @@ long long get_sys_seconds_boot() // get number of milliseconds since boot uint32_t get_time_boot_ms() { - if (!system_time.initialised) { - gettimeofday(&system_time.tv,NULL); - system_time.initialised = true; - } - struct timeval tv; - gettimeofday(&tv,NULL); - return (tv.tv_sec - system_time.tv.tv_sec) * 1000U + (tv.tv_usec - system_time.tv.tv_usec) / 1000U; + struct timespec elapsed_from_boot; + + clock_gettime(CLOCK_BOOTTIME, &elapsed_from_boot); + + return elapsed_from_boot.tv_sec*1000 + elapsed_from_boot.tv_nsec/1000000; } void mdelay(uint32_t ms) From 06ce9fc07376e80f3dbbe217c77d06eb1713782e Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 14 Jun 2017 20:47:41 +1000 Subject: [PATCH 067/124] linux: invoke shutdown(1) for __reboot --- linux/util_linux.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/linux/util_linux.c b/linux/util_linux.c index b1a3c95..80ca87f 100644 --- a/linux/util_linux.c +++ b/linux/util_linux.c @@ -68,6 +68,8 @@ void __reboot(void) #if __APPLE__ printf("reboot OSX implemented, but disabled for now.\n"); //reboot(0); + #elif __linux__ + system("/sbin/shutdown -t now -r"); #else printf("reboot not implemented\n"); #endif From c415f396a2977c02515292acd21dd783eb5dc389 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 14 Jun 2017 10:26:47 +1000 Subject: [PATCH 068/124] posix: add disk_info function --- Makefile | 2 +- functions.c | 7 +++++++ posix/functions.c | 42 ++++++++++++++++++++++++++++++++++++++++++ posix/functions.h | 8 ++++++++ 4 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 posix/functions.c create mode 100644 posix/functions.h diff --git a/Makefile b/Makefile index 6b097e3..310be85 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ CC=gcc CFLAGS=-Wall -g -Werror -std=gnu99 -SRC = $(wildcard *.c) $(wildcard lib/*.c) $(wildcard linux/*.c) +SRC = $(wildcard *.c) $(wildcard lib/*.c) $(wildcard linux/*.c) $(wildcard posix/*.c) OBJ = $(SRC:%.c=%.o) LIBS = -ltalloc -lpthread diff --git a/functions.c b/functions.c index deb718e..7ce071f 100644 --- a/functions.c +++ b/functions.c @@ -9,6 +9,10 @@ #include "mavlink_core.h" #include "cgi.h" +#ifdef _POSIX_VERSION +#include "posix/functions.h" +#endif + #ifdef SYSTEM_FREERTOS #include "../mavlink_wifi.h" #include "video_main.h" @@ -1027,6 +1031,9 @@ void functions_init(struct template_state *tmpl) tmpl->put(tmpl, "nvram_set_value", "", nvram_set_value); tmpl->put(tmpl, "get_ssid", "", get_ssid); #endif // SYSTEM_FREERTOS +#ifdef _POSIX_VERSION + posix_functions_init(tmpl); +#endif tmpl->put(tmpl, "format_storage", "", format_storage); tmpl->put(tmpl, "factory_reset", "", factory_reset); tmpl->put(tmpl, "reboot_companion", "", reboot_companion); diff --git a/posix/functions.c b/posix/functions.c new file mode 100644 index 0000000..f862a51 --- /dev/null +++ b/posix/functions.c @@ -0,0 +1,42 @@ +#include "../includes.h" +#include "../template.h" +#include "functions.h" + +#include + +static void sock_send_diskinfo(struct sock_buf *sock, const char *label, unsigned serial, unsigned total_clusters, unsigned free_clusters, unsigned cluster_size) +{ + sock_printf(sock, + "{" + "\"label\" : \"%s\", " + "\"serial\" : %u, " + "\"total_clusters\" : %u, " + "\"free_clusters\" : %u, " + "\"cluster_size\" : %u" + "}", + label, serial, total_clusters, free_clusters, cluster_size*512); +} + +static void disk_info(struct template_state *tmpl, const char *name, const char *value, int argc, char **argv) +{ + unsigned long free_clusters = 0, total_clusters = 0, cluster_size = 0; + const char label[] = "/"; + + /* Get volume information and free clusters of root filesystem */ + struct statvfs buf; + if (statvfs("/", &buf) != -1) { + total_clusters = buf.f_blocks; + free_clusters = buf.f_bfree; + cluster_size = buf.f_bsize / 512; + } + + const unsigned serial = 0; + + sock_send_diskinfo(tmpl->sock, label, serial, total_clusters, free_clusters, cluster_size); +} + + +void posix_functions_init(struct template_state *tmpl) +{ + tmpl->put(tmpl, "disk_info", "", disk_info); +} diff --git a/posix/functions.h b/posix/functions.h new file mode 100644 index 0000000..bb7d28c --- /dev/null +++ b/posix/functions.h @@ -0,0 +1,8 @@ +/* + provide server side functions in C + */ + +#include "../template.h" +#include "../includes.h" + +void posix_functions_init(struct template_state *tmpl); From d6bf3016417d5c66066a36956607cfa915ccfd82 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 14 Jun 2017 11:38:49 +1000 Subject: [PATCH 069/124] posix: add file_listdir --- posix/functions.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/posix/functions.c b/posix/functions.c index f862a51..07b000e 100644 --- a/posix/functions.c +++ b/posix/functions.c @@ -4,6 +4,9 @@ #include +#include +#include + static void sock_send_diskinfo(struct sock_buf *sock, const char *label, unsigned serial, unsigned total_clusters, unsigned free_clusters, unsigned cluster_size) { sock_printf(sock, @@ -36,7 +39,74 @@ static void disk_info(struct template_state *tmpl, const char *name, const char } +static void sock_send_dirent(struct sock_buf *sock, bool first, int type, const char *name, unsigned year, unsigned month, unsigned day, unsigned hour, unsigned minute, unsigned second, unsigned size) +{ + if (!first) { + sock_printf(sock, "%s", ",\n"); + } + sock_printf(sock, "{" + "\"type\" : %u, " + "\"name\" : \"%s\", " + "\"date\" : \"%04u-%02u-%02u %02u:%02u:%02u\", " + "\"size\" : %u " + "}", + type, name, year, month, day, hour, minute, second, size); +} + +static void file_listdir(struct template_state *tmpl, const char *name, const char *value, int argc, char **argv) +{ + if (argc < 1) { + return; + } + const char *dirpath = argv[0]; + + DIR *dh = opendir(dirpath); + if (dh == NULL) { + console_printf("Failed to open directory %s\n", dirpath); + return; + } + + sock_printf(tmpl->sock, "[ "); + + bool first = true; + struct dirent *result; + while ((result = readdir(dh)) != NULL) { + if (strcmp(result->d_name, ".") == 0) { + continue; + } + + struct stat buf; + char filepath[PATH_MAX] = {}; + snprintf(filepath, sizeof(filepath), "%s/%s", dirpath, result->d_name); + if (stat(filepath, &buf) == -1) { + continue; + } + + struct tm t; + if (localtime_r(&buf.st_mtim.tv_sec, &t) == NULL) { + continue; + } + + sock_send_dirent(tmpl->sock, + first, + (result->d_type==DT_DIR) ? 1 :0, + result->d_name, + t.tm_year+1900, + t.tm_mon+1, + t.tm_mday, + t.tm_hour, + t.tm_min, + t.tm_sec, + buf.st_size); + first = false; + } + sock_printf(tmpl->sock, "]"); + closedir(dh); +} + + void posix_functions_init(struct template_state *tmpl) { + tmpl->put(tmpl, "file_listdir", "", file_listdir); tmpl->put(tmpl, "disk_info", "", disk_info); } From 61d0a86c8fce7c148a5a2f423bd0e8a1cc974bc7 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 1 Sep 2017 13:55:29 +1000 Subject: [PATCH 070/124] posix: download_filesystem support --- cgi.c | 8 ++++--- posix/functions.c | 54 +++++++++++++++++++++++++++++++++++++++++++++-- posix/functions.h | 1 + 3 files changed, 58 insertions(+), 5 deletions(-) diff --git a/cgi.c b/cgi.c index 9d3b079..daf5652 100644 --- a/cgi.c +++ b/cgi.c @@ -21,6 +21,10 @@ #include "includes.h" #include +#ifdef _POSIX_VERSION +#include "posix/functions.h" +#endif + #define CONTENT_DISPOSITION "Content-Disposition:" #define CONTENT_TYPE "Content-Type:" #define MULTIPART_FORM_DATA "multipart/form-data" @@ -589,13 +593,11 @@ static void download(struct cgi_state *cgi, const char *path) mtype = get_mime_type(path); -#ifdef SYSTEM_FREERTOS if (strncmp(path, "fs/", 3) == 0) { download_filesystem(cgi, path); return; } -#endif - + size_t size = 0; const char *contents = get_embedded_file(path, &size); if (!contents) { diff --git a/posix/functions.c b/posix/functions.c index 07b000e..84a4875 100644 --- a/posix/functions.c +++ b/posix/functions.c @@ -2,10 +2,15 @@ #include "../template.h" #include "functions.h" +#include +#include +#include +#include #include - #include -#include +#include +#include + static void sock_send_diskinfo(struct sock_buf *sock, const char *label, unsigned serial, unsigned total_clusters, unsigned free_clusters, unsigned cluster_size) { @@ -104,6 +109,51 @@ static void file_listdir(struct template_state *tmpl, const char *name, const ch closedir(dh); } +void download_filesystem(struct cgi_state *cgi, const char *fs_path) +{ + const char *path = fs_path+2; + + struct stat stats; + if (stat(path, &stats) == -1) { + cgi->http_error(cgi, "404 Bad File", "", "file not found"); + return; + } + + cgi->content_length = stats.st_size; + const int fd = open(path, O_RDONLY); + if(fd == -1) { + cgi->http_error(cgi, "500 Open failed", "", strerror(errno)); + return; + } + cgi->http_header(cgi, fs_path); + char buf[2048]; + do { + const ssize_t read_count = read(fd, buf, sizeof(buf)); + if (read_count == -1) { + console_printf("Read failure: %s", strerror(errno)); + return; + } + if (read_count == 0) { + // EOF + break; + } + ssize_t to_write = read_count; + while (to_write > 0) { + ssize_t write_count = sock_write(cgi->sock, buf, to_write); + if (write_count == 0) { + console_printf("EOF on write?!"); + return; + } + if (write_count == -1) { + console_printf("Error on write: %s", strerror(errno)); + return; + } + to_write -= write_count; + } + } while (1); + + close(fd); +} void posix_functions_init(struct template_state *tmpl) { diff --git a/posix/functions.h b/posix/functions.h index bb7d28c..38b4240 100644 --- a/posix/functions.h +++ b/posix/functions.h @@ -6,3 +6,4 @@ #include "../includes.h" void posix_functions_init(struct template_state *tmpl); +void download_filesystem(struct cgi_state *cgi, const char *fs_path); From 9bce46dfd2ec027846e32089bfd1b5ca67f64842 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Thu, 22 Jun 2017 16:02:21 +1000 Subject: [PATCH 071/124] linux: Get system information statistics working --- functions.c | 13 ++++++++----- linux/util_linux.c | 7 +++++++ linux/util_linux.h | 5 +++++ web_server.c | 20 +++++++++++++++++++- 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/functions.c b/functions.c index 7ce071f..c2135a6 100644 --- a/functions.c +++ b/functions.c @@ -24,6 +24,7 @@ #include "files/version.h" #include #include +#endif /* get uptime in seconds @@ -36,6 +37,7 @@ static void uptime(struct template_state *tmpl, const char *name, const char *va /* get FC mavlink packet count */ +unsigned mavlink_fc_pkt_count(); static void fc_mavlink_count(struct template_state *tmpl, const char *name, const char *value, int argc, char **argv) { sock_printf(tmpl->sock, "%u", mavlink_fc_pkt_count()); @@ -44,6 +46,8 @@ static void fc_mavlink_count(struct template_state *tmpl, const char *name, cons /* get FC mavlink baudrate */ +int uart2_get_baudrate(); + static void fc_mavlink_baudrate(struct template_state *tmpl, const char *name, const char *value, int argc, char **argv) { sock_printf(tmpl->sock, "%u", uart2_get_baudrate()); @@ -57,7 +61,6 @@ static void mem_free(struct template_state *tmpl, const char *name, const char * int mem_type = argc>0?atoi(argv[0]):1; sock_printf(tmpl->sock, "%u", xPortGetFreeHeapSize(mem_type)); } -#endif /* get upload progress @@ -1007,8 +1010,6 @@ static void nvram_set_value(struct template_state *tmpl, const char *name, const void functions_init(struct template_state *tmpl) { #ifdef SYSTEM_FREERTOS - tmpl->put(tmpl, "uptime", "", uptime); - tmpl->put(tmpl, "mem_free", "", mem_free); tmpl->put(tmpl, "snapshot", "", snapshot); tmpl->put(tmpl, "mjpgvideo", "", mjpg_video); tmpl->put(tmpl, "take_picture", "", take_picture); @@ -1022,8 +1023,6 @@ void functions_init(struct template_state *tmpl) tmpl->put(tmpl, "file_listdir", "", file_listdir); tmpl->put(tmpl, "disk_info", "", disk_info); tmpl->put(tmpl, "set_time_utc", "", set_time_utc); - tmpl->put(tmpl, "fc_mavlink_count", "", fc_mavlink_count); - tmpl->put(tmpl, "fc_mavlink_baudrate", "", fc_mavlink_baudrate); tmpl->put(tmpl, "mga_status", "", mga_status); tmpl->put(tmpl, "mga_upload", "", mga_upload); tmpl->put(tmpl, "nvram_pack_list", "", nvram_pack_list); @@ -1034,6 +1033,10 @@ void functions_init(struct template_state *tmpl) #ifdef _POSIX_VERSION posix_functions_init(tmpl); #endif + tmpl->put(tmpl, "uptime", "", uptime); + tmpl->put(tmpl, "mem_free", "", mem_free); + tmpl->put(tmpl, "fc_mavlink_count", "", fc_mavlink_count); + tmpl->put(tmpl, "fc_mavlink_baudrate", "", fc_mavlink_baudrate); tmpl->put(tmpl, "format_storage", "", format_storage); tmpl->put(tmpl, "factory_reset", "", factory_reset); tmpl->put(tmpl, "reboot_companion", "", reboot_companion); diff --git a/linux/util_linux.c b/linux/util_linux.c index 80ca87f..17b7fea 100644 --- a/linux/util_linux.c +++ b/linux/util_linux.c @@ -97,3 +97,10 @@ void *print_printf(void *ctx, const char *fmt, ...) va_end(ap); return ret; } + + + +unsigned xPortGetFreeHeapSize() +{ + return 0; +} diff --git a/linux/util_linux.h b/linux/util_linux.h index 35577d1..90ec2fd 100644 --- a/linux/util_linux.h +++ b/linux/util_linux.h @@ -25,3 +25,8 @@ void __reboot(void); // __ so we don't call the os version of this by mistake. char *print_vprintf(void *ctx, const char *fmt, va_list ap); void *print_printf(void *ctx, const char *fmt, ...); + + + +unsigned mavlink_fc_pkt_count(); +unsigned xPortGetFreeHeapSize(); diff --git a/web_server.c b/web_server.c index 868a145..7878108 100644 --- a/web_server.c +++ b/web_server.c @@ -27,6 +27,12 @@ socklen_t fc_addrlen; struct sockaddr_in udp_out_addr; socklen_t udp_out_addrlen; +unsigned baudrate = 57600; + +struct { + uint64_t packet_count_from_fc; +} stats; + #endif static int num_sockets_open; @@ -507,6 +513,17 @@ void do_http_accept(const int sockfd) BAD_ACCEPT: return; } + +int uart2_get_baudrate() +{ + return baudrate; +} + +unsigned mavlink_fc_pkt_count() +{ + return stats.packet_count_from_fc; +} + /* main select loop */ @@ -603,6 +620,7 @@ static void select_loop(int http_socket_fd, int udp_socket_fd) mavlink_status_t status; for (uint16_t i=0; i Date: Thu, 28 Sep 2017 20:51:48 +1000 Subject: [PATCH 072/124] web_server: catch SIGPIPE --- web_server.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/web_server.c b/web_server.c index 7878108..fac1242 100644 --- a/web_server.c +++ b/web_server.c @@ -351,6 +351,11 @@ static void setup_origin(const char *origin) #endif } +void sig_pipe_handler(int signum) +{ + web_debug(3, "Caught signal SIGPIPE %d\n",signum); +} + /* task for web_server */ @@ -879,6 +884,14 @@ int main(int argc, char *argv[]) exit(1); } + // summarily ignore SIGPIPE; without this, if a download is + // interrupted sock_write's write() call will kill the process + // with SIGPIPE + web_debug(4, "Ignoring sig pipe\n"); + if (signal(SIGPIPE, sig_pipe_handler) == SIG_ERR) { + console_printf("Failed to ignore SIGPIPE: %m\n"); + } + pthread_mutex_init(&lock, NULL); if (serial_port) { From 2e3c95f38b9d10b30c599c7af400da1020c6823c Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Thu, 5 Oct 2017 17:07:32 +1100 Subject: [PATCH 073/124] filesystem.html: sort by filename --- files/filesystem.html | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/files/filesystem.html b/files/filesystem.html index 96ecbee..92946f3 100644 --- a/files/filesystem.html +++ b/files/filesystem.html @@ -57,6 +57,17 @@

    Index of /

    current_directory = params["start_directory"] } + function find_insertion_point(table, name) { + // offset 1 is the table header + for (var i=1; i name) { + return i; + } + } + return 1; + } + function fill_directory(json) { var table = document.getElementById("directory_table"); @@ -92,11 +103,12 @@

    Index of /

    var total_size = 0; for (var i=0; i Date: Wed, 14 Jun 2017 10:25:49 +1000 Subject: [PATCH 074/124] files: Generalise some interface messages --- files/system.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/system.html b/files/system.html index fdac8a7..556e5a4 100644 --- a/files/system.html +++ b/files/system.html @@ -89,7 +89,7 @@

    WiFi Setup


    Reboot

    -Reboot your video board or flight controller board

    +Reboot your companion computer or flight controller board

    From 2d317585641ad94fd153b1c36d100b311ba06f89 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 18 Aug 2017 12:52:29 +1000 Subject: [PATCH 075/124] files: parameters.html: set default category to All --- files/parameters.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/parameters.html b/files/parameters.html index 38be0d1..cee801c 100644 --- a/files/parameters.html +++ b/files/parameters.html @@ -60,7 +60,7 @@ option.innerHTML = category; category_select.appendChild(option); } - category_select.value = "Actions"; + category_select.value = "All"; var param_docs = {}; var plist; From 4257006fe6334350d33c4867185f5cdbf67534e6 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 22 Sep 2017 21:19:58 +1000 Subject: [PATCH 076/124] linux: use system_time messages to set system clock --- linux/mavlink_linux.c | 45 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/linux/mavlink_linux.c b/linux/mavlink_linux.c index 217ef82..3673f02 100644 --- a/linux/mavlink_linux.c +++ b/linux/mavlink_linux.c @@ -297,6 +297,40 @@ void mavlink_message_list_json(struct sock_buf *sock) sock_printf(sock, "]"); } +enum TIME_SOURCE { + TIME_SOURCE_NONE=0, + TIME_SOURCE_FC, +}; +static uint8_t time_source = 0; + +bool mavlink_should_handle_system_time() +{ + if (time_source >= TIME_SOURCE_FC) { + return false; + } + return true; +} + +void set_system_time_utc_usec(const time_t epoch_time) +{ + if (stime(&epoch_time) == -1) { + fprintf(stderr, "Failed to set time: %s\n", strerror(errno)); + } +} + + +void mavlink_handle_system_time(const mavlink_system_time_t *m) +{ +#define FC_MIN_DATE 1494314686 + if (m->time_unix_usec > FC_MIN_DATE) { + fprintf(stderr, "Setting system time to %u (from fc)\n", + (uint32_t)m->time_unix_usec/1000000); + set_system_time_utc_usec(m->time_unix_usec/1000000); + time_source = TIME_SOURCE_FC; + } +} + + /* * handle an (as yet undecoded) mavlink message */ @@ -321,7 +355,16 @@ bool mavlink_handle_msg(const mavlink_message_t *msg) command_ack_save(&m); break; } - + + case MAVLINK_MSG_ID_SYSTEM_TIME: { + if (mavlink_should_handle_system_time()) { + mavlink_system_time_t m; + mavlink_msg_system_time_decode(msg, &m); + mavlink_handle_system_time(&m); + } + break; + } + default: break; } From 61022e2376ea66115679f302f341b9780c0c68d7 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 14 Jun 2017 19:42:48 +1000 Subject: [PATCH 077/124] APSync: linux: use nmcli for control of network interfaces posix: use nmcli for get_ssid posix: use nmcli for set_ssid APSync AP name is WiFiAP --- files/Makefile | 2 +- files/apsync/system.html | 94 ++++++++++++++++++++ files/index.html | 2 +- functions.c | 14 ++- functions.h | 13 +++ linux/functions.c | 180 +++++++++++++++++++++++++++++++++++++++ linux/functions.h | 4 + posix/functions.c | 1 + 8 files changed, 304 insertions(+), 6 deletions(-) create mode 100644 files/apsync/system.html create mode 100644 linux/functions.c create mode 100644 linux/functions.h diff --git a/files/Makefile b/files/Makefile index 010bc34..1cdbd1e 100644 --- a/files/Makefile +++ b/files/Makefile @@ -1,6 +1,6 @@ all: @echo "Generating embedded.c" - @./embed.py *.html images/*.svg */*.js */*.json */*.css */*.jpg */*.png */*.mjpg data/*.xml + @./embed.py *.html images/*.svg */*.js */*.json */*.css */*.jpg */*.png */*.mjpg data/*.xml apsync/*.html @echo "Generating manifest" @./gen_manifest.sh @echo "Generating version.h" diff --git a/files/apsync/system.html b/files/apsync/system.html new file mode 100644 index 0000000..60df5a2 --- /dev/null +++ b/files/apsync/system.html @@ -0,0 +1,94 @@ + + + + ArduPilot + + + + + + + + +

    ArduPilot

    + +

    System Control

    + +Control system setup of your vehicle +

    +

    +

    + +


    +

    WiFi Setup

    + +Configure your WiFi SSID, password, authentication type and +channel. + +

    If using WEP you need to use a 5 character password. For WPA2 your +password needs to be at least 8 characters long. Using WPA2 is +recommended.

    + +

    + WiFi Configuration + WiFi SSID:
    +
    +WiFi Password:
    + +Show password
    +Auth Type: + +WiFi Channel: + +
    +
    + + + +
    +

    Reboot

    + +Reboot your companion computer or flight controller board

    + + + + +


    +

    home + + + + diff --git a/files/index.html b/files/index.html index aa3e555..109323f 100644 --- a/files/index.html +++ b/files/index.html @@ -19,7 +19,7 @@

    ArduPilot Web Server

    • Filesystem access
    • -
    • System control
    • +
    • System control
    • Upgrade Firmware
    • System Status
    • Map View
    • diff --git a/functions.c b/functions.c index c2135a6..a00108a 100644 --- a/functions.c +++ b/functions.c @@ -12,6 +12,9 @@ #ifdef _POSIX_VERSION #include "posix/functions.h" #endif +#ifdef __linux__ +#include "linux/functions.h" +#endif #ifdef SYSTEM_FREERTOS #include "../mavlink_wifi.h" @@ -376,15 +379,13 @@ static void format_storage(struct template_state *tmpl, const char *name, const #endif } - -#ifdef SYSTEM_FREERTOS /* validate auth settings for wifi return error-string on error. Return NULL if OK */ -static const char *validate_ssid_password(const char *ssid, +const char *validate_ssid_password(const char *ssid, const char *password, - enc_auth_t auth_mode, + apweb_enc_auth_t auth_mode, int channel) { if (channel < 1 || channel > 14) { @@ -413,6 +414,8 @@ static const char *validate_ssid_password(const char *ssid, return "Invalid auth mode"; } +#ifdef SYSTEM_FREERTOS + /* set ssid and password */ @@ -1032,6 +1035,9 @@ void functions_init(struct template_state *tmpl) #endif // SYSTEM_FREERTOS #ifdef _POSIX_VERSION posix_functions_init(tmpl); +#endif +#ifdef __linux__ + linux_functions_init(tmpl); #endif tmpl->put(tmpl, "uptime", "", uptime); tmpl->put(tmpl, "mem_free", "", mem_free); diff --git a/functions.h b/functions.h index c1c44bb..e6204b9 100644 --- a/functions.h +++ b/functions.h @@ -1,5 +1,18 @@ +#pragma once /* provide server side functions in C */ void functions_init(struct template_state *tmpl); + +typedef enum { + AUTH_NONE= 0, + AUTH_WEP = 1, + AUTH_WPA = 2, + AUTH_WPA2 = 3, +} apweb_enc_auth_t ; + +const char *validate_ssid_password(const char *ssid, + const char *password, + apweb_enc_auth_t auth_mode, + int channel); diff --git a/linux/functions.c b/linux/functions.c new file mode 100644 index 0000000..721a862 --- /dev/null +++ b/linux/functions.c @@ -0,0 +1,180 @@ +#include "../includes.h" +#include "../template.h" +#include "functions.h" +#include "../functions.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +void sock_send_ssid(struct sock_buf *sock, const char *ssid, const char *pass, const unsigned channel, const unsigned mode) +{ + sock_printf(sock, "{ " + "\"ssid\": \"%s\", " + "\"password\" : \"%s\", " + "\"channel\" : %d, " + "\"authmode\" : %d " + "}", + ssid, pass, channel, mode); +} + +static void nmcli_property_string_get(struct template_state *tmpl, const char *ifname, const char *setting_property, char *ret, unsigned retlen) +{ + char cmd[300]; + char tmpfile[] = "/tmp/nmcli.XXXXXX"; + int content_fd = mkstemp(tmpfile); + if (content_fd == -1) { + sock_printf(tmpl->sock, "mkstemp failed"); + return; + } + /* TODO: do we REALLY want to link with the dbus libraries?! */ + /* note that the -s argument to nmcli is not present on Raspbian/Jessie */ + /* .... and manlfunctions on TX1's Ubuntu 16.04 */ + snprintf(cmd, sizeof(cmd), "nmcli c s %s | grep \"%s:\" | perl -pe 's/^[^ ]*[ ]*(.*)\n/$1/' >%s", ifname, setting_property, tmpfile); + if (system(cmd) == -1) { + sock_printf(tmpl->sock, "system failed"); + return; + } + memset(ret, '\0', retlen); + if (read(content_fd, ret, retlen) == -1) { + sock_printf(tmpl->sock, "read failed"); + return; + } + close(content_fd); +} + +static void nmcli_property_integer_get(struct template_state *tmpl, const char *ifname, const char *setting_property, int *ret) +{ + char text[300]; + nmcli_property_string_get(tmpl, ifname, setting_property, text, sizeof(text)); + *ret = atoi(text); +} + + +static void nmcli_property_string_set(struct template_state *tmpl, const char *ifname, const char *setting_property, const char *value) +{ + char cmd[300]; + /* TODO: do we REALLY want to link with the dbus libraries?! */ + snprintf(cmd, sizeof(cmd), "nmcli c m %s %s %s", ifname, setting_property, value); + if (system(cmd) == -1) { + sock_printf(tmpl->sock, "system failed"); + return; + } +} + +static void nmcli_property_integer_set(struct template_state *tmpl, const char *ifname, const char *setting_property, int value) +{ + char text[300]; + snprintf(text, sizeof(text), "%d", value); + nmcli_property_string_set(tmpl, ifname, setting_property, text); +} + + +/* + * work around nmcli variation on different versions of Ubuntu by + * fetching secret directly from files. Yay abusing root access. + */ +int nm_fetch_wpa_psk_secret(const char *ifname, char *password, const uint8_t passwordlen) +{ + char cmd[300]; + char tmpfile[] = "/tmp/nmcli.XXXXXX"; + int content_fd = mkstemp(tmpfile); + if (content_fd == -1) { + return -1; + } + /* TODO: do we REALLY want to link with the dbus libraries?! */ + /* note that the -s argument to nmcli is not present on Raspbian/Jessie */ + /* .... and manlfunctions on TX1's Ubuntu 16.04 */ + snprintf(cmd, sizeof(cmd), "cat /etc/NetworkManager/system-connections/%s | grep '^psk=' | cut -f 2 -d '=' | perl -pe 's/\n//'g >%s", ifname, tmpfile); + if (system(cmd) == -1) { + return -1; + } + memset(password, '\0', passwordlen); + if (read(content_fd, password, passwordlen) == -1) { + return -1; + } + close(content_fd); + return 0; +} + +#define streq(a,b) (strcmp(a,b) == 0) + +static const char *ifname = "WiFiAP"; + +/* + get ssid and password + */ +static const char *prop_ssid = "802-11-wireless.ssid"; +static const char *prop_sectype = "802-11-wireless-security.key-mgmt"; +static const char *prop_channel = "802-11-wireless.channel"; +static const char *prop_key = "802-11-wireless-security.psk"; +static void get_ssid(struct template_state *tmpl, const char *name, const char *value, int argc, char **argv) +{ + char ssid[50]="", pass[50], security_type[50]=""; + int mode=0, channel=0; + + nmcli_property_string_get(tmpl, ifname, prop_ssid, ssid, sizeof(ssid)); + nmcli_property_string_get(tmpl, ifname, prop_sectype, security_type, sizeof(security_type)); + nmcli_property_integer_get(tmpl, ifname, prop_channel, &channel); + + if (streq(security_type, "wpa-psk")) { + // nmcli_property_string_get(tmpl, ifname, prop_key, pass, sizeof(pass)); + if (nm_fetch_wpa_psk_secret(ifname, pass, sizeof(pass)) == -1) { + pass[0] = '\0'; + } + mode = AUTH_WPA2; + } else { + mode = -1; + } + + sock_send_ssid(tmpl->sock, ssid, pass, channel, mode); +} + + +/* + set ssid and password + */ +static void set_ssid(struct template_state *tmpl, const char *name, const char *value, int argc, char **argv) +{ + if (argc < 4) { + sock_printf(tmpl->sock, "invalid call\n"); + return; + } + const char *ssid = argv[0]; + const char *password = argv[1]; + const char *authtype = argv[2]; + const char *channel = argv[3]; + if (!ssid || !password || !authtype || !channel) { + sock_printf(tmpl->sock, "invalid SSID or password\n"); + } + + int auth_mode = atoi(authtype); + int ap_channel = atoi(channel); + + const char *ret = validate_ssid_password(ssid, password, auth_mode, ap_channel); + if (ret) { + // invalid input + sock_printf(tmpl->sock, "%s", ret); + return; + } + + console_printf("Setting SSID='%s' password='%s' authtype=%s channel=%u\n", ssid, password, authtype, ap_channel); + + nmcli_property_integer_set(tmpl, ifname, prop_sectype, auth_mode); + nmcli_property_integer_set(tmpl, ifname, prop_channel, ap_channel); + nmcli_property_string_set(tmpl, ifname, prop_ssid, ssid); + nmcli_property_string_set(tmpl, ifname, prop_key, password); + + sock_printf(tmpl->sock, "Set SSID and password"); +} + +void linux_functions_init(struct template_state *tmpl) +{ + tmpl->put(tmpl, "get_ssid", "", get_ssid); + tmpl->put(tmpl, "set_ssid", "", set_ssid); +} diff --git a/linux/functions.h b/linux/functions.h new file mode 100644 index 0000000..9ebbafd --- /dev/null +++ b/linux/functions.h @@ -0,0 +1,4 @@ +#include "../template.h" +#include "../includes.h" + +void linux_functions_init(struct template_state *tmpl); diff --git a/posix/functions.c b/posix/functions.c index 84a4875..bb017b7 100644 --- a/posix/functions.c +++ b/posix/functions.c @@ -1,6 +1,7 @@ #include "../includes.h" #include "../template.h" #include "functions.h" +#include "../functions.h" #include #include From 7cefe58db7c8079984048b84a84700d4785ee478 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 1 Sep 2017 14:58:19 +1000 Subject: [PATCH 078/124] APSync: system.html: 0 is a valid channel (use any) --- files/apsync/system.html | 1 + 1 file changed, 1 insertion(+) diff --git a/files/apsync/system.html b/files/apsync/system.html index 60df5a2..05ccc12 100644 --- a/files/apsync/system.html +++ b/files/apsync/system.html @@ -45,6 +45,7 @@

      WiFi Setup

      WiFi Channel:
VariableValue
Status
Channels
Chan1
Chan2
+ + + + +
VariableValue
Uptime
FC MAVLink count
FC MAVLink baudrate
+ +

Flight Board Status

+ + + + + +
Mode
Uptime
Voltage
+ + +
+

Attitude

+ + + + + +
+ + + + + + +
VariableValue
Roll
Pitch
Yaw
+ +

IMU Status

+ + + + + + + + + + + + + + + + + + +
SensorXYZ
Accelerometer
Gyroscope
Magnetometer
+ +
+ Accelerometers (X, Y, Z)
+

+ Gyro (roll, pitch, yaw)
+

+ Magnetometer (X, Y, Z)
+

+

+
+ + +
+ + + + + +
+ + + + + +
VariableValue
Pressure Absolute
Pressure Relative
Temperature
+ +
+ Pressure
+

+ Temperature
+

+

+ +
+ +
+ + + + +
+ + + + + + + +
VariableValue
FixType
Numsats
Latitude (GPS)
Longitude (GPS)
Altitude (AMSL)
+
+
+ +
+ + + + + + + + + + + +
VariableValue
Flags
Latitude
Longitude
Altitude
Velocity Variance
Position Variance (H)
Position Variance (V)
Compass Variance
+
+ +
+ + + + + +
+ + + + + + + + + + +
VariableValue
Channels
Chan1
Chan2
Chan3
Chan4
Chan5
Chan6
Chan7
+
+ Stick input (chan1, chan2, chan3, chan4)
+

+

+ +
+ +
+ snapshot +

+

+ JPG Frames + MJPG Stream
+
+ + + + +
+ +
+ +

Motor Testing

+ + +Select motor to test, along with test power level (as a percentage) and test time in seconds. + +

+ + + + + +

+ Test Power + + +
Test Time (s) + + +

+ + Refresh rate:  + + +
+

home + + + + + + diff --git a/files/index.html b/files/index.html index 109323f..68d2695 100644 --- a/files/index.html +++ b/files/index.html @@ -20,12 +20,10 @@

ArduPilot Web Server

From c1cf78ec51c3417ed2692fd0db98877a5ec80ab3 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 1 Sep 2017 18:15:57 +1000 Subject: [PATCH 081/124] APSync: create custom calibration page without one-touch calibration --- files/apsync/calibration.html | 331 ++++++++++++++++++++++++++++++++++ files/index.html | 3 +- 2 files changed, 332 insertions(+), 2 deletions(-) create mode 100644 files/apsync/calibration.html diff --git a/files/apsync/calibration.html b/files/apsync/calibration.html new file mode 100644 index 0000000..f1cf313 --- /dev/null +++ b/files/apsync/calibration.html @@ -0,0 +1,331 @@ + + + + ArduPilot + + + + + + + + + + + + + +

ArduPilot

+ +
+ + +
+ +
+ +
+

Six-Axis Accelerometer Calibration

+ +A six axis accelerometer calibration involves you placing your vehicle +in each of 6 orientations in turn, as you are guided by the prompts +below. This type of calibration is good if you will be doing 3D +flying, or if you find that you get poor results with a simple +accelerometer calibration. + +

After a six-axis calibration you will need to power cycle your vehicle + +

+ +
+


+

+


+ +


+ +

Sensor State

+ + + + + +
+ + + + + +
VariableValue
Roll
Pitch
+ + + + + + + + + + + + + + + + + + +
NameXYZ
Sensor
Offsets
Scaling
+ +
+ Accelerometers (X, Y, Z)
+

+

+
+ +
+ +

Magnetometer calibration

+ +To calibrate the magnetometer you will need to move to a location well +away from all metal. Then press the button below to start +calibration. Once started you will need to rotate the vehicle about +all axes. + +

A progress bar will display to show how far you are through the calibration. + +

After a magnetometer calibration you will need to power cycle your vehicle + +

+ +
+
+

Calibration progress:
+

+
+
+
+
+ +


+ +


+ +

Sensor State

+ + + + +
+ + + + + + +
VariableValue
Roll
Pitch
Yaw
+ + + + + + + + +
SensorXYZ
Magnetometer
+ +
+ Magnetometer (X, Y, Z)
+

+

+
+ + +
+

home + + + + + + diff --git a/files/index.html b/files/index.html index 68d2695..e157a27 100644 --- a/files/index.html +++ b/files/index.html @@ -21,8 +21,7 @@

ArduPilot Web Server

  • Filesystem access
  • System control
  • System Status
  • -
  • Map View
  • -
  • Calibration
  • +
  • Calibration
  • Flight Parameters
  • From 86b9bd434c4b3a2c7f8dedecd397eba1c9ad7a1c Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Fri, 18 Aug 2017 12:21:38 +1000 Subject: [PATCH 082/124] APSync: Use local files for apsync and apsync.local hostnames --- files/js/config.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/files/js/config.js b/files/js/config.js index 8a59c03..2e50568 100644 --- a/files/js/config.js +++ b/files/js/config.js @@ -11,7 +11,8 @@ var mga_data_url = "http://gps.tridgell.net/data/mga-offline.ubx"; try { var hosta = window.location.hostname.split('.') if ((hosta[0] == 192 && hosta[1] == 168) || hosta[0] == 172 || hosta[0] == 10 || hosta[0] == 127 || - window.location.hostname == "tridgell.net") { + window.location.hostname == "apsync" || + window.location.hostname == "apsync.local") { drone_url = ''; } } catch(e) { From ba5d3313c837b1318a4e8fd54a7db27074c169de Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Thu, 31 Aug 2017 14:44:56 +1000 Subject: [PATCH 083/124] APSync: Add direct link to download dataflash logs --- files/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/files/index.html b/files/index.html index e157a27..6e9757d 100644 --- a/files/index.html +++ b/files/index.html @@ -18,6 +18,7 @@

    ArduPilot Web Server

    Welcome to the ArduPilot Web Interface!

      +
    • Download DataFlash Logs
    • Filesystem access
    • System control
    • System Status
    • From ea1850a55e80e5e055c6393fc4e7e0366e004c01 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Mon, 25 Sep 2017 14:21:01 +1000 Subject: [PATCH 084/124] linux: use clock_settime in place of stime for setting system time --- linux/mavlink_linux.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/linux/mavlink_linux.c b/linux/mavlink_linux.c index 3673f02..d6ea17c 100644 --- a/linux/mavlink_linux.c +++ b/linux/mavlink_linux.c @@ -3,6 +3,7 @@ */ #include "../includes.h" +#include /* list of packet types received @@ -311,9 +312,9 @@ bool mavlink_should_handle_system_time() return true; } -void set_system_time_utc_usec(const time_t epoch_time) +void set_system_time_utc_usec(const struct timespec *ts) { - if (stime(&epoch_time) == -1) { + if (clock_settime(CLOCK_REALTIME, ts) == -1) { fprintf(stderr, "Failed to set time: %s\n", strerror(errno)); } } @@ -323,9 +324,13 @@ void mavlink_handle_system_time(const mavlink_system_time_t *m) { #define FC_MIN_DATE 1494314686 if (m->time_unix_usec > FC_MIN_DATE) { - fprintf(stderr, "Setting system time to %u (from fc)\n", - (uint32_t)m->time_unix_usec/1000000); - set_system_time_utc_usec(m->time_unix_usec/1000000); + struct timespec ts = { + m->time_unix_usec/1000000, + (m->time_unix_usec%1000000) * 1000 + }; + fprintf(stderr, "Setting system time to %u.%u (from fc)\n", + (uint32_t)ts.tv_sec, (uint32_t)ts.tv_nsec); + set_system_time_utc_usec(&ts); time_source = TIME_SOURCE_FC; } } From d123f2dfc3e3ed6957896c56fc554381e1885be0 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Wed, 1 Nov 2017 16:21:46 +1100 Subject: [PATCH 085/124] APSync: trusted IP address is 10.0.1.128 --- web_server.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_server.c b/web_server.c index fac1242..2eccec5 100644 --- a/web_server.c +++ b/web_server.c @@ -273,7 +273,7 @@ static void connection_process(struct connection_state *c) */ static bool check_origin(const char *origin) { - if (strcmp(origin, "http://192.168.99.1") == 0) { + if (strcmp(origin, "http://10.0.1.128") == 0) { // always accept return true; } From c1a1d1e566a82aeddc24a3e75b8a43566a837e6a Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Thu, 2 Nov 2017 14:15:04 +1100 Subject: [PATCH 086/124] mavlink.js: ensure stream rate matches refresh rate --- files/js/mavlink.js | 90 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/files/js/mavlink.js b/files/js/mavlink.js index e9cd65e..d7a8ed5 100644 --- a/files/js/mavlink.js +++ b/files/js/mavlink.js @@ -41,6 +41,45 @@ for (var r in scaling) { scaling_re[r] = new RegExp(r); } +// from common.xml: +// var MAV_DATA_STREAM_ALL = 0; +const stream_ids = { + MAV_DATA_STREAM_RAW_SENSORS : 1, + MAV_DATA_STREAM_EXTENDED_STATUS : 2, + MAV_DATA_STREAM_RC_CHANNELS : 3, + MAV_DATA_STREAM_RAW_CONTROLLER : 4, + MAV_DATA_STREAM_POSITION : 6, + MAV_DATA_STREAM_EXTRA1 : 10, + MAV_DATA_STREAM_EXTRA2 : 11, + MAV_DATA_STREAM_EXTRA3 : 12 +} + +const stream_for_msg = { + 'RAW_IMU' : "MAV_DATA_STREAM_RAW_SENSORS", + 'GPS_RAW_INT' : "MAV_DATA_STREAM_EXTENDED_STATUS", + 'GLOBAL_POSITION_INT' : "MAV_DATA_STREAM_POSITION", + 'ATTITUDE' : "MAV_DATA_STREAM_EXTRA1", + 'SCALED_PRESSURE' : "MAV_DATA_STREAM_RAW_SENSORS", + 'GPS2_RAW' : "MAV_DATA_STREAM_EXTENDED_STATUS", + 'SYS_STATUS' : "MAV_DATA_STREAM_EXTENDED_STATUS" +} +const not_stream_msg = { + 'STATUSTEXT' : 1 +} + +const param_for_stream = { + MAV_DATA_STREAM_RAW_SENSORS : 'RAW_SENS', + MAV_DATA_STREAM_EXTENDED_STATUS : 'EXT_STAT', + MAV_DATA_STREAM_RC_CHANNELS : 'RC_CHAN', + MAV_DATA_STREAM_RAW_CONTROLLER : 'RAW_CTRL', + MAV_DATA_STREAM_POSITION : 'POSITION', + MAV_DATA_STREAM_EXTRA1 : 'EXTRA1', + MAV_DATA_STREAM_EXTRA2 : 'EXTRA2', + MAV_DATA_STREAM_EXTRA3 : 'EXTRA3' +} + +const sr_prefix = "SR2_"; + // return scaled variable function scale_variable(varname, value) { var scale = 1.0; @@ -60,6 +99,15 @@ function scale_variable(varname, value) { } var mavlink_msg_types = [] +var mavlink_stream_params = [] + +var sr_parameters = {} +function fill_sr_parameters(plist) { + plist.forEach(function bob(entry) { + sr_parameters[entry.name] = entry.value; + }); + return true; +} /* fill in all divs of form MAVLINK:MSGNAME:field at refresh_ms() rate @@ -86,7 +134,49 @@ function fill_mavlink_ids(options={}) { mavlink_msg_types.push(msg_name); } } + // determine which streams are required to get the messages we want: + var mavlink_streams = {} + for (var msg_name in stream_for_msg) { + if (!(msg_name in stream_for_msg)) { + if (!(msg_name in not_stream_msg)) { + console.log("No mapping from " + msg_name + "to stream"); + } + continue + } + mavlink_streams[stream_for_msg[msg_name]] = 1; + } + // determine which parameters need to be set to get the messages we want: + var params = {} + for (var stream in mavlink_streams) { + if (param_for_stream[stream] == "undefined") { + console.log("No mapping from stream " + stream + " to param"); + continue + } + params[param_for_stream[stream]] = 1; + } + mavlink_stream_params = Object.keys(params); +// console.log("stream_params: " + mavlink_stream_params); + + // start updating our parameter values + ajax_json_poll(drone_url + "/ajax/command.json?command1=get_param_list(" + sr_prefix + ")", fill_sr_parameters, 1000); } + // check refresh rates: + var params_to_set = {}; + mavlink_stream_params.forEach(function x(param) { + var required_rate = 1000/refresh_ms(); + var sr_key = sr_prefix + param; + if (sr_parameters[sr_key] == "undefined") { + return; + } + var current_rate = sr_parameters[sr_key]; +// console.log("current=" + current_rate + " required=" + required_rate); + if (current_rate < required_rate) { +// console.log("update required"); + params_to_set[sr_key] = required_rate; + } + }); + mavlink_set_params(params_to_set); + var xhr = createCORSRequest("POST", drone_url + "/ajax/command.json"); var form = new FormData(); form.append('command1', 'mavlink_message(' + mavlink_msg_types.join() + ')'); From 3e4817c3421697b6a7193e8bac54823af5306681 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Thu, 2 Nov 2017 14:16:34 +1100 Subject: [PATCH 087/124] Add support for a configuration file --- posix/config_variables.c | 262 +++++++++++++++++++++++++++++++++++++++ posix/config_variables.h | 8 ++ web_server.c | 4 + 3 files changed, 274 insertions(+) create mode 100644 posix/config_variables.c create mode 100644 posix/config_variables.h diff --git a/posix/config_variables.c b/posix/config_variables.c new file mode 100644 index 0000000..70951d0 --- /dev/null +++ b/posix/config_variables.c @@ -0,0 +1,262 @@ +#include "config_variables.h" + +#include +#include +#include +#include +#include +#include +#include + +char *config; +off_t config_size; +uint32_t config_file_modtime = 0; +const char *config_filename = "config.txt"; + +bool lock_initted; +static pthread_mutex_t lock; + +bool lock_config() +{ + if (!lock_initted) { + pthread_mutex_init(&lock, NULL); + lock_initted = 1; + } + return pthread_mutex_lock(&lock); +} + +bool unlock_config() +{ + return pthread_mutex_unlock(&lock); +} + +bool read_config_file() +{ + int fd = open(config_filename, O_RDONLY); + if (fd == -1) { + goto OUT_BAD; + } + struct stat _stat; + if (fstat(fd, &_stat) == -1) { + goto OUT_BAD_FD; + } + const uint32_t modtime = _stat.st_atime; + if (modtime == config_file_modtime) { + close(fd); + return true; + } + config_size = _stat.st_size; + char *new_config = realloc(config, config_size+1); + if (new_config == NULL) { + goto OUT_BAD_FD; + } + config = new_config; + memset(config, '\0', config_size+1); + off_t total_read = 0; + uint8_t max_loop_count = 10; + while (total_read != config_size && max_loop_count--) { + const off_t this_read = read(fd, &config[total_read], config_size-total_read); + if (this_read == -1) { + goto OUT_BAD_FD; + } + total_read += this_read; + } + if (total_read != config_size) { + goto OUT_BAD_FD; + } + config_file_modtime = modtime; + return true; +OUT_BAD_FD: + close(fd); +OUT_BAD: + free(config); + config_size = 0; + return false; +} + +bool config_string_get(const char *category, const char *name, char *ret, uint8_t retlen) +{ + char fullname[50]; + snprintf(fullname, 50, "%s.%s=", category, name); + lock_config(); + if (!read_config_file()) { + goto OUT_DO_RELEASE; + } + const char *namepos = strstr(config, fullname); + if (namepos == NULL) { + goto OUT_DO_RELEASE; + } + const char *terminator = strstr(namepos, "\n"); + if (terminator == NULL) { + goto OUT_DO_RELEASE; + } + const int16_t len = terminator - namepos - strlen(fullname); + const char *value = namepos+strlen(fullname); + memcpy(ret, value, (len <= retlen) ? len : retlen); +OUT_DO_RELEASE: + unlock_config(); + return true; +} + +bool config_integer_get(const char *category, const char *name, int *ret) +{ + char value[50] = {}; + if (!config_string_get(category, name, value, 50)) { + return false; + } + *ret = atoi(value); + fprintf(stderr, "value: (%s) (%d)\n", value, *ret); + return true; +} + +bool config_string_set(const char *category, const char *name, char *value) +{ + fprintf(stderr, "old config string: (%s) len=%lu\n", config, config_size); + char fullname[50]; + snprintf(fullname, 50, "%s.%s=", category, name); + lock_config(); + if (!read_config_file()) { + return false; + } + const char *namepos = strstr(config, fullname); + if (namepos == NULL) { + // append + const off_t new_config_size = config_size + strlen(fullname) + strlen(value) + 1; + char *new_config = realloc(config, new_config_size+1); + if (new_config == NULL) { + goto OUT_DO_RELEASE; + } + config = new_config; + config[new_config_size] = '\0'; + strcpy(&config[config_size], fullname); + strcpy(&config[config_size+strlen(fullname)], value); + config[config_size+strlen(fullname)+strlen(value)] = '\n'; + config_size = new_config_size; + } else { + // found existing entry + const char *terminator = strstr(namepos, "\n"); + if (terminator == NULL) { + goto OUT_DO_RELEASE; + } + const int name_offset = namepos-config; + const int value_offset = name_offset + strlen(fullname); + const off_t old_value_len = terminator - namepos - strlen(fullname); + const int delta = old_value_len - strlen(value); + const off_t new_config_size = config_size - old_value_len + strlen(value); + if (new_config_size > config_size) { + // make buffer bigger, move stuff to end of buffer using memmove + char *new_config = realloc(config, new_config_size+1); + if (new_config == NULL) { + goto OUT_DO_RELEASE; + } + config = new_config; + config[new_config_size] = '\0'; + memmove(&config[value_offset+strlen(value)], + &config[value_offset+old_value_len], + config_size-value_offset); + } else if (new_config_size < config_size) { + // move stuff to beginning of buffer using memmove, make + // buffer smaller + memmove(&config[value_offset], + &config[value_offset+delta], + config_size-value_offset-delta); + char *new_config = realloc(config, new_config_size+1); + if (new_config == NULL) { + goto OUT_DO_RELEASE; + } + config = new_config; + config[new_config_size] = '\0'; + } + memcpy(&config[name_offset+strlen(fullname)], value, strlen(value)); + config_size = new_config_size; + } + fprintf(stderr, "new config string: (%s) len=%lu\n", config, config_size); + unlock_config(); + return true; +OUT_DO_RELEASE: + unlock_config(); + return false; +} + +bool config_integer_set(const char *category, const char *name, int value) +{ + char value_string[50] = {}; + snprintf(value_string, 50, "%d", value); + return config_string_set(category, name, value_string); +} + + + +void test_config() +{ + int bob; + if (!config_integer_get("FOO", "BAR", &bob)) { + fprintf(stderr, "Failed to get FOO.BAR\n"); + abort(); + } + if (bob != 37) { + abort(); + } + fprintf(stderr, "Got %d\n", bob); + + if (!config_integer_set("FOO", "BAR", 5)) { + fprintf(stderr, "Failed to set FOO.BAR\n"); + abort(); + } + if (!config_integer_get("FOO", "BAR", &bob)) { + fprintf(stderr, "Failed to get FOO.BAR\n"); + abort(); + } + if (bob != 5) { + fprintf(stderr, "bob=%d\n", bob); + abort(); + } + + if (!config_integer_set("FOO", "BAR", 713)) { + fprintf(stderr, "Failed to set FOO.BAR\n"); + abort(); + } + if (!config_integer_get("FOO", "BAR", &bob)) { + fprintf(stderr, "Failed to get FOO.BAR\n"); + abort(); + } + if (bob != 713) { + fprintf(stderr, "bob=%d\n", bob); + abort(); + } + + if (!config_integer_set("FOO", "BAR", 123)) { + fprintf(stderr, "Failed to set FOO.BAR\n"); + abort(); + } + if (!config_integer_get("FOO", "BAR", &bob)) { + fprintf(stderr, "Failed to get FOO.BAR\n"); + abort(); + } + if (bob != 123) { + fprintf(stderr, "bob=%d\n", bob); + abort(); + } + + if (!config_integer_set("FOO", "BAZ", 54)) { + fprintf(stderr, "Failed to set FOO.BAR\n"); + abort(); + } + if (!config_integer_get("FOO", "BAZ", &bob)) { + fprintf(stderr, "Failed to get FOO.BAZ\n"); + abort(); + } + if (bob != 54) { + fprintf(stderr, "bob=%d\n", bob); + abort(); + } + if (!config_integer_get("FOO", "BAR", &bob)) { + fprintf(stderr, "Failed to get FOO.BAR\n"); + abort(); + } + if (bob != 123) { + fprintf(stderr, "bob=%d\n", bob); + abort(); + } +} + diff --git a/posix/config_variables.h b/posix/config_variables.h new file mode 100644 index 0000000..6e7a8c2 --- /dev/null +++ b/posix/config_variables.h @@ -0,0 +1,8 @@ +#pragma once + +#include +#include +#include + +bool config_integer_get(const char *category, const char *name, int * ret); +bool config_string_get(const char *category, const char *name, char *ret, uint8_t retlen); diff --git a/web_server.c b/web_server.c index 2eccec5..da4a65b 100644 --- a/web_server.c +++ b/web_server.c @@ -831,6 +831,7 @@ static int udp_out_open(const char *ip, const int port) return res; } +void test_config(); /* main program, start listening and answering queries */ int main(int argc, char *argv[]) @@ -847,6 +848,9 @@ int main(int argc, char *argv[]) // setup default allowed origin setup_origin(public_origin); + /* test_config(); */ + /* exit(1); */ + while ((opt=getopt(argc, argv, "p:s:b:hd:uf:O:")) != -1) { switch (opt) { case 'p': From a3fdabad14723b4191194787aebac96ac1e12551 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Thu, 2 Nov 2017 15:37:23 +1100 Subject: [PATCH 088/124] APSync: copy in a whole bunch of improvements to status.html --- files/apsync/status.html | 99 +++++++++++++++++++++++++++++++++++----- files/js/mavlink.js | 3 +- 2 files changed, 89 insertions(+), 13 deletions(-) diff --git a/files/apsync/status.html b/files/apsync/status.html index b1a8380..0501bdf 100644 --- a/files/apsync/status.html +++ b/files/apsync/status.html @@ -25,6 +25,7 @@ +
      @@ -128,6 +129,7 @@

      IMU Status

      VariableValue FixType
      Numsats
      + EKF Status
      Latitude (GPS)
      Longitude (GPS)
      Altitude (AMSL)
      @@ -247,17 +249,26 @@

      Motor Testing

      function motor_test(motornum) { var motorpower = document.getElementById("motor_power").value; var testtime = document.getElementById("test_time").value; - mavlink_command_long_send(MAV_CMD_DO_MOTOR_TEST, 0, motornum, 0, motorpower, testtime); + var motorcount = 0; + if (motornum == 0) { + motornum = 1; + motorcount = 4; + } + mavlink_command_long_send(MAV_CMD_DO_MOTOR_TEST, 0, motornum, 0, motorpower, testtime, motorcount); } -Select motor to test, along with test power level (as a percentage) and test time in seconds. +Select motor to test, along with test power level (as a percentage) +and test time in seconds. If you choose "All Motors" then all 4 motors +will come on in sequence, starting with the front-right motor and +proceeding clockwise from there.

      +

      Test Power @@ -288,14 +299,22 @@

      Motor Testing

      +
      + +
      + +

      Flight Controller Messages

      + + +
      Refresh rate: 

      + +
      + + +
      DeviceCamera NameRTSP URLCopy URLQuality ⓘRecord ⓘApply
      +

      +
      + + \ No newline at end of file diff --git a/files/index.html b/files/index.html index 6e9757d..1ccedb1 100644 --- a/files/index.html +++ b/files/index.html @@ -24,6 +24,7 @@

      ArduPilot Web Server

    • System Status
    • Calibration
    • Flight Parameters
    • +
    • Video Streaming
    diff --git a/files/js/config.js b/files/js/config.js index 2e50568..5fb8abd 100644 --- a/files/js/config.js +++ b/files/js/config.js @@ -1,4 +1,4 @@ -var drone_url = "http://192.168.99.1"; +var drone_url = "http://127.0.0.1"; /* URL for Ublox MGA data */ var mga_data_url = "http://gps.tridgell.net/data/mga-offline.ubx"; diff --git a/files/js/mavlink.js b/files/js/mavlink.js index 9e47cee..52d5417 100644 --- a/files/js/mavlink.js +++ b/files/js/mavlink.js @@ -113,7 +113,8 @@ function fill_sr_parameters(plist) { /* fill in all divs of form MAVLINK:MSGNAME:field at refresh_ms() rate */ -function fill_mavlink_ids(options={}) { +function fill_mavlink_ids(options) { + options = options || {} function again() { setTimeout(function() { fill_mavlink_ids(options); }, refresh_ms()); } @@ -266,7 +267,8 @@ function page_fill_json_html(json) { /* send a command function */ -function command_send(command, options={}) { +function command_send(command, options) { + options = options || {} var args = Array.prototype.slice.call(arguments); var xhr = createCORSRequest("POST", drone_url + "/ajax/command.json"); var form = new FormData(); @@ -395,7 +397,8 @@ function ajax_get_callback_binary(url, callback) { /* poll a URL, calling a callback */ -function ajax_poll(url, callback, refresh_ms=1000) { +function ajax_poll(url, callback, refresh_ms) { + refresh_ms = refresh_ms || 1000 function again() { setTimeout(function() { ajax_poll(url, callback, refresh_ms); }, refresh_ms); } @@ -419,7 +422,8 @@ function ajax_poll(url, callback, refresh_ms=1000) { /* poll a json file and fill document IDs at the given rate */ -function ajax_json_poll(url, callback, refresh_ms=1000) { +function ajax_json_poll(url, callback, refresh_ms) { + refresh_ms = refresh_ms || 1000 function do_callback(responseText) { try { var json = JSON.parse(responseText); @@ -436,7 +440,8 @@ function ajax_json_poll(url, callback, refresh_ms=1000) { /* poll a json file and fill document IDs at the given rate */ -function ajax_json_poll_fill(url, refresh_ms=1000) { +function ajax_json_poll_fill(url, refresh_ms) { + refresh_ms = refresh_ms || 1000 function callback(json) { page_fill_json_html(json); return true; diff --git a/functions.c b/functions.c index ad2ec8e..0c5987e 100644 --- a/functions.c +++ b/functions.c @@ -8,6 +8,7 @@ #include "mavlink_json.h" #include "mavlink_core.h" #include "cgi.h" +#include "rtsp_ipc.h" #ifdef _POSIX_VERSION #include "posix/functions.h" @@ -755,6 +756,77 @@ static void get_param(struct template_state *tmpl, const char *name, const char } } +/* + gets the list of avaialble cameras from the RTSP stream server over a local socket + */ +static void get_camera_details(struct template_state *tmpl, const char *name, const char *value, int argc, char **argv) +{ + char msg[IPC_BUFFER_SIZE]; + char result[IPC_BUFFER_SIZE]; + get_server_response(GET_DEVICE_PROPS, msg, NULL); + if (strlen(msg)) { + process_server_response(msg, result); + sock_printf(tmpl->sock, "%s", result); + } else { + sock_printf(tmpl->sock, "%s", "ERROR"); + } +} + +/* + find the list of available network interfaces for starting the RTSP stream server + */ +static void get_interfaces(struct template_state *tmpl, const char *name, const char *value, int argc, char **argv) +{ + char interfaces_list[IPC_BUFFER_SIZE]; + get_interfaces_list(interfaces_list); + sock_printf(tmpl->sock, "%s", interfaces_list); +} + +/* + sets the properties of a camera through IPC with the RTSP stream server + */ +static void set_device_quality(struct template_state *tmpl, const char *name, const char *value, int argc, char **argv) +{ + if (argc) { + if (send_server_message(argv[0])) { + printf("Error in setting camera properties\n"); + } + } +} + +static pid_t stream_server_pid = -1; + +/* + forks to create a new process for the RTSP stream + */ +static void start_rtsp_server(struct template_state *tmpl, const char *name, const char *value, int argc, char **argv) +{ + if (stream_server_pid == -1) { + stream_server_pid = fork(); + if (stream_server_pid < 0) { + printf("Fork failed\n"); + } else if (stream_server_pid == 0) { + if (execlp("stream_server", "stream_server", argv[0], NULL)==-1) { + printf("Error in launching the stream server\n"); + } + } + } else { + printf("Stream server running with PID: %d\n", stream_server_pid); + } +} + +static void stop_rtsp_server(struct template_state *tmpl, const char *name, const char *value, int argc, char **argv) +{ + if (stream_server_pid != -1) { + if(!kill(stream_server_pid, SIGTERM)) { + stream_server_pid = -1; + printf("Stream server successfully killed\n"); + } else { + printf("Could not kill the stream server\n"); + } + } +} + /* get parameter list */ @@ -1061,4 +1133,9 @@ void functions_init(struct template_state *tmpl) tmpl->put(tmpl, "process_content", "", process_content); tmpl->put(tmpl, "get_param", "", get_param); tmpl->put(tmpl, "get_param_list", "", get_param_list); + tmpl->put(tmpl, "get_camera_details", "", get_camera_details); + tmpl->put(tmpl, "set_device_quality", "", set_device_quality); + tmpl->put(tmpl, "start_rtsp_server", "", start_rtsp_server); + tmpl->put(tmpl, "stop_rtsp_server", "", stop_rtsp_server); + tmpl->put(tmpl, "get_interfaces", "", get_interfaces); } diff --git a/rtsp_ipc.c b/rtsp_ipc.c new file mode 100644 index 0000000..811530e --- /dev/null +++ b/rtsp_ipc.c @@ -0,0 +1,139 @@ +#include "includes.h" +#include "rtsp_ipc.h" +#include +#include +#include +#include +#include +#include +#include +#include + +const char SOCKET_PATH[80] = "/tmp/rtsp_server.sock"; + +const char* RTSP_MESSAGE_HEADER[] = { + "GDP", "SDP" +}; + +int send_server_message(char* msg) +{ + struct sockaddr_un addr; + int fd; + + if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + printf("Unable to create stream server socket\n"); + return -1; + } + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, SOCKET_PATH); + + if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) { + printf("Unable to connect to the stream server\n"); + return -1; + } else { + write(fd, msg, strlen(msg)); + close(fd); + } + return 0; +} + +void get_server_response(RTSP_MESSAGE_TYPE type, char* reply, char* args) +{ + struct sockaddr_un addr; + int fd; + + if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { + printf("Unable to create stream server socket\n"); + reply[0] = '\0'; + return; + } + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, SOCKET_PATH); + + if (connect(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) { + reply[0] = '\0'; + printf("Unable to connect to the stream server\n"); + } else { + switch(type) { + case GET_DEVICE_PROPS: + write(fd, "GDP", 4); + break; + default: + printf("Malformed message from stream server\n"); + } + + char read_buffer[IPC_BUFFER_SIZE]; + read_buffer[0] = '\0'; + int bytes_read = recv(fd, read_buffer, sizeof(read_buffer), 0); + read_buffer[bytes_read] = '\0'; + if (bytes_read != -1) { + strcpy(reply, read_buffer); + } + } + close(fd); +} + +RTSP_MESSAGE_TYPE get_message_type(char* header) +{ + for (int i = 0; i < RTSP_MESSAGE_TYPE_COUNT; i++) { + if (!strcmp(header, RTSP_MESSAGE_HEADER[i])) { + return i; + } + } + return ERROR; +} + +void process_server_response(char* reply, char* result) +{ + char* p = strtok(reply, "$"); + + char* msg_header = strdup(p); + RTSP_MESSAGE_TYPE message_type; + message_type = get_message_type(msg_header); + + p = strtok(NULL, "$"); + + switch (message_type) { + case GET_DEVICE_PROPS: + ; + strcpy(result, p); + break; + default: + printf("Malformed message from stream server\n"); + } +} + +// Gets list of available network interfaces for starting the RTSP stream server +void get_interfaces_list(char* interface_list) +{ + struct ifaddrs *ifaddr, *ifa; + char host[NI_MAXHOST]; + + if (getifaddrs(&ifaddr) == -1) { + printf("Could not get IPs"); + } + interface_list[0] = '\0'; + sprintf(interface_list, "{\"interfaces\": ["); + int i = 0; + for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL) { + continue; + } + getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, + NULL, 0, NI_NUMERICHOST); + if (ifa->ifa_addr->sa_family==AF_INET) { + if (i == 0) { + sprintf(interface_list, "%s\"%s\"", interface_list, ifa->ifa_name); + } else { + sprintf(interface_list, "%s,\"%s\"", interface_list, ifa->ifa_name); + } + i++; + } + } + sprintf(interface_list, "%s]}", interface_list); + freeifaddrs(ifaddr); +} diff --git a/rtsp_ipc.h b/rtsp_ipc.h new file mode 100644 index 0000000..a87598c --- /dev/null +++ b/rtsp_ipc.h @@ -0,0 +1,18 @@ +#ifndef RTSP_IPC_H +#define RTSP_IPC_H + +static const unsigned int IPC_BUFFER_SIZE = 10000; + +typedef enum RTSP_MESSAGE_TYPE {GET_DEVICE_PROPS, + SET_DEVICE_PROPS, + ERROR, + RTSP_MESSAGE_TYPE_COUNT} + RTSP_MESSAGE_TYPE; + +void get_server_response(RTSP_MESSAGE_TYPE type, char* reply, char* args); +int send_server_message(char* msg); +void process_server_response(char* reply, char* result); +void get_interfaces_list(char* interface_list); +RTSP_MESSAGE_TYPE get_message_type(char* header); + +#endif diff --git a/web_server.c b/web_server.c index 78fa5c2..0c977c3 100644 --- a/web_server.c +++ b/web_server.c @@ -13,6 +13,9 @@ #else #include #include +#include +#include +#include #endif #ifndef SYSTEM_FREERTOS @@ -273,9 +276,27 @@ static void connection_process(struct connection_state *c) */ static bool check_origin(const char *origin) { - if (strcmp(origin, "http://10.0.1.128") == 0) { - // always accept - return true; + struct ifaddrs *ifaddr, *ifa; + char host[NI_MAXHOST]; + + if (getifaddrs(&ifaddr) == -1) { + printf("Could not get IPs"); + } + + // check for matching IPs on all interfaces of the device + for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { + if (ifa->ifa_addr == NULL) { + continue; + } + getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, + NULL, 0, NI_NUMERICHOST); + if (ifa->ifa_addr->sa_family==AF_INET) { + char host_string[20] = "http://"; + strcat(host_string, host); + if (strcmp(origin, host_string) == 0) { + return true; + } + } } #ifdef SYSTEM_FREERTOS From feaa8800dd0ff6f189170f9009ec1740bf670b7c Mon Sep 17 00:00:00 2001 From: arnav dhamija Date: Tue, 7 Aug 2018 12:59:13 +0530 Subject: [PATCH 113/124] Fixed layout bug --- files/apsync/video.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/files/apsync/video.html b/files/apsync/video.html index 2caab77..4bd1e8e 100644 --- a/files/apsync/video.html +++ b/files/apsync/video.html @@ -152,7 +152,7 @@

    Video Streaming

    var form_quality = "form_quality" + i; var quality_select_box = "quality_select_box"+i; - var set_quality_button = "set_quality_button"+i;copy_clipboard + var set_quality_button = "set_quality_button"+i; var record_video_checkbox = "record"+i; var current_quality = rowdata.current_quality; From b0d8471415f0b698598a631e85e741012998d69a Mon Sep 17 00:00:00 2001 From: arnav dhamija Date: Wed, 8 Aug 2018 14:51:42 +0530 Subject: [PATCH 114/124] Changed SIG for killing the stream server --- functions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/functions.c b/functions.c index 0c5987e..8163877 100644 --- a/functions.c +++ b/functions.c @@ -818,7 +818,7 @@ static void start_rtsp_server(struct template_state *tmpl, const char *name, con static void stop_rtsp_server(struct template_state *tmpl, const char *name, const char *value, int argc, char **argv) { if (stream_server_pid != -1) { - if(!kill(stream_server_pid, SIGTERM)) { + if(!kill(stream_server_pid, SIGINT)) { stream_server_pid = -1; printf("Stream server successfully killed\n"); } else { From cd4289cb3a1ba6ef4021732f4c19e60f512e3c1f Mon Sep 17 00:00:00 2001 From: arnav dhamija Date: Wed, 8 Aug 2018 15:19:39 +0530 Subject: [PATCH 115/124] Fixed segfault bug --- functions.c | 1 + rtsp_ipc.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/functions.c b/functions.c index 8163877..b373995 100644 --- a/functions.c +++ b/functions.c @@ -763,6 +763,7 @@ static void get_camera_details(struct template_state *tmpl, const char *name, co { char msg[IPC_BUFFER_SIZE]; char result[IPC_BUFFER_SIZE]; + msg[0] = '\0'; get_server_response(GET_DEVICE_PROPS, msg, NULL); if (strlen(msg)) { process_server_response(msg, result); diff --git a/rtsp_ipc.c b/rtsp_ipc.c index 811530e..d3f568a 100644 --- a/rtsp_ipc.c +++ b/rtsp_ipc.c @@ -96,11 +96,14 @@ void process_server_response(char* reply, char* result) message_type = get_message_type(msg_header); p = strtok(NULL, "$"); + result[0] = '\0'; switch (message_type) { case GET_DEVICE_PROPS: ; - strcpy(result, p); + if (result) { + strcpy(result, p); + } break; default: printf("Malformed message from stream server\n"); From bad39aebeb233c080498524c22de7ade80fdfbf0 Mon Sep 17 00:00:00 2001 From: arnav dhamija Date: Tue, 18 Sep 2018 15:00:45 +0530 Subject: [PATCH 116/124] Changed location of stream server binary --- functions.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/functions.c b/functions.c index b373995..9ca878a 100644 --- a/functions.c +++ b/functions.c @@ -807,7 +807,11 @@ static void start_rtsp_server(struct template_state *tmpl, const char *name, con if (stream_server_pid < 0) { printf("Fork failed\n"); } else if (stream_server_pid == 0) { - if (execlp("stream_server", "stream_server", argv[0], NULL)==-1) { + char* home_dir; + char stream_server_path[256]; + home_dir = getenv("HOME"); + sprintf(stream_server_path, "%s/apsync/start_apstreamline/bin/stream_server", home_dir); + if (execl(stream_server_path, "stream_server", argv[0], NULL)==-1) { printf("Error in launching the stream server\n"); } } From 2374b8fb9383794565ea2ba542866a6ed33b2e6d Mon Sep 17 00:00:00 2001 From: arnav dhamija Date: Tue, 18 Sep 2018 18:23:33 +0530 Subject: [PATCH 117/124] Changed stream_server executable path --- functions.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/functions.c b/functions.c index 9ca878a..69ba4e9 100644 --- a/functions.c +++ b/functions.c @@ -810,7 +810,8 @@ static void start_rtsp_server(struct template_state *tmpl, const char *name, con char* home_dir; char stream_server_path[256]; home_dir = getenv("HOME"); - sprintf(stream_server_path, "%s/apsync/start_apstreamline/bin/stream_server", home_dir); + sprintf(stream_server_path, "%s/start_apstreamline/bin/stream_server", home_dir); + printf("%s", stream_server_path); if (execl(stream_server_path, "stream_server", argv[0], NULL)==-1) { printf("Error in launching the stream server\n"); } From 9ce1ff167c70d0268a77ac45783305b0cf2e2c56 Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Thu, 14 Mar 2019 16:10:40 +1100 Subject: [PATCH 118/124] mavlink: update to ardupilot master --- modules/mavlink | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/mavlink b/modules/mavlink index 27e40d1..789a6d1 160000 --- a/modules/mavlink +++ b/modules/mavlink @@ -1 +1 @@ -Subproject commit 27e40d19654ca39818e6f63728f999afae679710 +Subproject commit 789a6d17fb33a1b95935313fd34116df6e62c485 From 80d1085777690d17090cbcbef83c2b740b39e2ed Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Thu, 14 Mar 2019 16:11:01 +1100 Subject: [PATCH 119/124] Makefile: use mavgen shipped with mavlink's pymavlink --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 310be85..6c56a16 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ all: files/embedded.c mavlink web_server mavlink: generated/mavlink/ardupilotmega/mavlink.h generated/mavlink/ardupilotmega/mavlink.h: - mavgen.py --lang C modules/mavlink/message_definitions/v1.0/ardupilotmega.xml -o generated/mavlink --wire-protocol=2.0 + modules/mavlink/pymavlink/tools/mavgen.py --lang C modules/mavlink/message_definitions/v1.0/ardupilotmega.xml -o generated/mavlink --wire-protocol=2.0 web_server: $(OBJ) files/embedded.c $(CC) -o web_server $(OBJ) $(LIBS) From e801235715841e1740b565cb3b9236e57031b391 Mon Sep 17 00:00:00 2001 From: arnav dhamija Date: Sun, 31 Mar 2019 10:38:54 +0800 Subject: [PATCH 120/124] Fixed CORS requests from Chrome/Safari --- web_server.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/web_server.c b/web_server.c index f5fe9d8..54a2568 100644 --- a/web_server.c +++ b/web_server.c @@ -291,9 +291,7 @@ static bool check_origin(const char *origin) getnameinfo(ifa->ifa_addr,sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); if (ifa->ifa_addr->sa_family==AF_INET) { - char host_string[20] = "http://"; - strcat(host_string, host); - if (strcmp(origin, host_string) == 0) { + if (strstr(origin, host) != NULL) { return true; } } From 11a48e52e97346b643c4419a60f0b374d5753234 Mon Sep 17 00:00:00 2001 From: arnav dhamija Date: Mon, 1 Apr 2019 13:50:39 +0800 Subject: [PATCH 121/124] Disabled the file recorder --- files/apsync/video.html | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/files/apsync/video.html b/files/apsync/video.html index 4bd1e8e..3683c84 100644 --- a/files/apsync/video.html +++ b/files/apsync/video.html @@ -17,7 +17,7 @@

    Video Streaming

    - +
    DeviceCamera NameRTSP URLCopy URLQuality ⓘRecord ⓘApply
    DeviceCamera NameRTSP URLCopy URLQuality ⓘApply

    @@ -164,12 +164,7 @@

    Video Streaming

    } else { row.insertCell(4).innerHTML = ''; } - if (rowdata.camtype != 2) { - row.insertCell(5).innerHTML = ''; - } else { - row.insertCell(5).innerHTML = ''; - } - row.insertCell(6).innerHTML = ''; + row.insertCell(5).innerHTML = ''; var select = document.getElementById(quality_select_box); select.options[select.options.length] = new Option("Auto", AUTO_PRESET); @@ -196,13 +191,7 @@

    Video Streaming

    var device_name = document.getElementById("device" + button.value).innerHTML; var qual_setting = quality_select_box.value; - var record_val; - - if (record_video_checkbox.checked == true) { - record_val = 1; - } else { - record_val = 0; - } + var record_val = 0; var sdp_string = "SDP$" + device_name + " " + qual_setting + " " + record_val; command_send("set_device_quality(" + sdp_string + ")", {"onload" : after_sdp}); From e4b0b543ee0d3323634ab97067a05780952e644f Mon Sep 17 00:00:00 2001 From: arnav dhamija Date: Mon, 1 Apr 2019 13:53:37 +0800 Subject: [PATCH 122/124] Re-enabled quality for UVC cameras --- files/apsync/video.html | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/files/apsync/video.html b/files/apsync/video.html index 3683c84..f291119 100644 --- a/files/apsync/video.html +++ b/files/apsync/video.html @@ -158,12 +158,7 @@

    Video Streaming

    var current_quality = rowdata.current_quality; var curr_recording = rowdata.recording; - // H.264 cams don't do file recording properly, so let's disable it for now - if (rowdata.camtype != 1) { - row.insertCell(4).innerHTML = ''; - } else { - row.insertCell(4).innerHTML = ''; - } + row.insertCell(4).innerHTML = ''; row.insertCell(5).innerHTML = ''; var select = document.getElementById(quality_select_box); From 2b4dcf1fa849f4c8312623fd197ae8bab80ed941 Mon Sep 17 00:00:00 2001 From: arnav dhamija Date: Tue, 21 May 2019 11:42:48 +0530 Subject: [PATCH 123/124] Removed file recording checkbox --- files/apsync/video.html | 1 - 1 file changed, 1 deletion(-) diff --git a/files/apsync/video.html b/files/apsync/video.html index f291119..6386f8e 100644 --- a/files/apsync/video.html +++ b/files/apsync/video.html @@ -172,7 +172,6 @@

    Video Streaming

    } } document.getElementById(quality_select_box).value = current_quality; - document.getElementById(record_video_checkbox).checked = curr_recording; } } } From b8203158a37ecec99f4e873777095a9013364804 Mon Sep 17 00:00:00 2001 From: arnav dhamija Date: Wed, 31 Jul 2019 17:13:47 +0530 Subject: [PATCH 124/124] Changed path of stream_server executable for APStreamline --- functions.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/functions.c b/functions.c index 7e8d38f..5b54809 100644 --- a/functions.c +++ b/functions.c @@ -811,12 +811,7 @@ static void start_rtsp_server(struct template_state *tmpl, const char *name, con if (stream_server_pid < 0) { printf("Fork failed\n"); } else if (stream_server_pid == 0) { - char* home_dir; - char stream_server_path[256]; - home_dir = getenv("HOME"); - sprintf(stream_server_path, "%s/start_apstreamline/bin/stream_server", home_dir); - printf("%s", stream_server_path); - if (execl(stream_server_path, "stream_server", argv[0], NULL)==-1) { + if (execlp("stream_server", "stream_server", argv[0], NULL)==-1) { printf("Error in launching the stream server\n"); } }