diff --git a/examples/esp32/main/main.c b/examples/esp32/main/main.c index 5b9e4dc3..1b92198a 100644 --- a/examples/esp32/main/main.c +++ b/examples/esp32/main/main.c @@ -3,8 +3,8 @@ #include "mongoose.h" -#define WIFI_SSID "VMDF554B9" // SET THIS! -#define WIFI_PASS "Mp7wjmamPafa" // SET THIS! +#define WIFI_SSID "WIFI_NETWORK" // SET THIS! +#define WIFI_PASS "WIFI_PASSWORD" // SET THIS! #define SERVER_URL "http://0.0.0.0:80" #define CLIENT_URL "http://info.cern.ch" @@ -12,7 +12,7 @@ // Event handler for an server (accepted) connection 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, "", "Hello from ESP32!\n"); + mg_http_reply(c, 200, "", "Hello from ESP!\n"); } } diff --git a/examples/esp32/main/wifi.c b/examples/esp32/main/wifi.c index fa080b6b..c7e3c0f9 100644 --- a/examples/esp32/main/wifi.c +++ b/examples/esp32/main/wifi.c @@ -1,13 +1,13 @@ // Code taken from the ESP32 IDF WiFi station Example #include -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "freertos/event_groups.h" -#include "esp_system.h" -#include "esp_wifi.h" #include "esp_event.h" #include "esp_log.h" +#include "esp_system.h" +#include "esp_wifi.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/task.h" #include "nvs_flash.h" #include "lwip/err.h" @@ -17,11 +17,12 @@ static EventGroupHandle_t s_wifi_event_group; -/* The event group allows multiple bits for each event, but we only care about two events: +/* The event group allows multiple bits for each event, but we only care about + * two events: * - we are connected to the AP with an IP * - we failed to connect after the maximum amount of retries */ #define WIFI_CONNECTED_BIT BIT0 -#define WIFI_FAIL_BIT BIT1 +#define WIFI_FAIL_BIT BIT1 static int s_retry_num = 0; @@ -47,7 +48,7 @@ static void event_handler(void *arg, esp_event_base_t event_base, } } -void wifi_init(const char *ssid, const char *pass, void (*fn)(void)) { +void wifi_init(const char *ssid, const char *pass) { esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { diff --git a/examples/esp8266/Makefile b/examples/esp8266/Makefile new file mode 100644 index 00000000..8fb09615 --- /dev/null +++ b/examples/esp8266/Makefile @@ -0,0 +1,10 @@ +THISDIR = $(realpath $(CURDIR)) +ROOTDIR = $(realpath $(CURDIR)/../..) + +all: example + +example: src/main/main.c src/main/wifi.c Makefile + docker run --rm -v $(ROOTDIR):$(ROOTDIR) -w $(THISDIR) docker.io/mdashnet/8266 make -C src defconfig app + +clean: + rm -rf $(PROG) *.o *.dSYM *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb mongoose mongoose_* mongoose.* src/build src/sdkconfig diff --git a/examples/esp8266/src/Makefile b/examples/esp8266/src/Makefile new file mode 100644 index 00000000..6c3603d9 --- /dev/null +++ b/examples/esp8266/src/Makefile @@ -0,0 +1,9 @@ +# +# This is a project Makefile. It is assumed the directory this Makefile resides in is a +# project subdirectory. +# + +PROJECT_NAME := mongoose-example + +include $(IDF_PATH)/make/project.mk + diff --git a/examples/esp8266/src/main/component.mk b/examples/esp8266/src/main/component.mk new file mode 100644 index 00000000..cc3c9381 --- /dev/null +++ b/examples/esp8266/src/main/component.mk @@ -0,0 +1,10 @@ + # + # Main component makefile. + # + # This Makefile can be left empty. By default, it will take the sources in the + # src/ directory, compile them and link them into lib(subdirectory_name).a + # in the build directory. This behaviour is entirely configurable, + # please read the ESP-IDF documents if you need to do this. +# + +COMPONENT_INCLUDES += ../../../../.. diff --git a/examples/esp8266/src/main/main.c b/examples/esp8266/src/main/main.c new file mode 100644 index 00000000..1b92198a --- /dev/null +++ b/examples/esp8266/src/main/main.c @@ -0,0 +1,54 @@ +// Copyright (c) 2020 Cesanta Software Limited +// All rights reserved + +#include "mongoose.h" + +#define WIFI_SSID "WIFI_NETWORK" // SET THIS! +#define WIFI_PASS "WIFI_PASSWORD" // SET THIS! + +#define SERVER_URL "http://0.0.0.0:80" +#define CLIENT_URL "http://info.cern.ch" + +// Event handler for an server (accepted) connection +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, "", "Hello from ESP!\n"); + } +} + +// Event handler for a client connection - fetch the first web page in history +// To enable TLS for HTTP, +// 1. Copy "ca.pem" file to the ESP32 flash FS +// 2. Add TLS init snippet for the connection, see examples/http-client +static void cb2(struct mg_connection *c, int ev, void *ev_data, void *fn_data) { + if (ev == MG_EV_CONNECT) { + struct mg_str s = mg_url_host(CLIENT_URL); + mg_printf(c, "GET / HTTP/1.0\r\nHost: %.*s\r\n\r\n", (int) s.len, s.ptr); + } else if (ev == MG_EV_HTTP_MSG) { + struct mg_http_message *hm = ev_data; // Print HTTP response + LOG(LL_INFO, ("Fetched:\n%.*s", (int) hm->message.len, hm->message.ptr)); + c->is_closing = 1; + } +} + +// Called after we're connected to WiFi network +static void run_mongoose(void) { + struct mg_mgr mgr; + mg_log_set("3"); + mg_mgr_init(&mgr); + mg_http_listen(&mgr, SERVER_URL, cb, &mgr); // Listening server + mg_http_connect(&mgr, CLIENT_URL, cb2, &mgr); // Example client + LOG(LL_INFO, ("Starting Mongoose web server v%s", MG_VERSION)); + for (;;) mg_mgr_poll(&mgr, 1000); + mg_mgr_free(&mgr); +} + +void app_main(void) { + // Setup wifi. This function is implemented in wifi.c + // It blocks until connected to the configured WiFi network + void wifi_init(const char *ssid, const char *pass); + wifi_init(WIFI_SSID, WIFI_PASS); + + // Done connecting to WiFi, now start HTTP server + run_mongoose(); +} diff --git a/examples/esp8266/src/main/mongoose.c b/examples/esp8266/src/main/mongoose.c new file mode 120000 index 00000000..7a2752cb --- /dev/null +++ b/examples/esp8266/src/main/mongoose.c @@ -0,0 +1 @@ +../../../../mongoose.c \ No newline at end of file diff --git a/examples/esp8266/src/main/wifi.c b/examples/esp8266/src/main/wifi.c new file mode 100644 index 00000000..28bff25a --- /dev/null +++ b/examples/esp8266/src/main/wifi.c @@ -0,0 +1,86 @@ +#include +#include "esp_event.h" +#include "esp_log.h" +#include "esp_system.h" +#include "esp_wifi.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/task.h" +#include "nvs_flash.h" + +#include "lwip/err.h" +#include "lwip/sys.h" + +#include "mongoose.h" + +static EventGroupHandle_t s_wifi_event_group; + +/* The event group allows multiple bits for each event, but we only care about + * two events: + * - we are connected to the AP with an IP + * - we failed to connect after the maximum amount of retries */ +#define WIFI_CONNECTED_BIT BIT0 +#define WIFI_FAIL_BIT BIT1 + +static int s_retry_num = 0; + +static void event_handler(void *arg, esp_event_base_t event_base, + int32_t event_id, void *event_data) { + if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) { + esp_wifi_connect(); + } else if (event_base == WIFI_EVENT && + event_id == WIFI_EVENT_STA_DISCONNECTED) { + if (s_retry_num < 3) { + esp_wifi_connect(); + s_retry_num++; + LOG(LL_DEBUG, ("retry to connect to the AP")); + } else { + xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT); + } + LOG(LL_ERROR, ("connect to the AP fail")); + } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) { + ip_event_got_ip_t *event = (ip_event_got_ip_t *) event_data; + LOG(LL_INFO, ("got ip:%s", ip4addr_ntoa(&event->ip_info.ip))); + s_retry_num = 0; + xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); + } +} + +void wifi_init(const char *ssid, const char *pass) { + s_wifi_event_group = xEventGroupCreate(); + tcpip_adapter_init(); + ESP_ERROR_CHECK(esp_event_loop_create_default()); + wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); + ESP_ERROR_CHECK(esp_wifi_init(&cfg)); + ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, + &event_handler, NULL)); + ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, + &event_handler, NULL)); + + wifi_config_t c = {}; + snprintf((char *) c.sta.ssid, sizeof(c.sta.ssid), "%s", ssid); + snprintf((char *) c.sta.password, sizeof(c.sta.password), "%s", pass); + if (pass != NULL && pass[0] != '\0') { + c.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK; + } + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &c)); + ESP_ERROR_CHECK(esp_wifi_start()); + EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, + WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, + pdFALSE, pdFALSE, portMAX_DELAY); + + if (bits & WIFI_CONNECTED_BIT) { + LOG(LL_INFO, ("connected to ap SSID:%s password:%s", ssid, pass)); + } else if (bits & WIFI_FAIL_BIT) { + LOG(LL_ERROR, ("Failed to connect to SSID:%s, password:%s", ssid, pass)); + } else { + LOG(LL_ERROR, ("UNEXPECTED EVENT")); + } + + ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, + &event_handler)); + ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, + &event_handler)); + vEventGroupDelete(s_wifi_event_group); +} diff --git a/mongoose.c b/mongoose.c index 76d3158b..7bbe2efc 100644 --- a/mongoose.c +++ b/mongoose.c @@ -3810,7 +3810,8 @@ unsigned long mg_millis(void) { #elif MG_ARCH == MG_ARCH_ESP32 return esp_timer_get_time() / 1000; #elif MG_ARCH == MG_ARCH_ESP8266 - return system_get_time() / 1000; + // return system_get_time() / 1000; + return xTaskGetTickCount() * portTICK_PERIOD_MS; #elif MG_ARCH == MG_ARCH_FREERTOS return xTaskGetTickCount() * portTICK_PERIOD_MS; #else diff --git a/mongoose.h b/mongoose.h index ac184ad4..854630f0 100644 --- a/mongoose.h +++ b/mongoose.h @@ -61,10 +61,10 @@ #define MG_ARCH MG_ARCH_NXP_KINETIS #elif defined(PIC32) #define MG_ARCH MG_ARCH_PIC32 -#elif defined(ESP_PLATFORM) -#define MG_ARCH MG_ARCH_ESP32 #elif defined(ICACHE_FLASH) || defined(ICACHE_RAM_ATTR) #define MG_ARCH MG_ARCH_ESP8266 +#elif defined(ESP_PLATFORM) +#define MG_ARCH MG_ARCH_ESP32 #elif defined(TARGET_IS_TM4C129_RA0) || defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define MG_ARCH MG_ARCH_TM4C129 @@ -128,26 +128,11 @@ #if MG_ARCH == MG_ARCH_ESP8266 #include +#include +#include #include #include -#include - #define MG_DIRSEP '/' -#ifndef PATH_MAX -#define PATH_MAX 128 -#endif -#define MG_ENABLE_LWIP 1 -#define LWIP_TIMEVAL_PRIVATE 0 // struct timeval is defined in sys/time.h - -#if LWIP_SOCKET -#include -#else -#undef LWIP_SOCKET -#define LWIP_SOCKET 1 -#include // Source sockaddr_in anyway -#undef LWIP_SOCKET -#define LWIP_SOCKET 0 -#endif #endif diff --git a/src/arch.h b/src/arch.h index 8ddcff7a..18221626 100644 --- a/src/arch.h +++ b/src/arch.h @@ -42,10 +42,10 @@ #define MG_ARCH MG_ARCH_NXP_KINETIS #elif defined(PIC32) #define MG_ARCH MG_ARCH_PIC32 -#elif defined(ESP_PLATFORM) -#define MG_ARCH MG_ARCH_ESP32 #elif defined(ICACHE_FLASH) || defined(ICACHE_RAM_ATTR) #define MG_ARCH MG_ARCH_ESP8266 +#elif defined(ESP_PLATFORM) +#define MG_ARCH MG_ARCH_ESP32 #elif defined(TARGET_IS_TM4C129_RA0) || defined(TARGET_IS_TM4C129_RA1) || \ defined(TARGET_IS_TM4C129_RA2) #define MG_ARCH MG_ARCH_TM4C129 diff --git a/src/arch_esp8266.h b/src/arch_esp8266.h index 2e1801d3..243b5831 100644 --- a/src/arch_esp8266.h +++ b/src/arch_esp8266.h @@ -3,25 +3,10 @@ #if MG_ARCH == MG_ARCH_ESP8266 #include +#include +#include #include #include -#include - #define MG_DIRSEP '/' -#ifndef PATH_MAX -#define PATH_MAX 128 -#endif -#define MG_ENABLE_LWIP 1 -#define LWIP_TIMEVAL_PRIVATE 0 // struct timeval is defined in sys/time.h - -#if LWIP_SOCKET -#include -#else -#undef LWIP_SOCKET -#define LWIP_SOCKET 1 -#include // Source sockaddr_in anyway -#undef LWIP_SOCKET -#define LWIP_SOCKET 0 -#endif #endif diff --git a/src/util.c b/src/util.c index c5180f26..b428ac63 100644 --- a/src/util.c +++ b/src/util.c @@ -269,7 +269,8 @@ unsigned long mg_millis(void) { #elif MG_ARCH == MG_ARCH_ESP32 return esp_timer_get_time() / 1000; #elif MG_ARCH == MG_ARCH_ESP8266 - return system_get_time() / 1000; + // return system_get_time() / 1000; + return xTaskGetTickCount() * portTICK_PERIOD_MS; #elif MG_ARCH == MG_ARCH_FREERTOS return xTaskGetTickCount() * portTICK_PERIOD_MS; #else