From bb0bc41f9949f4ef6e96b4edf7506cc15116cf06 Mon Sep 17 00:00:00 2001 From: Sergey Lyubka Date: Thu, 31 Mar 2022 16:58:27 +0100 Subject: [PATCH] Add zephyr example skeleton --- examples/zephyr/Makefile | 9 +++ examples/zephyr/http-server/CMakeLists.txt | 13 ++++ examples/zephyr/http-server/prj.conf | 19 +++++ examples/zephyr/http-server/src/main.c | 83 ++++++++++++++++++++++ mongoose.c | 2 +- src/net.c | 2 +- 6 files changed, 126 insertions(+), 2 deletions(-) create mode 100644 examples/zephyr/Makefile create mode 100644 examples/zephyr/http-server/CMakeLists.txt create mode 100644 examples/zephyr/http-server/prj.conf create mode 100644 examples/zephyr/http-server/src/main.c diff --git a/examples/zephyr/Makefile b/examples/zephyr/Makefile new file mode 100644 index 00000000..4bd5b3e1 --- /dev/null +++ b/examples/zephyr/Makefile @@ -0,0 +1,9 @@ +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 diff --git a/examples/zephyr/http-server/CMakeLists.txt b/examples/zephyr/http-server/CMakeLists.txt new file mode 100644 index 00000000..0fa5794c --- /dev/null +++ b/examples/zephyr/http-server/CMakeLists.txt @@ -0,0 +1,13 @@ +# 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_SSI=0) + +target_sources(app PRIVATE src/main.c src/mongoose.c) diff --git a/examples/zephyr/http-server/prj.conf b/examples/zephyr/http-server/prj.conf new file mode 100644 index 00000000..d6d84d98 --- /dev/null +++ b/examples/zephyr/http-server/prj.conf @@ -0,0 +1,19 @@ +# networking +CONFIG_NETWORKING=y +CONFIG_NET_IPV4=y +# CONFIG_NET_IPV6 is not set +CONFIG_NET_TCP=y +CONFIG_NET_SOCKETS=y +CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE=16384 +CONFIG_NET_TX_STACK_SIZE=2048 +CONFIG_NET_RX_STACK_SIZE=2048 +CONFIG_ISR_STACK_SIZE=2048 +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_IDLE_STACK_SIZE=1024 +CONFIG_NET_CONFIG_SETTINGS=y +#CONFIG_NET_CONFIG_MY_IPV4_ADDR="192.0.2.1" +#CONFIG_NET_CONFIG_MY_IPV4_NETMASK="255.255.255.0" +#CONFIG_NET_CONFIG_MY_IPV4_GW="192.0.2.2" +CONFIG_NET_CONFIG_MY_IPV4_ADDR="169.254.240.10" +CONFIG_NET_CONFIG_MY_IPV4_NETMASK="255.255.0.0" +CONFIG_NET_CONFIG_MY_IPV4_GW="169.254.240.5" diff --git a/examples/zephyr/http-server/src/main.c b/examples/zephyr/http-server/src/main.c new file mode 100644 index 00000000..4f0d1f8d --- /dev/null +++ b/examples/zephyr/http-server/src/main.c @@ -0,0 +1,83 @@ +// Copyright (c) 2020 Cesanta Software Limited +// All rights reserved + +#include "mongoose.h" + +static const char *s_debug_level = "3"; +static const char *s_root_dir = "."; +static const char *s_listening_address = "http://0.0.0.0:8000"; +static time_t s_boot_timestamp = 0; +static struct mg_connection *s_sntp_conn = NULL; + +// Event handler for the listening connection. +// Simply serve static files from `s_root_dir` +static void cb(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { + if (ev == MG_EV_HTTP_MSG) { + mg_http_reply(c, 200, NULL, "hi\n"); +#if 0 + struct mg_http_message *hm = ev_data, tmp = {0}; + struct mg_str unknown = mg_str_n("?", 1), *cl; + struct mg_http_serve_opts opts = {0}; + opts.root_dir = s_root_dir; + mg_http_serve_dir(c, hm, &opts); + mg_http_parse((char *) c->send.buf, c->send.len, &tmp); + cl = mg_http_get_header(&tmp, "Content-Length"); + if (cl == NULL) cl = &unknown; + MG_INFO(("%.*s %.*s %.*s %.*s", (int) hm->method.len, hm->method.ptr, + (int) hm->uri.len, hm->uri.ptr, (int) tmp.uri.len, tmp.uri.ptr, + (int) cl->len, cl->ptr)); +#endif + } else if (ev == MG_EV_OPEN) { + c->is_hexdumping = 1; + } + (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; +} + +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; + } +} + +static void timer_fn(void *arg) { + struct mg_mgr *mgr = (struct mg_mgr *) arg; + return; + 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)); +} + +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_listening_address, cb, &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_listening_address)); + MG_INFO(("Web root : [%s]", s_root_dir)); + for (;;) mg_mgr_poll(&mgr, 1000); + mg_mgr_free(&mgr); + return 0; +} diff --git a/mongoose.c b/mongoose.c index dad28bf4..71e678f5 100644 --- a/mongoose.c +++ b/mongoose.c @@ -2799,7 +2799,7 @@ struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url, c->fn = fn; c->fn_data = fn_data; mg_call(c, MG_EV_OPEN, NULL); - MG_DEBUG(("%lu %s port %u", c->id, url, mg_ntohs(c->rem.port))); + MG_DEBUG(("%lu %s", c->id, url)); } return c; } diff --git a/src/net.c b/src/net.c index debbb62b..a706f139 100644 --- a/src/net.c +++ b/src/net.c @@ -198,7 +198,7 @@ struct mg_connection *mg_listen(struct mg_mgr *mgr, const char *url, c->fn = fn; c->fn_data = fn_data; mg_call(c, MG_EV_OPEN, NULL); - MG_DEBUG(("%lu %s port %u", c->id, url, mg_ntohs(c->rem.port))); + MG_DEBUG(("%lu %s", c->id, url)); } return c; }