Add Zephyr examples

This commit is contained in:
Alex Alashkin 2022-04-07 15:29:42 +03:00
parent 6e3e77a1a0
commit 17e0fb1c15
21 changed files with 757 additions and 19 deletions

View File

@ -1,15 +0,0 @@
CWD = $(realpath $(CURDIR))
ZEPHYR_DIR ?= $(realpath ../../../zephyrproject)
example:
true
build:
cp ../../mongoose.c ../../mongoose.h http-server/src/
cd $(ZEPHYR_DIR) && west build -b nucleo_f746zg -p auto $(CWD)/http-server
flash:
cd $(ZEPHYR_DIR) && west flash
clean:
rm -rf */*/mongoose.*

View File

@ -0,0 +1,11 @@
# Copyright (c) 2022 Cesanta Software Limited
# Mail: support@cesanta.com
#
# SPDX-License-Identifier: GPL2.0 or commercial
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(http_server)
#add_definitions(-DMG_ENABLE_LINES=1)
add_definitions(-DMG_ENABLE_MBEDTLS=1 -DMG_MBEDTLS_DEBUG_LEVEL=4)
target_sources(app PRIVATE src/main.c src/mongoose.c)

View File

@ -0,0 +1,16 @@
CWD = $(realpath $(CURDIR))
ZEPHYR_DIR ?= $(realpath ../../../../zephyrproject)
BOARD ?= nucleo_h743zi
example:
true
build:
cp ../../../mongoose.c ../../../mongoose.h src/
cd $(ZEPHYR_DIR) && west build -b $(BOARD) -p auto $(CWD)
flash:
cd $(ZEPHYR_DIR) && west flash
clean:
rm -rf */*/mongoose.*

View File

@ -0,0 +1,32 @@
CONFIG_NETWORKING=y
CONFIG_NET_IPV4=y
CONFIG_NET_IPV6=y
CONFIG_NET_TCP=y
CONFIG_NET_UDP=y
CONFIG_NET_DHCPV4=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POLL_MAX=32
CONFIG_POSIX_MAX_FDS=32
CONFIG_NET_CONFIG_SETTINGS=y
CONFIG_NET_LOG=y
CONFIG_LOG=y
CONFIG_ISR_STACK_SIZE=2048
CONFIG_MAIN_STACK_SIZE=16000
CONFIG_IDLE_STACK_SIZE=1024
CONFIG_MBEDTLS=y
CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=8192
CONFIG_MBEDTLS_PEM_CERTIFICATE_FORMAT=y
CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=y
CONFIG_MBEDTLS_ECP_ALL_ENABLED=y
CONFIG_MBEDTLS_TLS_VERSION_1_2=y
CONFIG_MINIMAL_LIBC_RAND=y
CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE=131072
CONFIG_FILE_SYSTEM_LITTLEFS=y
CONFIG_PRINTK=y
CONFIG_MBEDTLS_DEBUG=y
CONFIG_MBEDTLS_DEBUG_LEVEL=4

View File

@ -0,0 +1,87 @@
#ifndef CERTS_H_
#define CERTS_H_
static const char *s_ca =
"-\n"
"Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert High Assurance EV Root CA\n"
"Not Before: Nov 10 00:00:00 2006 GMT\n"
"Not After : Nov 10 00:00:00 2031 GMT\n"
"-----BEGIN CERTIFICATE-----\n"
"MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs\n"
"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n"
"d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j\n"
"ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL\n"
"MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3\n"
"LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug\n"
"RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm\n"
"+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW\n"
"PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM\n"
"xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB\n"
"Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3\n"
"hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg\n"
"EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF\n"
"MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA\n"
"FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec\n"
"nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z\n"
"eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF\n"
"hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2\n"
"Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe\n"
"vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep\n"
"+OkuE6N36B9K\n"
"-----END CERTIFICATE-----\n"
"\n"
"Subject: C=US, O=DigiCert Inc, OU=www.digicert.com, CN=DigiCert Global Root CA\n"
"Not Before: Nov 10 00:00:00 2006 GMT\n"
"Not After : Nov 10 00:00:00 2031 GMT\n"
"-----BEGIN CERTIFICATE-----\n"
"MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh\n"
"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n"
"d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\n"
"QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT\n"
"MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n"
"b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG\n"
"9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB\n"
"CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97\n"
"nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt\n"
"43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P\n"
"T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4\n"
"gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO\n"
"BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR\n"
"TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw\n"
"DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr\n"
"hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg\n"
"06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF\n"
"PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls\n"
"YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk\n"
"CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=\n"
"-----END CERTIFICATE-----\n"
"\n"
"Not Before: Nov 10 00:00:00 2006 GMT\n"
"Not After : Nov 10 00:00:00 2031 GMT\n"
"Subject: C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert Global Root CA\n"
"-----BEGIN CERTIFICATE-----\n"
"MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh\n"
"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\n"
"d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD\n"
"QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT\n"
"MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j\n"
"b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG\n"
"9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB\n"
"CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97\n"
"nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt\n"
"43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P\n"
"T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4\n"
"gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO\n"
"BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR\n"
"TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw\n"
"DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr\n"
"hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg\n"
"06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF\n"
"PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls\n"
"YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk\n"
"CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=\n"
"-----END CERTIFICATE-----\n"
"\n"
"";
#endif

View File

@ -0,0 +1,112 @@
// Copyright (c) 2020 Cesanta Software Limited
// All rights reserved
#include "mongoose.h"
#include "certs.h"
static const char *s_debug_level = "3";
static time_t s_boot_timestamp = 0;
static struct mg_connection *s_sntp_conn = NULL;
static const char *s_url = "https://example.org/";
static const char *s_post_data = NULL; // POST data
static const int64_t s_timeout_ms = 1500; // Connect timeout in milliseconds
struct mg_mgr s_mgr;
static int s_connected = 0;
// Print HTTP response and signal that we're done
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
if (ev == MG_EV_OPEN) {
// Connection created. Store connect expiration time in c->label
*(int64_t *) c->label = mg_millis() + s_timeout_ms;
} else if (ev == MG_EV_POLL) {
if (mg_millis() > *(int64_t *) c->label &&
(c->is_connecting || c->is_resolving)) {
mg_error(c, "Connect timeout");
}
} else if (ev == MG_EV_CONNECT) {
// Connected to server. Extract host name from URL
struct mg_str host = mg_url_host(s_url);
// If s_url is https://, tell client connection to use TLS
if (mg_url_is_ssl(s_url)) {
struct mg_tls_opts opts = {.ca = s_ca, .srvname = host };
mg_tls_init(c, &opts);
}
// Send request
int content_length = s_post_data ? strlen(s_post_data) : 0;
mg_printf(c,
"%s %s HTTP/1.0\r\n"
"Host: %.*s\r\n"
"Content-Type: octet-stream\r\n"
"Content-Length: %d\r\n"
"\r\n",
s_post_data ? "POST" : "GET", mg_url_uri(s_url), (int) host.len,
host.ptr, content_length);
mg_send(c, s_post_data, content_length);
} else if (ev == MG_EV_HTTP_MSG) {
// Response is received. Print it
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
MG_INFO(("%.*s", (int) hm->message.len, hm->message.ptr));
c->is_closing = 1; // Tell mongoose to close this connection
*(bool *) fn_data = true; // Tell event loop to stop
} else if (ev == MG_EV_ERROR) {
*(bool *) fn_data = true; // Error, tell event loop to stop
}
}
// We have no valid system time(), and we need it for TLS. Implement it
time_t time(time_t *tp) {
time_t t = s_boot_timestamp + k_uptime_get() / 1000;
if (tp != NULL) *tp = t;
return t;
}
// SNTP callback. Modifies s_boot_timestamp, to make time() correct
static void sfn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
if (ev == MG_EV_SNTP_TIME) {
int64_t t = *(int64_t *) ev_data;
MG_INFO(("Got SNTP time: %lld ms from epoch", t));
s_boot_timestamp = (time_t) ((t - mg_millis()) / 1000);
// We need correct time in order to get HTTPs working, therefore,
// making https request from SMTP callback
if(!s_connected) {
MG_INFO(("Connecting to : [%s]", s_url));
mg_http_connect(&s_mgr, s_url, fn, NULL); // Create client connection
s_connected = 1;
}
} else if (ev == MG_EV_CLOSE) {
s_sntp_conn = NULL;
}
}
// Periodic timer syncs time via SNTP
static void timer_fn(void *arg) {
struct mg_mgr *mgr = (struct mg_mgr *) arg;
if (s_sntp_conn == NULL) s_sntp_conn = mg_sntp_connect(mgr, NULL, sfn, NULL);
if (s_boot_timestamp < 9999) mg_sntp_send(s_sntp_conn, time(NULL));
}
// Use Zephyr's printk() for Mongooose MG_* logging
static void logfn(const void *ptr, size_t len, void *userdata) {
printk("%.*s", (int) len, (char *) ptr);
}
int main(int argc, char *argv[]) {
mg_log_set(s_debug_level);
mg_log_set_callback(logfn, NULL);
mg_mgr_init(&s_mgr);
struct mg_timer t;
mg_timer_init(&t, 5000, MG_TIMER_REPEAT | MG_TIMER_RUN_NOW, timer_fn, &s_mgr);
// Start infinite event loop
MG_INFO(("Mongoose version : v%s", MG_VERSION));
for (;;) mg_mgr_poll(&s_mgr, 1000);
mg_mgr_free(&s_mgr);
return 0;
}

View File

@ -6,6 +6,5 @@
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(http_server)
#add_definitions(-DMG_ENABLE_LINES=1)
add_definitions(-DMG_ENABLE_MBEDTLS=1)
target_sources(app PRIVATE src/main.c src/mongoose.c)

View File

@ -0,0 +1,16 @@
CWD = $(realpath $(CURDIR))
ZEPHYR_DIR ?= $(realpath ../../../../zephyrproject)
BOARD ?= nucleo_h743zi
example:
true
build:
cp ../../../mongoose.c ../../../mongoose.h src/
cd $(ZEPHYR_DIR) && west build -b $(BOARD) -p auto $(CWD)
flash:
cd $(ZEPHYR_DIR) && west flash
clean:
rm -rf */*/mongoose.*

View File

@ -6,6 +6,7 @@ CONFIG_NET_UDP=y
CONFIG_NET_DHCPV4=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POLL_MAX=32
CONFIG_POSIX_MAX_FDS=32
CONFIG_NET_CONFIG_SETTINGS=y
CONFIG_NET_LOG=y
@ -16,6 +17,9 @@ CONFIG_IDLE_STACK_SIZE=1024
CONFIG_MBEDTLS=y
CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=2048
CONFIG_MBEDTLS_PEM_CERTIFICATE_FORMAT=y
CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=y
CONFIG_MBEDTLS_ECP_ALL_ENABLED=y
CONFIG_MINIMAL_LIBC_RAND=y
CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE=32756

View File

@ -0,0 +1,24 @@
#ifndef CERTS_H_
#define CERTS_H_
static const char *s_ssl_cert =
"-----BEGIN CERTIFICATE-----\r\n" \
"MIIBhzCCASygAwIBAgIUbnMoVd8TtWH1T09dANkK2LU6IUswCgYIKoZIzj0EAwIw\r\n" \
"RDELMAkGA1UEBhMCSUUxDzANBgNVBAcMBkR1YmxpbjEQMA4GA1UECgwHQ2VzYW50\r\n" \
"YTESMBAGA1UEAwwJVGVzdCBSb290MB4XDTIwMDUwOTIxNTE0OVoXDTMwMDUwOTIx\r\n" \
"NTE0OVowETEPMA0GA1UEAwwGc2VydmVyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD\r\n" \
"QgAEkuBGnInDN6l06zVVQ1VcrOvH5FDu9MC6FwJc2e201P8hEpq0Q/SJS2nkbSuW\r\n" \
"H/wBTTBaeXN2uhlBzMUWK790KKMvMC0wCQYDVR0TBAIwADALBgNVHQ8EBAMCA6gw\r\n" \
"EwYDVR0lBAwwCgYIKwYBBQUHAwEwCgYIKoZIzj0EAwIDSQAwRgIhAPo6xx7LjCdZ\r\n" \
"QY133XvLjAgVFrlucOZHONFVQuDXZsjwAiEAzHBNligA08c5U3SySYcnkhurGg50\r\n" \
"BllCI0eYQ9ggp/o=\r\n" \
"-----END CERTIFICATE-----\r\n";
static const char *s_ssl_key =
"-----BEGIN PRIVATE KEY-----\r\n" \
"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQglNni0t9Dg9icgG8w\r\n" \
"kbfxWSS+TuNgbtNybIQXcm3NHpmhRANCAASS4EacicM3qXTrNVVDVVys68fkUO70\r\n" \
"wLoXAlzZ7bTU/yESmrRD9IlLaeRtK5Yf/AFNMFp5c3a6GUHMxRYrv3Qo\r\n" \
"-----END PRIVATE KEY-----\r\n";
#endif

View File

@ -2,20 +2,19 @@
// All rights reserved
#include "mongoose.h"
#include "certs.h"
static const char *s_debug_level = "3";
static const char *s_web_dir = "/";
static const char *s_http_addr = "http://0.0.0.0:8000";
static const char *s_https_addr = "https://0.0.0.0:8443";
static const char *s_cert = "cert.pem";
static const char *s_key = "key.pem";
static time_t s_boot_timestamp = 0;
static struct mg_connection *s_sntp_conn = NULL;
// Event handler for the listening HTTP/HTTPS connection.
static void wcb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
if (ev == MG_EV_ACCEPT && fn_data != NULL) {
struct mg_tls_opts opts = {.cert = s_cert, .certkey = s_key};
struct mg_tls_opts opts = {.cert = s_ssl_cert, .certkey = s_ssl_key};
mg_tls_init(c, &opts);
} else if (ev == MG_EV_HTTP_MSG) {
struct mg_http_message *hm = ev_data;

View File

@ -0,0 +1,11 @@
# Copyright (c) 2022 Cesanta Software Limited
# Mail: support@cesanta.com
#
# SPDX-License-Identifier: GPL2.0 or commercial
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(http_server)
#add_definitions(-DMG_ENABLE_LINES=1)
add_definitions(-DMG_ENABLE_MBEDTLS=1 -DMG_MBEDTLS_DEBUG_LEVEL=4)
target_sources(app PRIVATE src/main.c src/mongoose.c)

View File

@ -0,0 +1,16 @@
CWD = $(realpath $(CURDIR))
ZEPHYR_DIR ?= $(realpath ../../../../zephyrproject)
BOARD ?= nucleo_h743zi
example:
true
build:
cp ../../../mongoose.c ../../../mongoose.h src/
cd $(ZEPHYR_DIR) && west build -b $(BOARD) -p auto $(CWD)
flash:
cd $(ZEPHYR_DIR) && west flash
clean:
rm -rf */*/mongoose.*

View File

@ -0,0 +1,32 @@
CONFIG_NETWORKING=y
CONFIG_NET_IPV4=y
CONFIG_NET_IPV6=y
CONFIG_NET_TCP=y
CONFIG_NET_UDP=y
CONFIG_NET_DHCPV4=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POLL_MAX=32
CONFIG_POSIX_MAX_FDS=32
CONFIG_NET_CONFIG_SETTINGS=y
CONFIG_NET_LOG=y
CONFIG_LOG=y
CONFIG_ISR_STACK_SIZE=2048
CONFIG_MAIN_STACK_SIZE=16000
CONFIG_IDLE_STACK_SIZE=1024
CONFIG_MBEDTLS=y
CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=8192
CONFIG_MBEDTLS_PEM_CERTIFICATE_FORMAT=y
CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=y
CONFIG_MBEDTLS_ECP_ALL_ENABLED=y
CONFIG_MBEDTLS_TLS_VERSION_1_2=y
CONFIG_MINIMAL_LIBC_RAND=y
CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE=131072
CONFIG_FILE_SYSTEM_LITTLEFS=y
CONFIG_PRINTK=y
CONFIG_MBEDTLS_DEBUG=y
CONFIG_MBEDTLS_DEBUG_LEVEL=4

View File

@ -0,0 +1,115 @@
#ifndef CERTS_H_
#define CERTS_H_
static const char *s_ca =
"-\n"
"# Note: Amazon ATS endpoint uses this (2018/12/18)\n"
"Subject: C=US, O=Starfield Technologies, Inc., OU=Starfield Class 2 Certification Authority\n"
"Not Before: Jun 29 17:39:16 2004 GMT\n"
"Not After : Jun 29 17:39:16 2034 GMT\n"
"-----BEGIN CERTIFICATE-----\n"
"MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl\n"
"MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp\n"
"U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw\n"
"NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE\n"
"ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp\n"
"ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3\n"
"DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf\n"
"8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN\n"
"+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0\n"
"X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa\n"
"K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA\n"
"1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G\n"
"A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR\n"
"zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0\n"
"YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD\n"
"bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w\n"
"DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3\n"
"L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D\n"
"eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl\n"
"xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp\n"
"VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY\n"
"WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=\n"
"-----END CERTIFICATE-----\n"
"\n"
"# https://www.amazontrust.com/repository/\n"
"Subject: C = US, O = Amazon, CN = Amazon Root CA 1\n"
"Not Before: May 26 00:00:00 2015 GMT\n"
"Not After : Jan 17 00:00:00 2038 GMT\n"
"-----BEGIN CERTIFICATE-----\n"
"MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsF\n"
"ADA5MQswCQYDVQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6\n"
"b24gUm9vdCBDQSAxMB4XDTE1MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTEL\n"
"MAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZMBcGA1UEAxMQQW1hem9uIFJv\n"
"b3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALJ4gHHKeNXj\n"
"ca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgHFzZM\n"
"9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qw\n"
"IFAGbHrQgLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6\n"
"VOujw5H5SNz/0egwLX0tdHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L\n"
"93FcXmn/6pUCyziKrlA4b9v7LWIbxcceVOF34GfID5yHI9Y/QCB/IIDEgEw+OyQm\n"
"jgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC\n"
"AYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3DQEBCwUA\n"
"A4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDI\n"
"U5PMCCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUs\n"
"N+gDS63pYaACbvXy8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vv\n"
"o/ufQJVtMVT8QtPHRh8jrdkPSHCa2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU\n"
"5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2xJNDd2ZhwLnoQdeXeGADbkpy\n"
"rqXRfboQnoZsG4q5WTP468SQvvG5\n"
"-----END CERTIFICATE-----\n"
"\n"
"";
static const char *s_cert =
"-----BEGIN CERTIFICATE-----\n"
"MIIDWjCCAkKgAwIBAgIVAPoY7Fz1DxA+/VgB/GdsOXwg45cRMA0GCSqGSIb3DQEB\n"
"CwUAME0xSzBJBgNVBAsMQkFtYXpvbiBXZWIgU2VydmljZXMgTz1BbWF6b24uY29t\n"
"IEluYy4gTD1TZWF0dGxlIFNUPVdhc2hpbmd0b24gQz1VUzAeFw0yMjA0MTExMjQw\n"
"MTRaFw00OTEyMzEyMzU5NTlaMB4xHDAaBgNVBAMME0FXUyBJb1QgQ2VydGlmaWNh\n"
"dGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvwVAUCWq4PCS0bsU5\n"
"b4meX8klfoyp7yuSkHcPVhBv846TSIh5VeRSR68LOYAYRHaN6C2ybqhb5E42QKRX\n"
"SOA37OFXR3HvcbLF7c7BPkT13kFpymZJA+KUIPZ2Ki2zwWDKi6uP2lZfNxMv9xLo\n"
"8PGuWBCphzadbf4Hi4tGEs2BeXSXRCb4ZaI7gv3DdZHLHJuyrkF040E6flZrXmPv\n"
"dumvmszNZxWl8iIA68Pk7M1npXCr/za9CkIdoeSslKVBY4S0FNSISOxMCMqpV8fS\n"
"w4c8xQ0G4Whxgt1a6sGtm6TBGB1CjbAvQNyLWFeL2U8RRbG82xo5GYuemkaodCvH\n"
"/sBRAgMBAAGjYDBeMB8GA1UdIwQYMBaAFMdnILw/0ZLaKJ2dH2GZTXKu0ciZMB0G\n"
"A1UdDgQWBBQahyFNkNwZFKmVi+c6uWW9Iif95TAMBgNVHRMBAf8EAjAAMA4GA1Ud\n"
"DwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAb4Tlb2kvWcv5Dz4kCc43AFbA\n"
"Jv1MHwltznedpiyAyqXGU8s6UJCrhHKpjABHHcigkCD3iUlxLMTNhzEuTNBR1zfS\n"
"PMVP5EVmzOSRGvQNvhURRGkGVlNytv4VHTzaZUcuqhqNvw/Slvo0i2vlAPK0VIKQ\n"
"EPNle86zpUypAf2UlyrOT5vD1s7x5HmoHiKdUMqEiB6G/rack4vtUpA2V8fugKrH\n"
"QmBVXWHqTbpTUbqPk3PxmV1zqt5C9ZRVjjIDvW+Hl2zfVEoVq8l6BcLZmxFUnvA/\n"
"/aBWQ3k+V1fg3dUck3OCRGMsYYgBsvey6X+9oa+JFZh5mFtjA45C2SRtYtLesQ==\n"
"-----END CERTIFICATE-----\n"
"";
static const char *s_key =
"-----BEGIN RSA PRIVATE KEY-----\n"
"MIIEowIBAAKCAQEAr8FQFAlquDwktG7FOW+Jnl/JJX6Mqe8rkpB3D1YQb/OOk0iI\n"
"eVXkUkevCzmAGER2jegtsm6oW+RONkCkV0jgN+zhV0dx73Gyxe3OwT5E9d5Bacpm\n"
"SQPilCD2diots8Fgyourj9pWXzcTL/cS6PDxrlgQqYc2nW3+B4uLRhLNgXl0l0Qm\n"
"+GWiO4L9w3WRyxybsq5BdONBOn5Wa15j73bpr5rMzWcVpfIiAOvD5OzNZ6Vwq/82\n"
"vQpCHaHkrJSlQWOEtBTUiEjsTAjKqVfH0sOHPMUNBuFocYLdWurBrZukwRgdQo2w\n"
"L0Dci1hXi9lPEUWxvNsaORmLnppGqHQrx/7AUQIDAQABAoIBAHX/c6QALoZC2uHI\n"
"/ODy4ZJS/NkPfaEZ0kc0drr1LVP8UVzQ9c+AuyoCtqLyl+2zCWV83DFP2fjX7yq9\n"
"e5iedOsXPrM6ZGQ+EaiRYJ6dD++CqKg+Gy4qTZTmDJKI/uYQjsttumF6VULX1yn8\n"
"19VM7vX+ajFndmN71XF7XqZNOWwS4kEk5znQ7oesMOzPazRDsdJmCCnvVc4h99jJ\n"
"IYOtCs9s2aLoSD/7lATKaVquuRNBdkcWmKqc3vYMUQwjk14ID7t31TBZtlLJC+Df\n"
"tn+LCH1C0cuTq86VV17lc9ObTj/xkc8tb3OEYAv8E7rOioJVKU6EMViGa0oJk1+f\n"
"tW6hqYECgYEA1GR0z69HzeGZun2ZbjX7DC8EPAI4PZY5EZ1O7RZQorLLKP7R+9sg\n"
"KtgSJwtKAgpi84I0iuMbE2VciCYfXao+UpWLxkAPZkAt6qcMGJ0kYVd42n0Rwesh\n"
"8bd/r6ojSnj0DY7zAsoXctdQiNDiGmCyrDvWqmGuM6XCDcuzlG4LbkMCgYEA09cq\n"
"tSDyZowGWafKIDW4JXLE3PQdJStM3hAmNisrx0mRB7HmNgs3gR4/L4giZnE2hI+O\n"
"6IofiLjDjSmenWkvWw8Jy/QrhWpAuWlfeEpHaN910IXemFyqzMz0jL9s/Bn4BOYQ\n"
"WiqV19Pj4EjSrum76e17mBNq8vc72C4wXS3gj9sCgYB2q/KAoIVUSbtlcgwqgkrV\n"
"Uefhx7O45ZjZeLXCzvcbER9mtoqJWLQufDAYVLxzS25idNv6xk44ligPgo1//kF4\n"
"T0qb6OsxzKZbOB8QGa1cHk3OdpdXbJO4xTi45C13zQFAGiE568USS7AZ4eyTpHfw\n"
"uDaHWLDG9tTodGrQgnQslQKBgFvdPwP1Gakmp8pRXPHC2exDbON0aP8pW9ggoLF0\n"
"3zM4z8/Kcc6V5qfzeese2ewaxE2QA6UL4MjldsfMeKBCcOrIBrOPWyAsB41gCKqd\n"
"a4IrBWg75V+lL9xINPSkPprEmC1np0eyl/BUTsmASvzXF0pGVgaIxSQ/2o/Q1+BQ\n"
"eMVpAoGBALiFGVLxSow60Cve7BRaUuKa+pfqPeuCW+bSLD5hy6hQeHInUtRJT7tW\n"
"NFC8y7zUpKRCENCqXbBsYe1x2HEdGtDv9NV4vjcvF63Dj90ZZVXQkSiLXkWvJu76\n"
"7sRX7dX2coR6LlQ+zwwkyDIh2wP2MAWXbYLeG8xbLp8a2ybueSZl\n"
"-----END RSA PRIVATE KEY-----\n"
"";
#endif

View File

@ -0,0 +1,109 @@
// Copyright (c) 2020 Cesanta Software Limited
// All rights reserved
#include "mongoose.h"
#include "certs.h"
struct mg_mgr mgr;
static const char *s_debug_level = "3";
static time_t s_boot_timestamp = 0;
static struct mg_connection *s_sntp_conn = NULL;
static const char *s_url = "mqtts://a3nkain3cvvy7l-ats.iot.us-east-1.amazonaws.com";
static const char *s_rx_topic = "d/rx";
static const char *s_tx_topic = "d/tx";
static int s_qos = 1;
static int s_connected = 0;
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
if (ev == MG_EV_OPEN) {
// c->is_hexdumping = 1;
} else if (ev == MG_EV_ERROR) {
// On error, log error message
MG_ERROR(("%p %s", c->fd, (char *) ev_data));
} else if (ev == MG_EV_CONNECT) {
// Set up 2-way TLS that is required by AWS IoT
struct mg_tls_opts opts = {
.ca = s_ca, .cert = s_cert, .certkey = s_key};
mg_tls_init(c, &opts);
} else if (ev == MG_EV_MQTT_OPEN) {
// MQTT connect is successful
struct mg_str topic = mg_str(s_rx_topic);
MG_INFO(("Connected to %s", s_url));
MG_INFO(("Subscribing to %s", s_rx_topic));
mg_mqtt_sub(c, topic, s_qos);
c->label[0] = 'X'; // Set a label that we're logged in
} else if (ev == MG_EV_MQTT_MSG) {
// When we receive MQTT message, print it
struct mg_mqtt_message *mm = (struct mg_mqtt_message *) ev_data;
MG_INFO(("Received on %.*s : %.*s", (int) mm->topic.len, mm->topic.ptr,
(int) mm->data.len, mm->data.ptr));
} else if (ev == MG_EV_POLL && c->label[0] == 'X') {
static unsigned long prev_second;
unsigned long now_second = (*(unsigned long *) ev_data) / 1000;
if (now_second != prev_second) {
struct mg_str topic = mg_str(s_tx_topic), data = mg_str("{\"a\":123}");
MG_INFO(("Publishing to %s", s_tx_topic));
mg_mqtt_pub(c, topic, data, s_qos, false);
prev_second = now_second;
}
}
}
// We have no valid system time(), and we need it for TLS. Implement it
time_t time(time_t *tp) {
time_t t = s_boot_timestamp + k_uptime_get() / 1000;
if (tp != NULL) *tp = t;
return t;
}
// SNTP callback. Modifies s_boot_timestamp, to make time() correct
static void sfn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
if (ev == MG_EV_SNTP_TIME) {
int64_t t = *(int64_t *) ev_data;
MG_INFO(("Got SNTP time: %lld ms from epoch", t));
s_boot_timestamp = (time_t) ((t - mg_millis()) / 1000);
// We need correct time in order to get HTTPs working, therefore,
// making https request from SMTP callback
if(!s_connected) {
MG_INFO(("Connecting to : [%s]", s_url));
struct mg_mqtt_opts opts = {.clean = true};
mg_mqtt_connect(&mgr, s_url, &opts, fn, NULL); // Create client connection
s_connected = 1;
}
} else if (ev == MG_EV_CLOSE) {
s_sntp_conn = NULL;
}
}
// Periodic timer syncs time via SNTP
static void timer_fn(void *arg) {
struct mg_mgr *mgr = (struct mg_mgr *) arg;
if (s_sntp_conn == NULL) s_sntp_conn = mg_sntp_connect(mgr, NULL, sfn, NULL);
if (s_boot_timestamp < 9999) mg_sntp_send(s_sntp_conn, time(NULL));
}
// Use Zephyr's printk() for Mongooose MG_* logging
static void logfn(const void *ptr, size_t len, void *userdata) {
printk("%.*s", (int) len, (char *) ptr);
}
int main(int argc, char *argv[]) {
mg_log_set(s_debug_level);
mg_log_set_callback(logfn, NULL);
mg_mgr_init(&mgr);
struct mg_timer t;
mg_timer_init(&t, 5000, MG_TIMER_REPEAT | MG_TIMER_RUN_NOW, timer_fn, &mgr);
// Start infinite event loop
MG_INFO(("Mongoose version : v%s", MG_VERSION));
mg_http_connect(&mgr, s_url, fn, NULL); // Create client connection
for (;;) mg_mgr_poll(&mgr, 1000);
mg_mgr_free(&mgr);
return 0;
}

View File

@ -0,0 +1,11 @@
# Copyright (c) 2022 Cesanta Software Limited
# Mail: support@cesanta.com
#
# SPDX-License-Identifier: GPL2.0 or commercial
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(http_server)
#add_definitions(-DMG_ENABLE_LINES=1)
add_definitions(-DMG_ENABLE_MBEDTLS=1)
target_sources(app PRIVATE src/main.c src/mongoose.c)

View File

@ -0,0 +1,16 @@
CWD = $(realpath $(CURDIR))
ZEPHYR_DIR ?= $(realpath ../../../../zephyrproject)
BOARD ?= nucleo_h743zi
example:
true
build:
cp ../../../mongoose.c ../../../mongoose.h src/
cd $(ZEPHYR_DIR) && west build -b $(BOARD) -p auto $(CWD)
flash:
cd $(ZEPHYR_DIR) && west flash
clean:
rm -rf */*/mongoose.*

View File

@ -0,0 +1,27 @@
CONFIG_NETWORKING=y
CONFIG_NET_IPV4=y
CONFIG_NET_IPV6=y
CONFIG_NET_TCP=y
CONFIG_NET_UDP=y
CONFIG_NET_DHCPV4=y
CONFIG_NET_SOCKETS=y
CONFIG_NET_SOCKETS_POLL_MAX=32
CONFIG_POSIX_MAX_FDS=32
CONFIG_NET_CONFIG_SETTINGS=y
CONFIG_NET_LOG=y
CONFIG_LOG=y
CONFIG_ISR_STACK_SIZE=2048
CONFIG_MAIN_STACK_SIZE=8192
CONFIG_IDLE_STACK_SIZE=1024
CONFIG_MBEDTLS=y
CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=2048
CONFIG_MBEDTLS_PEM_CERTIFICATE_FORMAT=y
CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=y
CONFIG_MBEDTLS_ECP_ALL_ENABLED=y
CONFIG_MINIMAL_LIBC_RAND=y
CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE=32756
CONFIG_FILE_SYSTEM_LITTLEFS=y

View File

@ -0,0 +1,24 @@
#ifndef CERTS_H_
#define CERTS_H_
static const char *s_ssl_cert =
"-----BEGIN CERTIFICATE-----\r\n" \
"MIIBhzCCASygAwIBAgIUbnMoVd8TtWH1T09dANkK2LU6IUswCgYIKoZIzj0EAwIw\r\n" \
"RDELMAkGA1UEBhMCSUUxDzANBgNVBAcMBkR1YmxpbjEQMA4GA1UECgwHQ2VzYW50\r\n" \
"YTESMBAGA1UEAwwJVGVzdCBSb290MB4XDTIwMDUwOTIxNTE0OVoXDTMwMDUwOTIx\r\n" \
"NTE0OVowETEPMA0GA1UEAwwGc2VydmVyMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD\r\n" \
"QgAEkuBGnInDN6l06zVVQ1VcrOvH5FDu9MC6FwJc2e201P8hEpq0Q/SJS2nkbSuW\r\n" \
"H/wBTTBaeXN2uhlBzMUWK790KKMvMC0wCQYDVR0TBAIwADALBgNVHQ8EBAMCA6gw\r\n" \
"EwYDVR0lBAwwCgYIKwYBBQUHAwEwCgYIKoZIzj0EAwIDSQAwRgIhAPo6xx7LjCdZ\r\n" \
"QY133XvLjAgVFrlucOZHONFVQuDXZsjwAiEAzHBNligA08c5U3SySYcnkhurGg50\r\n" \
"BllCI0eYQ9ggp/o=\r\n" \
"-----END CERTIFICATE-----\r\n";
static const char *s_ssl_key =
"-----BEGIN PRIVATE KEY-----\r\n" \
"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQglNni0t9Dg9icgG8w\r\n" \
"kbfxWSS+TuNgbtNybIQXcm3NHpmhRANCAASS4EacicM3qXTrNVVDVVys68fkUO70\r\n" \
"wLoXAlzZ7bTU/yESmrRD9IlLaeRtK5Yf/AFNMFp5c3a6GUHMxRYrv3Qo\r\n" \
"-----END PRIVATE KEY-----\r\n";
#endif

View File

@ -0,0 +1,92 @@
// Copyright (c) 2020 Cesanta Software Limited
// All rights reserved
#include "mongoose.h"
#include "certs.h"
static const char *s_debug_level = "3";
static const char *s_web_dir = "/";
static const char *s_ws_addr = "ws://0.0.0.0:8000";
static const char *s_wss_addr = "wss://0.0.0.0:8443";
static time_t s_boot_timestamp = 0;
static struct mg_connection *s_sntp_conn = NULL;
// This RESTful server implements the following endpoints:
// /websocket - upgrade to Websocket, and implement websocket echo server
// /api/rest - respond with JSON string {"result": 123}
static void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
if (ev == MG_EV_OPEN) {
c->is_hexdumping = 1;
} else if (ev == MG_EV_ACCEPT && fn_data != NULL) {
struct mg_tls_opts opts = {.cert = s_ssl_cert, .certkey = s_ssl_key};
mg_tls_init(c, &opts);
} else if (ev == MG_EV_HTTP_MSG) {
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
if (mg_http_match_uri(hm, "/websocket")) {
// Upgrade to websocket. From now on, a connection is a full-duplex
// Websocket connection, which will receive MG_EV_WS_MSG events.
mg_ws_upgrade(c, hm, NULL);
} else if (mg_http_match_uri(hm, "/rest")) {
// Serve REST response
mg_http_reply(c, 200, "", "{\"result\": %d}\n", 123);
}
} else if (ev == MG_EV_WS_MSG) {
// Got websocket frame. Received data is wm->data. Echo it back!
struct mg_ws_message *wm = (struct mg_ws_message *) ev_data;
mg_ws_send(c, wm->data.ptr, wm->data.len, WEBSOCKET_OP_TEXT);
}
(void) fn_data;
}
// We have no valid system time(), and we need it for TLS. Implement it
time_t time(time_t *tp) {
time_t t = s_boot_timestamp + k_uptime_get() / 1000;
if (tp != NULL) *tp = t;
return t;
}
// SNTP callback. Modifies s_boot_timestamp, to make time() correct
static void sfn(struct mg_connection *c, int ev, void *ev_data, void *fn_data) {
if (ev == MG_EV_SNTP_TIME) {
int64_t t = *(int64_t *) ev_data;
MG_INFO(("Got SNTP time: %lld ms from epoch", t));
s_boot_timestamp = (time_t) ((t - mg_millis()) / 1000);
} else if (ev == MG_EV_CLOSE) {
s_sntp_conn = NULL;
}
}
// Periodic timer syncs time via SNTP
static void timer_fn(void *arg) {
struct mg_mgr *mgr = (struct mg_mgr *) arg;
if (s_sntp_conn == NULL) s_sntp_conn = mg_sntp_connect(mgr, NULL, sfn, NULL);
if (s_boot_timestamp < 9999) mg_sntp_send(s_sntp_conn, time(NULL));
}
// Use Zephyr's printk() for Mongooose MG_* logging
static void logfn(const void *ptr, size_t len, void *userdata) {
printk("%.*s", (int) len, (char *) ptr);
}
int main(int argc, char *argv[]) {
struct mg_mgr mgr;
mg_log_set(s_debug_level);
mg_log_set_callback(logfn, NULL);
mg_mgr_init(&mgr);
mg_http_listen(&mgr, s_ws_addr, fn, NULL);
mg_http_listen(&mgr, s_wss_addr, fn, &mgr);
struct mg_timer t;
mg_timer_init(&t, 5000, MG_TIMER_REPEAT | MG_TIMER_RUN_NOW, timer_fn, &mgr);
// Start infinite event loop
MG_INFO(("Mongoose version : v%s", MG_VERSION));
MG_INFO(("Listening on : %s", s_ws_addr));
MG_INFO(("Listening on : %s", s_wss_addr));
MG_INFO(("Web root : [%s]", s_web_dir));
for (;;) mg_mgr_poll(&mgr, 1000);
mg_mgr_free(&mgr);
return 0;
}