Skip to content

Commit

Permalink
Merge pull request #2370 from cesanta/ota
Browse files Browse the repository at this point in the history
Add OTA to the device dashboard. Implement for H5
  • Loading branch information
cpq authored Sep 5, 2023
2 parents fbc56f4 + 2f01423 commit 2883709
Show file tree
Hide file tree
Showing 19 changed files with 3,332 additions and 7,534 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ OPTS ?= -O3 -g3
INCS ?= -Isrc -I.
SSL ?=
CWD ?= $(realpath $(CURDIR))
ENV ?= -e Tmp=. -e WINEDEBUG=-all
ENV ?= -e Tmp=. -e WINEDEBUG=-all
DOCKER ?= docker run --platform linux/amd64 --rm $(ENV) -v $(CWD):$(CWD) -w $(CWD)
VCFLAGS = /nologo /W3 /O2 /MD /I. $(DEFS) $(TFLAGS)
IPV6 ?= 1
Expand Down Expand Up @@ -175,7 +175,7 @@ mongoose.c: Makefile $(wildcard src/*.c) $(wildcard src/drivers/*.c)
(cat src/license.h; echo; echo '#include "mongoose.h"' ; (for F in src/*.c src/drivers/*.c ; do echo; echo '#ifdef MG_ENABLE_LINES'; echo "#line 1 \"$$F\""; echo '#endif'; cat $$F | sed -e 's,#include ".*,,'; done))> $@

mongoose.h: $(HDRS) Makefile
(cat src/license.h; echo; echo '#ifndef MONGOOSE_H'; echo '#define MONGOOSE_H'; echo; cat src/version.h ; echo; echo '#ifdef __cplusplus'; echo 'extern "C" {'; echo '#endif'; cat src/arch.h src/arch_*.h src/net_ft.h src/net_lwip.h src/net_rl.h src/config.h src/str.h src/queue.h src/fmt.h src/printf.h src/log.h src/timer.h src/fs.h src/util.h src/url.h src/iobuf.h src/base64.h src/md5.h src/sha1.h src/event.h src/net.h src/http.h src/ssi.h src/tls.h src/tls_mbed.h src/tls_openssl.h src/ws.h src/sntp.h src/mqtt.h src/dns.h src/json.h src/rpc.h src/net_builtin.h src/drivers/*.h src/certs.h | sed -e '/keep/! s,#include ".*,,' -e 's,^#pragma once,,'; echo; echo '#ifdef __cplusplus'; echo '}'; echo '#endif'; echo '#endif // MONGOOSE_H')> $@
(cat src/license.h; echo; echo '#ifndef MONGOOSE_H'; echo '#define MONGOOSE_H'; echo; cat src/version.h ; echo; echo '#ifdef __cplusplus'; echo 'extern "C" {'; echo '#endif'; cat src/arch.h src/arch_*.h src/net_ft.h src/net_lwip.h src/net_rl.h src/config.h src/str.h src/queue.h src/fmt.h src/printf.h src/log.h src/timer.h src/fs.h src/util.h src/url.h src/iobuf.h src/base64.h src/md5.h src/sha1.h src/event.h src/net.h src/http.h src/ssi.h src/tls.h src/tls_mbed.h src/tls_openssl.h src/ws.h src/sntp.h src/mqtt.h src/dns.h src/json.h src/rpc.h src/ota.h src/net_builtin.h src/drivers/*.h src/certs.h | sed -e '/keep/! s,#include ".*,,' -e 's,^#pragma once,,'; echo; echo '#ifdef __cplusplus'; echo '}'; echo '#endif'; echo '#endif // MONGOOSE_H')> $@


clean: clean_examples clean_embedded
Expand Down
6 changes: 5 additions & 1 deletion examples/device-dashboard/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
PROG ?= ./example # Program we are building
PACK ?= ./pack # Packing executable
DELETE = rm -rf # Command to remove files
GZIP ?= gzip # For compressing files in web_root/
OUT ?= -o $(PROG) # Compiler argument for output file
SOURCES = main.c mongoose.c net.c packed_fs.c # Source code files
CFLAGS = -W -Wall -Wextra -g -I. # Build options
Expand All @@ -14,6 +15,7 @@ ifeq ($(OS),Windows_NT) # Windows settings. Assume MinGW compiler. To us
CC = gcc # Use MinGW gcc compiler
CFLAGS += -lws2_32 # Link against Winsock library
DELETE = cmd /C del /Q /F /S # Command prompt command to delete files
GZIP = echo # No gzip on Windows
endif

# Default target. Build and run program
Expand All @@ -34,8 +36,10 @@ web_root/main.css: web_root/index.html $(wildcard web_root/*.js)

# Generate packed filesystem for serving Web UI
packed_fs.c: $(wildcard web_root/*) $(wildcard certs/*) Makefile web_root/main.css web_root/bundle.js
$(GZIP) web_root/*
$(CC) ../../test/pack.c -o $(PACK)
$(PACK) $(wildcard web_root/*) $(wildcard certs/*) > $@
$(PACK) web_root/* certs/* > $@
$(GZIP) -d web_root/*

mbedtls:
git clone --depth 1 -b v2.28.2 https://github.com/mbed-tls/mbedtls $@
Expand Down
1 change: 0 additions & 1 deletion examples/device-dashboard/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ int main(void) {
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);

srand(time(NULL));
mg_log_set(MG_LL_DEBUG); // Set debug log level
mg_mgr_init(&mgr);

Expand Down
74 changes: 72 additions & 2 deletions examples/device-dashboard/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ static struct user *authenticate(struct mg_http_message *hm) {
char user[64], pass[64];
struct user *u, *result = NULL;
mg_http_creds(hm, user, sizeof(user), pass, sizeof(pass));
MG_INFO(("user [%s] pass [%s]", user, pass));
MG_VERBOSE(("user [%s] pass [%s]", user, pass));

if (user[0] != '\0' && pass[0] != '\0') {
// Both user and password is set, search by user/password
Expand Down Expand Up @@ -198,6 +198,67 @@ static void handle_settings_get(struct mg_connection *c) {
MG_ESC("device_name"), MG_ESC(s_settings.device_name));
}

static void handle_firmware_upload(struct mg_connection *c,
struct mg_http_message *hm) {
char name[64], offset[20], total[20];
struct mg_str data = hm->body;
long ofs = -1, tot = -1;
name[0] = offset[0] = '\0';
mg_http_get_var(&hm->query, "name", name, sizeof(name));
mg_http_get_var(&hm->query, "offset", offset, sizeof(offset));
mg_http_get_var(&hm->query, "total", total, sizeof(total));
MG_INFO(("File %s, offset %s, len %lu", name, offset, data.len));
if ((ofs = mg_json_get_long(mg_str(offset), "$", -1)) < 0 ||
(tot = mg_json_get_long(mg_str(total), "$", -1)) < 0) {
mg_http_reply(c, 500, "", "offset and total not set\n");
} else if (ofs == 0 && mg_ota_begin((size_t) tot) == false) {
mg_http_reply(c, 500, "", "mg_ota_begin(%ld) failed\n", tot);
} else if (data.len > 0 && mg_ota_write(data.ptr, data.len) == false) {
mg_http_reply(c, 500, "", "mg_ota_write(%lu) @%ld failed\n", data.len, ofs);
mg_ota_end();
} else if (data.len == 0 && mg_ota_end() == false) {
mg_http_reply(c, 500, "", "mg_ota_end() failed\n", tot);
} else {
mg_http_reply(c, 200, s_json_header, "true\n");
if (data.len == 0) {
// Successful mg_ota_end() called, schedule device reboot
mg_timer_add(c->mgr, 500, 0, (void (*)(void *)) mg_sys_reset, NULL);
}
}
}

static void handle_firmware_commit(struct mg_connection *c) {
mg_http_reply(c, 200, s_json_header, "%s\n",
mg_ota_commit() ? "true" : "false");
}

static void handle_firmware_rollback(struct mg_connection *c) {
mg_http_reply(c, 200, s_json_header, "%s\n",
mg_ota_rollback() ? "true" : "false");
}

static size_t print_status(void (*out)(char, void *), void *ptr, va_list *ap) {
struct mg_ota_data *os = va_arg(*ap, struct mg_ota_data *);
return mg_xprintf(
out, ptr, "{%m:%s,%m:%c%x%c,%m:%u,%m:%u,%m:%u,%m:%u,%m:%u}",
MG_ESC("valid"), os->magic == MG_OTA_MAGIC ? "true" : "false",
MG_ESC("magic"), '"', os->magic, '"', MG_ESC("crc32"), os->crc32,
MG_ESC("size"), os->size, MG_ESC("time"), os->time, MG_ESC("booted"),
os->booted, MG_ESC("golden"), os->golden);
}

static void handle_firmware_status(struct mg_connection *c) {
struct mg_ota_data od[2];
mg_ota_status(od);
mg_http_reply(c, 200, s_json_header, "[%M,%M]\n", print_status, &od[0],
print_status, &od[1]);
}

static void handle_sys_reset(struct mg_connection *c) {
mg_http_reply(c, 200, s_json_header, "true\n");
mg_timer_add(c->mgr, 500, 0, (void (*)(void *)) mg_sys_reset, NULL);
}

// HTTP request handler function
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
if (ev == MG_EV_HTTP_MSG) {
Expand All @@ -220,6 +281,16 @@ static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
handle_settings_get(c);
} else if (mg_http_match_uri(hm, "/api/settings/set")) {
handle_settings_set(c, hm->body);
} else if (mg_http_match_uri(hm, "/api/firmware/upload")) {
handle_firmware_upload(c, hm);
} else if (mg_http_match_uri(hm, "/api/firmware/commit")) {
handle_firmware_commit(c);
} else if (mg_http_match_uri(hm, "/api/firmware/rollback")) {
handle_firmware_rollback(c);
} else if (mg_http_match_uri(hm, "/api/firmware/status")) {
handle_firmware_status(c);
} else if (mg_http_match_uri(hm, "/api/sys/reset")) {
handle_sys_reset(c);
} else {
struct mg_http_serve_opts opts;
memset(&opts, 0, sizeof(opts));
Expand Down Expand Up @@ -249,7 +320,6 @@ void web_init(struct mg_mgr *mgr) {
mg_http_listen(mgr, HTTP_URL, fn, NULL);
mg_http_listen(mgr, HTTPS_URL, fn, NULL);

// mg_timer_add(c->mgr, 1000, MG_TIMER_REPEAT, timer_mqtt_fn, c->mgr);
mg_timer_add(mgr, 3600 * 1000, MG_TIMER_RUN_NOW | MG_TIMER_REPEAT,
timer_sntp_fn, mgr);
}
Loading

0 comments on commit 2883709

Please sign in to comment.