diff --git a/Makefile b/Makefile index e9cebb7a..fc4f3bfb 100644 --- a/Makefile +++ b/Makefile @@ -144,7 +144,7 @@ mongoose.c: Makefile $(wildcard src/*) $(wildcard mip/*.c) (cat src/license.h; echo; echo '#include "mongoose.h"' ; (for F in src/*.c mip/*.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/config.h src/str.h src/fmt.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 mip/mip.h mip/driver_*.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_*.h src/config.h src/str.h src/fmt.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 mip/mip.h mip/driver_*.h | sed -e '/keep/! s,#include ".*,,' -e 's,^#pragma once,,'; echo; echo '#ifdef __cplusplus'; echo '}'; echo '#endif'; echo '#endif // MONGOOSE_H')> $@ clean: rm -rf $(PROG) *.exe *.o *.dSYM *_test* ut fuzzer *.gcov *.gcno *.gcda *.obj *.exe *.ilk *.pdb slow-unit* _CL_* infer-out data.txt crash-* test/packed_fs.c pack diff --git a/docs/README.md b/docs/README.md index c1da54f1..0ab37b19 100644 --- a/docs/README.md +++ b/docs/README.md @@ -267,20 +267,22 @@ files to the application's source tree. The `mongoose.c` and `mongoose.h` files are actually an amalgamation - non-amalgamated sources can be found at https://github.com/cesanta/mongoose/tree/master/src -Mongoose has two types of build constants (preprocessor definitions) that -affect the build: a target architecture, and tunables. In order to set the -option during build time, use the `-D OPTION` compiler flag: +Mongoose has 3 types of build constants (preprocessor definitions) that affect +the build: a target architecture/OS, target network stack, and tunables. In +order to set the option during build time, use the `-D OPTION` compiler flag: ```sh -$ cc app0.c mongoose.c # Use defaults! -$ cc app1.c mongoose.c -D MG_ENABLE_IPV6=1 # Build with IPv6 enabled -$ cc app2.c mongoose.c -D MG_ARCH=MG_ARCH_FREERTOS_LWIP # Set architecture -$ cc app3.c mongoose.c -D MG_ENABLE_SSI=0 -D MG_IO_SIZE=8192 # Multiple options +$ cc app.c mongoose.c # Use defaults! +$ cc app.c mongoose.c -D MG_ENABLE_IPV6=1 # Build with IPv6 enabled +$ cc app.c mongoose.c -D MG_ARCH=MG_ARCH_RTX # Set architecture +$ cc app.c mongoose.c -D MG_ENABLE_SSI=0 -D MG_IO_SIZE=8192 # Multiple options ``` -The list of supported architectures is defined in the [arch.h](https://github.com/cesanta/mongoose/blob/master/src/arch.h) -header file. Normally, there is no need to explicitly specify the architecture. -The architecture is guessed during the build, so setting it is not usually required. +The list of supported architectures is defined in the +[arch.h](https://github.com/cesanta/mongoose/blob/master/src/arch.h) header +file. Normally, there is no need to explicitly specify the architecture. The +architecture is guessed during the build, so setting it is not usually +required. | Name | Description | | ---- | ----------- | @@ -288,17 +290,26 @@ The architecture is guessed during the build, so setting it is not usually requi |MG_ARCH_WIN32 | Windows systems | |MG_ARCH_ESP32 | Espressif's ESP32 | |MG_ARCH_ESP8266 | Espressif's ESP8266 | -|MG_ARCH_FREERTOS_LWIP | All systems with FreeRTOS kernel and LwIP IP stack | -|MG_ARCH_FREERTOS_TCP | All systems with FreeRTOS kernel and FreeRTOS-Plus-TCP IP stack | +|MG_ARCH_FREERTOS | All systems with FreeRTOS kernel| |MG_ARCH_AZURERTOS | Microsoft Azure RTOS | -|MG_ARCH_RTX_LWIP | Keil RTX with LWIP TCP/IP stack | -|MG_ARCH_RTX | Keil RTX with MDK TCP/IP stack | +|MG_ARCH_RTX | Keil RTX | |MG_ARCH_ZEPHYR | Zephyr RTOS | |MG_ARCH_TIRTOS | TI RTOS | |MG_ARCH_RP2040 | RP2040 SDK | |MG_ARCH_NEWLIB | Bare ARM GCC | |MG_ARCH_CUSTOM | A custom architecture, discussed in the next section | +The network stack constants are listed below. Note that if a network stack +is not specified, then it is assumed that the target architecture supports +standard BSD socket API. + +| Name | Default | Description | +| ---- | -------- | ----------- | +|MG_ENABLE_LWIP | 0 | lwIP network stack | +|MG_ENABLE_FREERTOS_TCP | 0 | Amazon FreeRTOS-Plus-TCP network stack | +|MG_ENABLE_RL | 0 | Keil MDK network stack | +|MG_ENABLE_MIP | 0 | Built-in Mongoose network stack | + The other class of build constants is defined in [src/config.h](https://github.com/cesanta/mongoose/blob/master/src/config.h) together with their default values. These are tunables that include/exclude diff --git a/examples/stm32/nucleo-f429zi-baremetal/mcu.h b/examples/stm32/nucleo-f429zi-baremetal/mcu.h index d4f23d3d..3b226b7e 100644 --- a/examples/stm32/nucleo-f429zi-baremetal/mcu.h +++ b/examples/stm32/nucleo-f429zi-baremetal/mcu.h @@ -22,7 +22,7 @@ enum { APB1_PRE = 5 /* AHB clock / 4 */, APB2_PRE = 4 /* AHB clock / 2 */ }; enum { PLL_HSI = 16, PLL_M = 8, PLL_N = 180, PLL_P = 2 }; // Run at 180 Mhz //#define PLL_FREQ PLL_HSI #define PLL_FREQ (PLL_HSI * PLL_N / PLL_M / PLL_P) -#define FLASH_LATENCY 5 +#define FLASH_LATENCY 5 #define FREQ (PLL_FREQ * 1000000) static inline void spin(volatile uint32_t count) { @@ -175,9 +175,10 @@ static inline void uart_init(struct uart *uart, unsigned long baud) { gpio_init(tx, GPIO_MODE_AF, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, 0, af); gpio_init(rx, GPIO_MODE_AF, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH, 0, af); - uart->CR1 = 0; // Disable this UART - uart->BRR = FREQ / 4 / baud; // Baud rate x16 (with 4dp), "4" is APBx prescaler, different from APBx_PRE - // TODO(): make this configurable ? + uart->CR1 = 0; // Disable this UART + uart->BRR = FREQ / APB2_PRE / baud; // Baud rate x16 (with 4dp), "4" is APBx + // prescaler, different from APBx_PRE + // TODO(): make this configurable ? uart->CR1 |= BIT(13) | BIT(2) | BIT(3); // Set UE, RE, TE } static inline void uart_write_byte(struct uart *uart, uint8_t byte) { @@ -194,12 +195,13 @@ static inline uint8_t uart_read_byte(struct uart *uart) { return (uint8_t) (uart->DR & 255); } -static inline void clock_init(void) { // Set clock frequency +static inline void clock_init(void) { // Set clock frequency SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); // Enable FPU - asm ("DSB"); - asm ("ISB"); - FLASH->ACR |= FLASH_LATENCY | BIT(8) | BIT(9); // Flash latency, prefetch, Icache, Dcache - RCC->PLLCFGR &= ~((BIT(17) - 1)); // Clear PLL multipliers + asm("DSB"); + asm("ISB"); + FLASH->ACR |= FLASH_LATENCY | BIT(8) | + BIT(9); // Flash latency, prefetch, Icache, Dcache + RCC->PLLCFGR &= ~((BIT(17) - 1)); // Clear PLL multipliers RCC->PLLCFGR |= (((PLL_P - 2) / 2) & 3) << 16; // Set PLL_P RCC->PLLCFGR |= PLL_M | (PLL_N << 6); // Set PLL_M and PLL_N RCC->CR |= BIT(24); // Enable PLL diff --git a/examples/stm32/stm32-freertos-tcp/Makefile b/examples/stm32/stm32-freertos-tcp/Makefile index b5a77dbe..f91199f4 100644 --- a/examples/stm32/stm32-freertos-tcp/Makefile +++ b/examples/stm32/stm32-freertos-tcp/Makefile @@ -6,7 +6,7 @@ DOCKER ?= docker run --rm -v $(PROJECT_ROOT_PATH):$(PROJECT_ROOT_PATH) -w $(CURD FREERTOS_KERNEL_PATH ?= $(PROJECT_ROOT_PATH)/test/freertos-kernel FREERTOS_PLUS_TCP_PATH ?= $(PROJECT_ROOT_PATH)/test/freertos-tcp -MONGOOSE_FLAGS = -DMG_ARCH=MG_ARCH_FREERTOS_TCP +MONGOOSE_FLAGS = -DMG_ARCH=MG_ARCH_FREERTOS -DMG_ENABLE_FREERTOS_TCP -DMG_ENABLE_FILE=0 MCU_FLAGS = -mcpu=cortex-m7 -mthumb -mfloat-abi=softfp -mfpu=vfpv4 #-mcpu=cortex-m7 -mthumb -mfpu=fpv5-sp-d16 -mfloat-abi=hard diff --git a/mip/driver_stm32.c b/mip/driver_stm32.c index 6cb962bf..03cea143 100644 --- a/mip/driver_stm32.c +++ b/mip/driver_stm32.c @@ -14,8 +14,10 @@ struct stm32_eth { DMAMFBOCR, DMARSWTR, RESERVED10[8], DMACHTDR, DMACHRDR, DMACHTBAR, DMACHRBAR; }; +#undef ETH #define ETH ((struct stm32_eth *) (uintptr_t) 0x40028000) +#undef BIT #define BIT(x) ((uint32_t) 1 << (x)) #define ETH_PKT_SIZE 1540 // Max frame size #define ETH_DESC_CNT 4 // Descriptors count @@ -29,15 +31,11 @@ static void (*s_rx)(void *, size_t, void *); // Recv callback static void *s_rxdata; // Recv callback data enum { PHY_ADDR = 0, PHY_BCR = 0, PHY_BSR = 1 }; // PHY constants -static inline void spin(volatile uint32_t count) { - while (count--) (void) 0; -} - static uint32_t eth_read_phy(uint8_t addr, uint8_t reg) { ETH->MACMIIAR &= (7 << 2); ETH->MACMIIAR |= ((uint32_t) addr << 11) | ((uint32_t) reg << 6); ETH->MACMIIAR |= BIT(0); - while (ETH->MACMIIAR & BIT(0)) spin(1); + while (ETH->MACMIIAR & BIT(0)) (void) 0; return ETH->MACMIIDR; } @@ -46,29 +44,29 @@ static void eth_write_phy(uint8_t addr, uint8_t reg, uint32_t val) { ETH->MACMIIAR &= (7 << 2); ETH->MACMIIAR |= ((uint32_t) addr << 11) | ((uint32_t) reg << 6) | BIT(1); ETH->MACMIIAR |= BIT(0); - while (ETH->MACMIIAR & BIT(0)) spin(1); + while (ETH->MACMIIAR & BIT(0)) (void) 0; } static uint32_t get_hclk(void) { struct rcc { volatile uint32_t CR, PLLCFGR, CFGR; - } *RCC = (struct rcc *) 0x40023800; + } *rcc = (struct rcc *) 0x40023800; uint32_t clk = 0, hsi = 16000000 /* 16 MHz */, hse = 8000000 /* 8MHz */; - if (RCC->CFGR & (1 << 2)) { + if (rcc->CFGR & (1 << 2)) { clk = hse; - } else if (RCC->CFGR & (1 << 3)) { + } else if (rcc->CFGR & (1 << 3)) { uint32_t vco, m, n, p; - m = (RCC->PLLCFGR & (0x3f << 0)) >> 0; - n = (RCC->PLLCFGR & (0x1ff << 6)) >> 6; - p = (((RCC->PLLCFGR & (3 << 16)) >> 16) + 1) * 2; - clk = (RCC->PLLCFGR & (1 << 22)) ? hse : hsi; + m = (rcc->PLLCFGR & (0x3f << 0)) >> 0; + n = (rcc->PLLCFGR & (0x1ff << 6)) >> 6; + p = (((rcc->PLLCFGR & (3 << 16)) >> 16) + 1) * 2; + clk = (rcc->PLLCFGR & (1 << 22)) ? hse : hsi; vco = (uint32_t) ((uint64_t) clk * n / m); clk = vco / p; } else { clk = hsi; } - uint32_t hpre = (RCC->CFGR & (15 << 4)) >> 4; + uint32_t hpre = (rcc->CFGR & (15 << 4)) >> 4; if (hpre < 8) return clk; uint8_t ahbptab[8] = {1, 2, 3, 4, 6, 7, 8, 9}; // log2(div) @@ -121,12 +119,12 @@ static bool mip_driver_stm32_init(uint8_t *mac, void *userdata) { (uint32_t) (uintptr_t) s_txdesc[(i + 1) % ETH_DESC_CNT]; // Chain } - ETH->DMABMR |= BIT(0); // Software reset - while ((ETH->DMABMR & BIT(0)) != 0) spin(1); // Wait until done + ETH->DMABMR |= BIT(0); // Software reset + while ((ETH->DMABMR & BIT(0)) != 0) (void) 0; // Wait until done // Set MDC clock divider. If user told us the value, use it. Otherwise, guess int cr = (d == NULL || d->mdc_cr < 0) ? guess_mdc_cr() : d->mdc_cr; - ETH->MACMIIAR = ((uint32_t)cr & 7) << 2; + ETH->MACMIIAR = ((uint32_t) cr & 7) << 2; // NOTE(cpq): we do not use extended descriptor bit 7, and do not use // hardware checksum. Therefore, descriptor size is 4, not 8 diff --git a/mip/mip.c b/mip/mip.c index eb6a2540..2e83c230 100644 --- a/mip/mip.c +++ b/mip/mip.c @@ -628,7 +628,7 @@ static void read_conn(struct mg_connection *c, struct pkt *pkt) { MG_DEBUG(("%lu SEQ %x -> %x", c->id, mg_htonl(pkt->tcp->seq), s->ack)); s->ack = (uint32_t) (mg_htonl(pkt->tcp->seq) + pkt->pay.len); -#if 1 +#if 0 // Send ACK immediately MG_DEBUG((" imm ACK", c->id, mg_htonl(pkt->tcp->seq), s->ack)); tx_tcp((struct mip_if *) c->mgr->priv, c->rem.ip, TH_ACK, c->loc.port, diff --git a/mongoose.c b/mongoose.c index c2ee5a01..f74bcfbc 100644 --- a/mongoose.c +++ b/mongoose.c @@ -3529,7 +3529,7 @@ void mg_mgr_free(struct mg_mgr *mgr) { mgr->timers = NULL; // Important. Next call to poll won't touch timers for (c = mgr->conns; c != NULL; c = c->next) c->is_closing = 1; mg_mgr_poll(mgr, 0); -#if MG_ARCH == MG_ARCH_FREERTOS_TCP +#if MG_ENABLE_FREERTOS_TCP FreeRTOS_DeleteSocketSet(mgr->ss); #endif MG_DEBUG(("All connections closed")); @@ -3550,7 +3550,7 @@ void mg_mgr_init(struct mg_mgr *mgr) { // clang-format off { WSADATA data; WSAStartup(MAKEWORD(2, 2), &data); } // clang-format on -#elif MG_ARCH == MG_ARCH_FREERTOS_TCP +#elif MG_ENABLE_FREERTOS_TCP mgr->ss = FreeRTOS_CreateSocketSet(); #elif defined(__unix) || defined(__unix__) || defined(__APPLE__) // Ignore SIGPIPE signal, so if client cancels the request, it @@ -4100,7 +4100,7 @@ long mg_io_send(struct mg_connection *c, const void *buf, size_t len) { } else { n = send(FD(c), (char *) buf, len, MSG_NONBLOCKING); #if MG_ARCH == MG_ARCH_RTX - if (n == BSD_EWOULDBLOCK) return MG_IO_WAIT; + if (n == EWOULDBLOCK) return MG_IO_WAIT; #endif } if (n < 0 && mg_sock_would_block()) return MG_IO_WAIT; @@ -4130,11 +4130,11 @@ static void mg_set_non_blocking_mode(MG_SOCKET_TYPE fd) { #elif MG_ARCH == MG_ARCH_RTX unsigned long on = 1; ioctlsocket(fd, FIONBIO, &on); -#elif MG_ARCH == MG_ARCH_FREERTOS_TCP +#elif MG_ENABLE_FREERTOS_TCP const BaseType_t off = 0; if (setsockopt(fd, 0, FREERTOS_SO_RCVTIMEO, &off, sizeof(off)) != 0) (void) 0; if (setsockopt(fd, 0, FREERTOS_SO_SNDTIMEO, &off, sizeof(off)) != 0) (void) 0; -#elif MG_ARCH == MG_ARCH_FREERTOS_LWIP || MG_ARCH == MG_ARCH_RTX_LWIP +#elif MG_ENABLE_LWIP lwip_fcntl(fd, F_SETFL, O_NONBLOCK); #elif MG_ARCH == MG_ARCH_AZURERTOS fcntl(fd, F_SETFL, O_NONBLOCK); @@ -4262,7 +4262,7 @@ static void close_conn(struct mg_connection *c) { epoll_ctl(c->mgr->epoll_fd, EPOLL_CTL_DEL, FD(c), NULL); #endif closesocket(FD(c)); -#if MG_ARCH == MG_ARCH_FREERTOS_TCP +#if MG_ENABLE_FREERTOS_TCP FreeRTOS_FD_CLR(c->fd, c->mgr->ss, eSELECT_ALL); #endif } @@ -4284,7 +4284,7 @@ static void connect_conn(struct mg_connection *c) { } static void setsockopts(struct mg_connection *c) { -#if MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_AZURERTOS || \ +#if MG_ENABLE_FREERTOS_TCP || MG_ARCH == MG_ARCH_AZURERTOS || \ MG_ARCH == MG_ARCH_TIRTOS (void) c; #else @@ -4312,7 +4312,8 @@ void mg_connect_resolved(struct mg_connection *c) { #if MG_ARCH == MG_ARCH_TIRTOS union usa usa; // TI-RTOS NDK requires binding to receive on UDP sockets socklen_t slen = tousa(&c->loc, &usa); - if (bind(c->fd, &usa.sa, slen) != 0) MG_ERROR(("bind: %d", MG_SOCKET_ERRNO)); + if (bind(c->fd, &usa.sa, slen) != 0) + MG_ERROR(("bind: %d", MG_SOCKET_ERRNO)); #endif mg_call(c, MG_EV_RESOLVE, NULL); mg_call(c, MG_EV_CONNECT, NULL); @@ -4336,7 +4337,8 @@ void mg_connect_resolved(struct mg_connection *c) { (void) rc; } -static MG_SOCKET_TYPE raccept(MG_SOCKET_TYPE sock, union usa *usa, socklen_t len) { +static MG_SOCKET_TYPE raccept(MG_SOCKET_TYPE sock, union usa *usa, + socklen_t len) { MG_SOCKET_TYPE s = MG_INVALID_SOCKET; do { memset(usa, 0, sizeof(*usa)); @@ -4358,8 +4360,8 @@ static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) { if (MG_SOCKET_ERRNO != EAGAIN) #endif MG_ERROR(("%lu accept failed, errno %d", lsn->id, MG_SOCKET_ERRNO)); -#if (MG_ARCH != MG_ARCH_WIN32) && (MG_ARCH != MG_ARCH_FREERTOS_TCP) && \ - (MG_ARCH != MG_ARCH_TIRTOS) && !(MG_ENABLE_POLL) +#if (MG_ARCH != MG_ARCH_WIN32) && !MG_ENABLE_FREERTOS_TCP && \ + (MG_ARCH != MG_ARCH_TIRTOS) && !MG_ENABLE_POLL } else if ((long) fd >= FD_SETSIZE) { MG_ERROR(("%ld > %ld", (long) fd, (long) FD_SETSIZE)); closesocket(fd); @@ -4463,7 +4465,7 @@ static bool skip_iotest(const struct mg_connection *c) { } static void mg_iotest(struct mg_mgr *mgr, int ms) { -#if MG_ARCH == MG_ARCH_FREERTOS_TCP +#if MG_ENABLE_FREERTOS_TCP struct mg_connection *c; for (c = mgr->conns; c != NULL; c = c->next) { c->is_readable = c->is_writable = 0; @@ -4475,8 +4477,8 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) { FreeRTOS_select(mgr->ss, pdMS_TO_TICKS(ms)); for (c = mgr->conns; c != NULL; c = c->next) { EventBits_t bits = FreeRTOS_FD_ISSET(c->fd, mgr->ss); - c->is_readable = bits & (eSELECT_READ | eSELECT_EXCEPT) ? 1 : 0; - c->is_writable = bits & eSELECT_WRITE ? 1 : 0; + c->is_readable = bits & (eSELECT_READ | eSELECT_EXCEPT) ? 1U : 0; + c->is_writable = bits & eSELECT_WRITE ? 1U : 0; FreeRTOS_FD_CLR(c->fd, mgr->ss, eSELECT_READ | eSELECT_EXCEPT | eSELECT_WRITE); } @@ -5598,9 +5600,7 @@ uint64_t mg_millis(void) { return time_us_64() / 1000; #elif MG_ARCH == MG_ARCH_ESP32 return esp_timer_get_time() / 1000; -#elif MG_ARCH == MG_ARCH_ESP8266 - return xTaskGetTickCount() * portTICK_PERIOD_MS; -#elif MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_FREERTOS_LWIP +#elif MG_ARCH == MG_ARCH_ESP8266 || MG_ARCH == MG_ARCH_FREERTOS return xTaskGetTickCount() * portTICK_PERIOD_MS; #elif MG_ARCH == MG_ARCH_AZURERTOS return tx_time_get() * (1000 /* MS per SEC */ / TX_TIMER_TICKS_PER_SECOND); @@ -5999,8 +5999,10 @@ struct stm32_eth { DMAMFBOCR, DMARSWTR, RESERVED10[8], DMACHTDR, DMACHRDR, DMACHTBAR, DMACHRBAR; }; +#undef ETH #define ETH ((struct stm32_eth *) (uintptr_t) 0x40028000) +#undef BIT #define BIT(x) ((uint32_t) 1 << (x)) #define ETH_PKT_SIZE 1540 // Max frame size #define ETH_DESC_CNT 4 // Descriptors count @@ -6014,15 +6016,11 @@ static void (*s_rx)(void *, size_t, void *); // Recv callback static void *s_rxdata; // Recv callback data enum { PHY_ADDR = 0, PHY_BCR = 0, PHY_BSR = 1 }; // PHY constants -static inline void spin(volatile uint32_t count) { - while (count--) (void) 0; -} - static uint32_t eth_read_phy(uint8_t addr, uint8_t reg) { ETH->MACMIIAR &= (7 << 2); ETH->MACMIIAR |= ((uint32_t) addr << 11) | ((uint32_t) reg << 6); ETH->MACMIIAR |= BIT(0); - while (ETH->MACMIIAR & BIT(0)) spin(1); + while (ETH->MACMIIAR & BIT(0)) (void) 0; return ETH->MACMIIDR; } @@ -6031,29 +6029,29 @@ static void eth_write_phy(uint8_t addr, uint8_t reg, uint32_t val) { ETH->MACMIIAR &= (7 << 2); ETH->MACMIIAR |= ((uint32_t) addr << 11) | ((uint32_t) reg << 6) | BIT(1); ETH->MACMIIAR |= BIT(0); - while (ETH->MACMIIAR & BIT(0)) spin(1); + while (ETH->MACMIIAR & BIT(0)) (void) 0; } static uint32_t get_hclk(void) { struct rcc { volatile uint32_t CR, PLLCFGR, CFGR; - } *RCC = (struct rcc *) 0x40023800; + } *rcc = (struct rcc *) 0x40023800; uint32_t clk = 0, hsi = 16000000 /* 16 MHz */, hse = 8000000 /* 8MHz */; - if (RCC->CFGR & (1 << 2)) { + if (rcc->CFGR & (1 << 2)) { clk = hse; - } else if (RCC->CFGR & (1 << 3)) { + } else if (rcc->CFGR & (1 << 3)) { uint32_t vco, m, n, p; - m = (RCC->PLLCFGR & (0x3f << 0)) >> 0; - n = (RCC->PLLCFGR & (0x1ff << 6)) >> 6; - p = (((RCC->PLLCFGR & (3 << 16)) >> 16) + 1) * 2; - clk = (RCC->PLLCFGR & (1 << 22)) ? hse : hsi; + m = (rcc->PLLCFGR & (0x3f << 0)) >> 0; + n = (rcc->PLLCFGR & (0x1ff << 6)) >> 6; + p = (((rcc->PLLCFGR & (3 << 16)) >> 16) + 1) * 2; + clk = (rcc->PLLCFGR & (1 << 22)) ? hse : hsi; vco = (uint32_t) ((uint64_t) clk * n / m); clk = vco / p; } else { clk = hsi; } - uint32_t hpre = (RCC->CFGR & (15 << 4)) >> 4; + uint32_t hpre = (rcc->CFGR & (15 << 4)) >> 4; if (hpre < 8) return clk; uint8_t ahbptab[8] = {1, 2, 3, 4, 6, 7, 8, 9}; // log2(div) @@ -6106,12 +6104,12 @@ static bool mip_driver_stm32_init(uint8_t *mac, void *userdata) { (uint32_t) (uintptr_t) s_txdesc[(i + 1) % ETH_DESC_CNT]; // Chain } - ETH->DMABMR |= BIT(0); // Software reset - while ((ETH->DMABMR & BIT(0)) != 0) spin(1); // Wait until done + ETH->DMABMR |= BIT(0); // Software reset + while ((ETH->DMABMR & BIT(0)) != 0) (void) 0; // Wait until done // Set MDC clock divider. If user told us the value, use it. Otherwise, guess int cr = (d == NULL || d->mdc_cr < 0) ? guess_mdc_cr() : d->mdc_cr; - ETH->MACMIIAR = ((uint32_t)cr & 7) << 2; + ETH->MACMIIAR = ((uint32_t) cr & 7) << 2; // NOTE(cpq): we do not use extended descriptor bit 7, and do not use // hardware checksum. Therefore, descriptor size is 4, not 8 @@ -6918,7 +6916,7 @@ static void read_conn(struct mg_connection *c, struct pkt *pkt) { MG_DEBUG(("%lu SEQ %x -> %x", c->id, mg_htonl(pkt->tcp->seq), s->ack)); s->ack = (uint32_t) (mg_htonl(pkt->tcp->seq) + pkt->pay.len); -#if 1 +#if 0 // Send ACK immediately MG_DEBUG((" imm ACK", c->id, mg_htonl(pkt->tcp->seq), s->ack)); tx_tcp((struct mip_if *) c->mgr->priv, c->rem.ip, TH_ACK, c->loc.port, diff --git a/mongoose.h b/mongoose.h index c30b5301..c32b3dfc 100644 --- a/mongoose.h +++ b/mongoose.h @@ -27,20 +27,18 @@ extern "C" { #endif -#define MG_ARCH_CUSTOM 0 -#define MG_ARCH_UNIX 1 -#define MG_ARCH_WIN32 2 -#define MG_ARCH_ESP32 3 -#define MG_ARCH_ESP8266 4 -#define MG_ARCH_FREERTOS_TCP 5 -#define MG_ARCH_FREERTOS_LWIP 6 -#define MG_ARCH_AZURERTOS 7 -#define MG_ARCH_RTX_LWIP 8 -#define MG_ARCH_ZEPHYR 9 -#define MG_ARCH_NEWLIB 10 -#define MG_ARCH_RTX 11 -#define MG_ARCH_TIRTOS 12 -#define MG_ARCH_RP2040 13 +#define MG_ARCH_CUSTOM 0 // User creates its own mongoose_custom.h +#define MG_ARCH_UNIX 1 // Linux, BSD, Mac, ... +#define MG_ARCH_WIN32 2 // Windows +#define MG_ARCH_ESP32 3 // ESP32 +#define MG_ARCH_ESP8266 4 // ESP8266 +#define MG_ARCH_FREERTOS 5 // FreeRTOS +#define MG_ARCH_AZURERTOS 6 // MS Azure RTOS +#define MG_ARCH_ZEPHYR 7 // Zephyr RTOS +#define MG_ARCH_NEWLIB 8 // Bare metal ARM +#define MG_ARCH_RTX 9 // Keil MDK RTX +#define MG_ARCH_TIRTOS 10 // Texas Semi TI-RTOS +#define MG_ARCH_RP2040 11 // Raspberry Pi RP2040 #if !defined(MG_ARCH) #if defined(__unix__) || defined(__APPLE__) @@ -54,7 +52,8 @@ extern "C" { #elif defined(ESP_PLATFORM) #define MG_ARCH MG_ARCH_ESP32 #elif defined(FREERTOS_IP_H) -#define MG_ARCH MG_ARCH_FREERTOS_TCP +#define MG_ARCH MG_ARCH_FREERTOS +#define MG_ENABLE_FREERTOS_TCP 1 #elif defined(AZURE_RTOS_THREADX) #define MG_ARCH MG_ARCH_AZURERTOS #elif defined(PICO_TARGET_NAME) @@ -71,7 +70,9 @@ extern "C" { #endif // http://esr.ibiblio.org/?p=5095 -#define MG_BIG_ENDIAN (*(uint16_t *)"\0\xff" < 0x100) +#define MG_BIG_ENDIAN (*(uint16_t *) "\0\xff" < 0x100) + + @@ -162,9 +163,10 @@ extern "C" { #endif -#if MG_ARCH == MG_ARCH_FREERTOS_LWIP +#if MG_ARCH == MG_ARCH_FREERTOS #include +// #include // Cannot include errno - might conflict with lwip! #include #include #include @@ -172,137 +174,32 @@ extern "C" { #include #include -#if defined(__GNUC__) -#include -#include -#else -struct timeval { - time_t tv_sec; - long tv_usec; -}; -#endif - #include #include -#include - -#if LWIP_SOCKET != 1 -// Sockets support disabled in LWIP by default -#error Set LWIP_SOCKET variable to 1 (in lwipopts.h) -#endif - -// Re-route calloc/free to the FreeRTOS's functions, don't use stdlib -static inline void *mg_calloc(int cnt, size_t size) { - void *p = pvPortMalloc(cnt * size); - if (p != NULL) memset(p, 0, size * cnt); - return p; -} -#define calloc(a, b) mg_calloc((a), (b)) -#define free(a) vPortFree(a) -#define malloc(a) pvPortMalloc(a) -#define strdup(s) ((char *) mg_strdup(mg_str(s)).ptr) -#define mkdir(a, b) (-1) - #ifndef MG_IO_SIZE #define MG_IO_SIZE 512 #endif -#endif // MG_ARCH == MG_ARCH_FREERTOS_LWIP - - -#if MG_ARCH == MG_ARCH_FREERTOS_TCP - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#define MG_SOCKET_TYPE Socket_t -#define MG_INVALID_SOCKET FREERTOS_INVALID_SOCKET - -// Why FreeRTOS-TCP did not implement a clean BSD API, but its own thing -// with FreeRTOS_ prefix, is beyond me -#define IPPROTO_TCP FREERTOS_IPPROTO_TCP -#define IPPROTO_UDP FREERTOS_IPPROTO_UDP -#define AF_INET FREERTOS_AF_INET -#define SOCK_STREAM FREERTOS_SOCK_STREAM -#define SOCK_DGRAM FREERTOS_SOCK_DGRAM -#define SO_BROADCAST 0 -#define SO_ERROR 0 -#define SOL_SOCKET 0 -#define SO_REUSEADDR 0 -#define sockaddr_in freertos_sockaddr -#define sockaddr freertos_sockaddr -#define accept(a, b, c) FreeRTOS_accept((a), (b), (c)) -#define connect(a, b, c) FreeRTOS_connect((a), (b), (c)) -#define bind(a, b, c) FreeRTOS_bind((a), (b), (c)) -#define listen(a, b) FreeRTOS_listen((a), (b)) -#define socket(a, b, c) FreeRTOS_socket((a), (b), (c)) -#define send(a, b, c, d) FreeRTOS_send((a), (b), (c), (d)) -#define recv(a, b, c, d) FreeRTOS_recv((a), (b), (c), (d)) -#define setsockopt(a, b, c, d, e) FreeRTOS_setsockopt((a), (b), (c), (d), (e)) -#define sendto(a, b, c, d, e, f) FreeRTOS_sendto((a), (b), (c), (d), (e), (f)) -#define recvfrom(a, b, c, d, e, f) \ - FreeRTOS_recvfrom((a), (b), (c), (d), (e), (f)) -#define closesocket(x) FreeRTOS_closesocket(x) -#define gethostbyname(x) FreeRTOS_gethostbyname(x) -#define getsockname(a, b, c) (-1) -#define getpeername(a, b, c) 0 +#define calloc(a, b) mg_calloc(a, b) +#define free(a) vPortFree(a) +#define malloc(a) pvPortMalloc(a) +#define strdup(s) ((char *) mg_strdup(mg_str(s)).ptr) // Re-route calloc/free to the FreeRTOS's functions, don't use stdlib -static inline void *mg_calloc(int cnt, size_t size) { +static inline void *mg_calloc(size_t cnt, size_t size) { void *p = pvPortMalloc(cnt * size); if (p != NULL) memset(p, 0, size * cnt); return p; } -#define calloc(a, b) mg_calloc((a), (b)) -#define free(a) vPortFree(a) -#define malloc(a) pvPortMalloc(a) -#define mkdir(a, b) (-1) -#if !defined(__GNUC__) -// copied from GCC on ARM; for some reason useconds are signed -struct timeval { - time_t tv_sec; - long tv_usec; -}; -#endif +#define mkdir(a, b) mg_mkdir(a, b) +static inline int mg_mkdir(const char *path, mode_t mode) { + (void) path, (void) mode; + return -1; +} -#ifndef EINPROGRESS -#define EINPROGRESS pdFREERTOS_ERRNO_EINPROGRESS -#endif -#ifndef EWOULDBLOCK -#define EWOULDBLOCK pdFREERTOS_ERRNO_EWOULDBLOCK -#endif -#ifndef EAGAIN -#define EAGAIN pdFREERTOS_ERRNO_EAGAIN -#endif -#ifndef EINTR -#define EINTR pdFREERTOS_ERRNO_EINTR -#endif - -// FreeRTOS-TCP uses non-standard semantics for listen() backlog size. It is -// not a backlog size for pending SYN connections, but a max socket number -#ifndef MG_SOCK_LISTEN_BACKLOG_SIZE -#define MG_SOCK_LISTEN_BACKLOG_SIZE 128 -#endif - -#endif // MG_ARCH == MG_ARCH_FREERTOS_TCP +#endif // MG_ARCH == MG_ARCH_FREERTOS #if MG_ARCH == MG_ARCH_NEWLIB @@ -356,60 +253,10 @@ int mkdir(const char *, mode_t); #include #include -#include - -#define MG_ENABLE_CUSTOM_MILLIS 1 -typedef int socklen_t; -#define closesocket(x) closesocket(x) -#define mkdir(a, b) (-1) -#define EWOULDBLOCK BSD_EWOULDBLOCK -#define EAGAIN BSD_EWOULDBLOCK -#define EINPROGRESS BSD_EWOULDBLOCK -#define EINTR BSD_EWOULDBLOCK -#define ECONNRESET BSD_ECONNRESET -#define EPIPE BSD_ECONNRESET -#define TCP_NODELAY SO_KEEPALIVE - +#if !defined MG_ENABLE_RL && (!defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP) +#define MG_ENABLE_RL 1 #endif - -#if MG_ARCH == MG_ARCH_RTX_LWIP - -#include -#include -#include -#include -#include -#include - -#if defined(__GNUC__) -#include -#include -#else -struct timeval { - time_t tv_sec; - long tv_usec; -}; -#endif - -#include - -#if LWIP_SOCKET != 1 -// Sockets support disabled in LWIP by default -#error Set LWIP_SOCKET variable to 1 (in lwipopts.h) -#endif - -#define mkdir(a, b) (-1) - -#ifndef MG_IO_SIZE -#define MG_IO_SIZE 512 -#endif - -#ifndef MG_PATH_MAX -#define MG_PATH_MAX 128 -#endif - - #endif @@ -626,12 +473,129 @@ int sscanf(const char *, const char *, ...); #endif +#if defined(MG_ENABLE_FREERTOS_TCP) && MG_ENABLE_FREERTOS_TCP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#define MG_SOCKET_TYPE Socket_t +#define MG_INVALID_SOCKET FREERTOS_INVALID_SOCKET + +// Why FreeRTOS-TCP did not implement a clean BSD API, but its own thing +// with FreeRTOS_ prefix, is beyond me +#define IPPROTO_TCP FREERTOS_IPPROTO_TCP +#define IPPROTO_UDP FREERTOS_IPPROTO_UDP +#define AF_INET FREERTOS_AF_INET +#define SOCK_STREAM FREERTOS_SOCK_STREAM +#define SOCK_DGRAM FREERTOS_SOCK_DGRAM +#define SO_BROADCAST 0 +#define SO_ERROR 0 +#define SOL_SOCKET 0 +#define SO_REUSEADDR 0 +#define sockaddr_in freertos_sockaddr +#define sockaddr freertos_sockaddr +#define accept(a, b, c) FreeRTOS_accept((a), (b), (c)) +#define connect(a, b, c) FreeRTOS_connect((a), (b), (c)) +#define bind(a, b, c) FreeRTOS_bind((a), (b), (c)) +#define listen(a, b) FreeRTOS_listen((a), (b)) +#define socket(a, b, c) FreeRTOS_socket((a), (b), (c)) +#define send(a, b, c, d) FreeRTOS_send((a), (b), (c), (d)) +#define recv(a, b, c, d) FreeRTOS_recv((a), (b), (c), (d)) +#define setsockopt(a, b, c, d, e) FreeRTOS_setsockopt((a), (b), (c), (d), (e)) +#define sendto(a, b, c, d, e, f) FreeRTOS_sendto((a), (b), (c), (d), (e), (f)) +#define recvfrom(a, b, c, d, e, f) \ + FreeRTOS_recvfrom((a), (b), (c), (d), (e), (f)) +#define closesocket(x) FreeRTOS_closesocket(x) +#define gethostbyname(x) FreeRTOS_gethostbyname(x) +#define getsockname(a, b, c) mg_getsockname((a), (b), (c)) +#define getpeername(a, b, c) mg_getpeername((a), (b), (c)) + +static inline int mg_getsockname(MG_SOCKET_TYPE fd, void *buf, socklen_t *len) { + (void) fd, (void) buf, (void) len; + return -1; +} + +static inline int mg_getpeername(MG_SOCKET_TYPE fd, void *buf, socklen_t *len) { + (void) fd, (void) buf, (void) len; + return 0; +} +#endif + + +#if defined(MG_ENABLE_LWIP) && MG_ENABLE_LWIP +#if defined(__GNUC__) +#include +#include +#else +struct timeval { + time_t tv_sec; + long tv_usec; +}; +#endif + +#include + +#if LWIP_SOCKET != 1 +// Sockets support disabled in LWIP by default +#error Set LWIP_SOCKET variable to 1 (in lwipopts.h) +#endif +#endif + + +#if defined(MG_ENABLE_RL) && MG_ENABLE_RL +#include + +#define MG_ENABLE_CUSTOM_MILLIS 1 +#define closesocket(x) closesocket(x) +#define mkdir(a, b) (-1) +#define EWOULDBLOCK BSD_EWOULDBLOCK +#define EAGAIN BSD_EWOULDBLOCK +#define EINPROGRESS BSD_EWOULDBLOCK +#define EINTR BSD_EWOULDBLOCK +#define ECONNRESET BSD_ECONNRESET +#define EPIPE BSD_ECONNRESET +#define TCP_NODELAY SO_KEEPALIVE +#endif + + #ifndef MG_ENABLE_LOG #define MG_ENABLE_LOG 1 #endif #ifndef MG_ENABLE_MIP -#define MG_ENABLE_MIP 0 +#define MG_ENABLE_MIP 0 // Mongoose built-in network stack +#endif + +#ifndef MG_ENABLE_LWIP +#define MG_ENABLE_LWIP 0 // lWIP network stack +#endif + +#ifndef MG_ENABLE_FREERTOS_TCP +#define MG_ENABLE_FREERTOS_TCP 0 // Amazon FreeRTOS-TCP network stack +#endif + +#ifndef MG_ENABLE_RL +#define MG_ENABLE_RL 0 // ARM MDK network stack +#endif + +#ifndef MG_ENABLE_SOCKET +#define MG_ENABLE_SOCKET !MG_ENABLE_MIP #endif #ifndef MG_ENABLE_POLL @@ -646,10 +610,6 @@ int sscanf(const char *, const char *, ...); #define MG_ENABLE_FATFS 0 #endif -#ifndef MG_ENABLE_SOCKET -#define MG_ENABLE_SOCKET 1 -#endif - #ifndef MG_ENABLE_MBEDTLS #define MG_ENABLE_MBEDTLS 0 #endif @@ -1044,6 +1004,7 @@ enum { + struct mg_dns { const char *url; // DNS server URL struct mg_connection *c; // DNS server connection @@ -1071,7 +1032,7 @@ struct mg_mgr { int epoll_fd; // Used when MG_EPOLL_ENABLE=1 void *priv; // Used by the MIP stack size_t extraconnsize; // Used by the MIP stack -#if MG_ARCH == MG_ARCH_FREERTOS_TCP +#if MG_ENABLE_FREERTOS_TCP SocketSet_t ss; // NOTE(lsm): referenced from socket struct #endif }; diff --git a/src/arch.h b/src/arch.h index 18a154ed..c7223bb7 100644 --- a/src/arch.h +++ b/src/arch.h @@ -1,19 +1,17 @@ #pragma once -#define MG_ARCH_CUSTOM 0 -#define MG_ARCH_UNIX 1 -#define MG_ARCH_WIN32 2 -#define MG_ARCH_ESP32 3 -#define MG_ARCH_ESP8266 4 -#define MG_ARCH_FREERTOS_TCP 5 -#define MG_ARCH_FREERTOS_LWIP 6 -#define MG_ARCH_AZURERTOS 7 -#define MG_ARCH_RTX_LWIP 8 -#define MG_ARCH_ZEPHYR 9 -#define MG_ARCH_NEWLIB 10 -#define MG_ARCH_RTX 11 -#define MG_ARCH_TIRTOS 12 -#define MG_ARCH_RP2040 13 +#define MG_ARCH_CUSTOM 0 // User creates its own mongoose_custom.h +#define MG_ARCH_UNIX 1 // Linux, BSD, Mac, ... +#define MG_ARCH_WIN32 2 // Windows +#define MG_ARCH_ESP32 3 // ESP32 +#define MG_ARCH_ESP8266 4 // ESP8266 +#define MG_ARCH_FREERTOS 5 // FreeRTOS +#define MG_ARCH_AZURERTOS 6 // MS Azure RTOS +#define MG_ARCH_ZEPHYR 7 // Zephyr RTOS +#define MG_ARCH_NEWLIB 8 // Bare metal ARM +#define MG_ARCH_RTX 9 // Keil MDK RTX +#define MG_ARCH_TIRTOS 10 // Texas Semi TI-RTOS +#define MG_ARCH_RP2040 11 // Raspberry Pi RP2040 #if !defined(MG_ARCH) #if defined(__unix__) || defined(__APPLE__) @@ -27,7 +25,8 @@ #elif defined(ESP_PLATFORM) #define MG_ARCH MG_ARCH_ESP32 #elif defined(FREERTOS_IP_H) -#define MG_ARCH MG_ARCH_FREERTOS_TCP +#define MG_ARCH MG_ARCH_FREERTOS +#define MG_ENABLE_FREERTOS_TCP 1 #elif defined(AZURE_RTOS_THREADX) #define MG_ARCH MG_ARCH_AZURERTOS #elif defined(PICO_TARGET_NAME) @@ -44,15 +43,17 @@ #endif // http://esr.ibiblio.org/?p=5095 -#define MG_BIG_ENDIAN (*(uint16_t *)"\0\xff" < 0x100) +#define MG_BIG_ENDIAN (*(uint16_t *) "\0\xff" < 0x100) #include "arch_esp32.h" #include "arch_esp8266.h" -#include "arch_freertos_lwip.h" -#include "arch_freertos_tcp.h" +#include "arch_freertos.h" #include "arch_newlib.h" #include "arch_rtx.h" -#include "arch_rtx_lwip.h" #include "arch_unix.h" #include "arch_win32.h" #include "arch_zephyr.h" + +#include "net_ft.h" +#include "net_lwip.h" +#include "net_rl.h" diff --git a/src/arch_freertos_lwip.h b/src/arch_freertos.h similarity index 52% rename from src/arch_freertos_lwip.h rename to src/arch_freertos.h index 840855d9..4be2b4de 100644 --- a/src/arch_freertos_lwip.h +++ b/src/arch_freertos.h @@ -1,8 +1,9 @@ #pragma once -#if MG_ARCH == MG_ARCH_FREERTOS_LWIP +#if MG_ARCH == MG_ARCH_FREERTOS #include +// #include // Cannot include errno - might conflict with lwip! #include #include #include @@ -10,40 +11,29 @@ #include #include -#if defined(__GNUC__) -#include -#include -#else -struct timeval { - time_t tv_sec; - long tv_usec; -}; -#endif - #include #include -#include - -#if LWIP_SOCKET != 1 -// Sockets support disabled in LWIP by default -#error Set LWIP_SOCKET variable to 1 (in lwipopts.h) -#endif - -// Re-route calloc/free to the FreeRTOS's functions, don't use stdlib -static inline void *mg_calloc(int cnt, size_t size) { - void *p = pvPortMalloc(cnt * size); - if (p != NULL) memset(p, 0, size * cnt); - return p; -} -#define calloc(a, b) mg_calloc((a), (b)) -#define free(a) vPortFree(a) -#define malloc(a) pvPortMalloc(a) -#define strdup(s) ((char *) mg_strdup(mg_str(s)).ptr) -#define mkdir(a, b) (-1) - #ifndef MG_IO_SIZE #define MG_IO_SIZE 512 #endif -#endif // MG_ARCH == MG_ARCH_FREERTOS_LWIP +#define calloc(a, b) mg_calloc(a, b) +#define free(a) vPortFree(a) +#define malloc(a) pvPortMalloc(a) +#define strdup(s) ((char *) mg_strdup(mg_str(s)).ptr) + +// Re-route calloc/free to the FreeRTOS's functions, don't use stdlib +static inline void *mg_calloc(size_t cnt, size_t size) { + void *p = pvPortMalloc(cnt * size); + if (p != NULL) memset(p, 0, size * cnt); + return p; +} + +#define mkdir(a, b) mg_mkdir(a, b) +static inline int mg_mkdir(const char *path, mode_t mode) { + (void) path, (void) mode; + return -1; +} + +#endif // MG_ARCH == MG_ARCH_FREERTOS diff --git a/src/arch_rtx.h b/src/arch_rtx.h index 8b7dfbc5..f364c16b 100644 --- a/src/arch_rtx.h +++ b/src/arch_rtx.h @@ -13,18 +13,8 @@ #include #include -#include - -#define MG_ENABLE_CUSTOM_MILLIS 1 -typedef int socklen_t; -#define closesocket(x) closesocket(x) -#define mkdir(a, b) (-1) -#define EWOULDBLOCK BSD_EWOULDBLOCK -#define EAGAIN BSD_EWOULDBLOCK -#define EINPROGRESS BSD_EWOULDBLOCK -#define EINTR BSD_EWOULDBLOCK -#define ECONNRESET BSD_ECONNRESET -#define EPIPE BSD_ECONNRESET -#define TCP_NODELAY SO_KEEPALIVE +#if !defined MG_ENABLE_RL && (!defined(MG_ENABLE_LWIP) || !MG_ENABLE_LWIP) +#define MG_ENABLE_RL 1 +#endif #endif diff --git a/src/config.h b/src/config.h index ae3f71bf..bbcf94b5 100644 --- a/src/config.h +++ b/src/config.h @@ -5,7 +5,23 @@ #endif #ifndef MG_ENABLE_MIP -#define MG_ENABLE_MIP 0 +#define MG_ENABLE_MIP 0 // Mongoose built-in network stack +#endif + +#ifndef MG_ENABLE_LWIP +#define MG_ENABLE_LWIP 0 // lWIP network stack +#endif + +#ifndef MG_ENABLE_FREERTOS_TCP +#define MG_ENABLE_FREERTOS_TCP 0 // Amazon FreeRTOS-TCP network stack +#endif + +#ifndef MG_ENABLE_RL +#define MG_ENABLE_RL 0 // ARM MDK network stack +#endif + +#ifndef MG_ENABLE_SOCKET +#define MG_ENABLE_SOCKET !MG_ENABLE_MIP #endif #ifndef MG_ENABLE_POLL @@ -20,10 +36,6 @@ #define MG_ENABLE_FATFS 0 #endif -#ifndef MG_ENABLE_SOCKET -#define MG_ENABLE_SOCKET 1 -#endif - #ifndef MG_ENABLE_MBEDTLS #define MG_ENABLE_MBEDTLS 0 #endif diff --git a/src/net.c b/src/net.c index 24fd891f..21c345be 100644 --- a/src/net.c +++ b/src/net.c @@ -237,7 +237,7 @@ void mg_mgr_free(struct mg_mgr *mgr) { mgr->timers = NULL; // Important. Next call to poll won't touch timers for (c = mgr->conns; c != NULL; c = c->next) c->is_closing = 1; mg_mgr_poll(mgr, 0); -#if MG_ARCH == MG_ARCH_FREERTOS_TCP +#if MG_ENABLE_FREERTOS_TCP FreeRTOS_DeleteSocketSet(mgr->ss); #endif MG_DEBUG(("All connections closed")); @@ -258,7 +258,7 @@ void mg_mgr_init(struct mg_mgr *mgr) { // clang-format off { WSADATA data; WSAStartup(MAKEWORD(2, 2), &data); } // clang-format on -#elif MG_ARCH == MG_ARCH_FREERTOS_TCP +#elif MG_ENABLE_FREERTOS_TCP mgr->ss = FreeRTOS_CreateSocketSet(); #elif defined(__unix) || defined(__unix__) || defined(__APPLE__) // Ignore SIGPIPE signal, so if client cancels the request, it diff --git a/src/net.h b/src/net.h index b01b0fbf..5f539d0f 100644 --- a/src/net.h +++ b/src/net.h @@ -1,6 +1,7 @@ #pragma once #include "arch.h" +#include "config.h" #include "event.h" #include "iobuf.h" #include "str.h" @@ -33,7 +34,7 @@ struct mg_mgr { int epoll_fd; // Used when MG_EPOLL_ENABLE=1 void *priv; // Used by the MIP stack size_t extraconnsize; // Used by the MIP stack -#if MG_ARCH == MG_ARCH_FREERTOS_TCP +#if MG_ENABLE_FREERTOS_TCP SocketSet_t ss; // NOTE(lsm): referenced from socket struct #endif }; diff --git a/src/arch_freertos_tcp.h b/src/net_ft.h similarity index 58% rename from src/arch_freertos_tcp.h rename to src/net_ft.h index 62346d5b..0c43ea07 100644 --- a/src/arch_freertos_tcp.h +++ b/src/net_ft.h @@ -1,6 +1,6 @@ #pragma once -#if MG_ARCH == MG_ARCH_FREERTOS_TCP +#if defined(MG_ENABLE_FREERTOS_TCP) && MG_ENABLE_FREERTOS_TCP #include #include @@ -50,45 +50,16 @@ FreeRTOS_recvfrom((a), (b), (c), (d), (e), (f)) #define closesocket(x) FreeRTOS_closesocket(x) #define gethostbyname(x) FreeRTOS_gethostbyname(x) -#define getsockname(a, b, c) (-1) -#define getpeername(a, b, c) 0 +#define getsockname(a, b, c) mg_getsockname((a), (b), (c)) +#define getpeername(a, b, c) mg_getpeername((a), (b), (c)) -// Re-route calloc/free to the FreeRTOS's functions, don't use stdlib -static inline void *mg_calloc(int cnt, size_t size) { - void *p = pvPortMalloc(cnt * size); - if (p != NULL) memset(p, 0, size * cnt); - return p; +static inline int mg_getsockname(MG_SOCKET_TYPE fd, void *buf, socklen_t *len) { + (void) fd, (void) buf, (void) len; + return -1; } -#define calloc(a, b) mg_calloc((a), (b)) -#define free(a) vPortFree(a) -#define malloc(a) pvPortMalloc(a) -#define mkdir(a, b) (-1) -#if !defined(__GNUC__) -// copied from GCC on ARM; for some reason useconds are signed -struct timeval { - time_t tv_sec; - long tv_usec; -}; +static inline int mg_getpeername(MG_SOCKET_TYPE fd, void *buf, socklen_t *len) { + (void) fd, (void) buf, (void) len; + return 0; +} #endif - -#ifndef EINPROGRESS -#define EINPROGRESS pdFREERTOS_ERRNO_EINPROGRESS -#endif -#ifndef EWOULDBLOCK -#define EWOULDBLOCK pdFREERTOS_ERRNO_EWOULDBLOCK -#endif -#ifndef EAGAIN -#define EAGAIN pdFREERTOS_ERRNO_EAGAIN -#endif -#ifndef EINTR -#define EINTR pdFREERTOS_ERRNO_EINTR -#endif - -// FreeRTOS-TCP uses non-standard semantics for listen() backlog size. It is -// not a backlog size for pending SYN connections, but a max socket number -#ifndef MG_SOCK_LISTEN_BACKLOG_SIZE -#define MG_SOCK_LISTEN_BACKLOG_SIZE 128 -#endif - -#endif // MG_ARCH == MG_ARCH_FREERTOS_TCP diff --git a/src/arch_rtx_lwip.h b/src/net_lwip.h similarity index 52% rename from src/arch_rtx_lwip.h rename to src/net_lwip.h index 9200a3ec..d137e919 100644 --- a/src/arch_rtx_lwip.h +++ b/src/net_lwip.h @@ -1,14 +1,6 @@ #pragma once -#if MG_ARCH == MG_ARCH_RTX_LWIP - -#include -#include -#include -#include -#include -#include - +#if defined(MG_ENABLE_LWIP) && MG_ENABLE_LWIP #if defined(__GNUC__) #include #include @@ -25,16 +17,4 @@ struct timeval { // Sockets support disabled in LWIP by default #error Set LWIP_SOCKET variable to 1 (in lwipopts.h) #endif - -#define mkdir(a, b) (-1) - -#ifndef MG_IO_SIZE -#define MG_IO_SIZE 512 -#endif - -#ifndef MG_PATH_MAX -#define MG_PATH_MAX 128 -#endif - - #endif diff --git a/src/net_rl.h b/src/net_rl.h new file mode 100644 index 00000000..28b7bd54 --- /dev/null +++ b/src/net_rl.h @@ -0,0 +1,16 @@ +#pragma once + +#if defined(MG_ENABLE_RL) && MG_ENABLE_RL +#include + +#define MG_ENABLE_CUSTOM_MILLIS 1 +#define closesocket(x) closesocket(x) +#define mkdir(a, b) (-1) +#define EWOULDBLOCK BSD_EWOULDBLOCK +#define EAGAIN BSD_EWOULDBLOCK +#define EINPROGRESS BSD_EWOULDBLOCK +#define EINTR BSD_EWOULDBLOCK +#define ECONNRESET BSD_ECONNRESET +#define EPIPE BSD_ECONNRESET +#define TCP_NODELAY SO_KEEPALIVE +#endif diff --git a/src/sock.c b/src/sock.c index bf1a672e..6262d3a7 100644 --- a/src/sock.c +++ b/src/sock.c @@ -136,7 +136,7 @@ long mg_io_send(struct mg_connection *c, const void *buf, size_t len) { } else { n = send(FD(c), (char *) buf, len, MSG_NONBLOCKING); #if MG_ARCH == MG_ARCH_RTX - if (n == BSD_EWOULDBLOCK) return MG_IO_WAIT; + if (n == EWOULDBLOCK) return MG_IO_WAIT; #endif } if (n < 0 && mg_sock_would_block()) return MG_IO_WAIT; @@ -166,11 +166,11 @@ static void mg_set_non_blocking_mode(MG_SOCKET_TYPE fd) { #elif MG_ARCH == MG_ARCH_RTX unsigned long on = 1; ioctlsocket(fd, FIONBIO, &on); -#elif MG_ARCH == MG_ARCH_FREERTOS_TCP +#elif MG_ENABLE_FREERTOS_TCP const BaseType_t off = 0; if (setsockopt(fd, 0, FREERTOS_SO_RCVTIMEO, &off, sizeof(off)) != 0) (void) 0; if (setsockopt(fd, 0, FREERTOS_SO_SNDTIMEO, &off, sizeof(off)) != 0) (void) 0; -#elif MG_ARCH == MG_ARCH_FREERTOS_LWIP || MG_ARCH == MG_ARCH_RTX_LWIP +#elif MG_ENABLE_LWIP lwip_fcntl(fd, F_SETFL, O_NONBLOCK); #elif MG_ARCH == MG_ARCH_AZURERTOS fcntl(fd, F_SETFL, O_NONBLOCK); @@ -298,7 +298,7 @@ static void close_conn(struct mg_connection *c) { epoll_ctl(c->mgr->epoll_fd, EPOLL_CTL_DEL, FD(c), NULL); #endif closesocket(FD(c)); -#if MG_ARCH == MG_ARCH_FREERTOS_TCP +#if MG_ENABLE_FREERTOS_TCP FreeRTOS_FD_CLR(c->fd, c->mgr->ss, eSELECT_ALL); #endif } @@ -320,7 +320,7 @@ static void connect_conn(struct mg_connection *c) { } static void setsockopts(struct mg_connection *c) { -#if MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_AZURERTOS || \ +#if MG_ENABLE_FREERTOS_TCP || MG_ARCH == MG_ARCH_AZURERTOS || \ MG_ARCH == MG_ARCH_TIRTOS (void) c; #else @@ -348,7 +348,8 @@ void mg_connect_resolved(struct mg_connection *c) { #if MG_ARCH == MG_ARCH_TIRTOS union usa usa; // TI-RTOS NDK requires binding to receive on UDP sockets socklen_t slen = tousa(&c->loc, &usa); - if (bind(c->fd, &usa.sa, slen) != 0) MG_ERROR(("bind: %d", MG_SOCKET_ERRNO)); + if (bind(c->fd, &usa.sa, slen) != 0) + MG_ERROR(("bind: %d", MG_SOCKET_ERRNO)); #endif mg_call(c, MG_EV_RESOLVE, NULL); mg_call(c, MG_EV_CONNECT, NULL); @@ -372,7 +373,8 @@ void mg_connect_resolved(struct mg_connection *c) { (void) rc; } -static MG_SOCKET_TYPE raccept(MG_SOCKET_TYPE sock, union usa *usa, socklen_t len) { +static MG_SOCKET_TYPE raccept(MG_SOCKET_TYPE sock, union usa *usa, + socklen_t len) { MG_SOCKET_TYPE s = MG_INVALID_SOCKET; do { memset(usa, 0, sizeof(*usa)); @@ -394,8 +396,8 @@ static void accept_conn(struct mg_mgr *mgr, struct mg_connection *lsn) { if (MG_SOCKET_ERRNO != EAGAIN) #endif MG_ERROR(("%lu accept failed, errno %d", lsn->id, MG_SOCKET_ERRNO)); -#if (MG_ARCH != MG_ARCH_WIN32) && (MG_ARCH != MG_ARCH_FREERTOS_TCP) && \ - (MG_ARCH != MG_ARCH_TIRTOS) && !(MG_ENABLE_POLL) +#if (MG_ARCH != MG_ARCH_WIN32) && !MG_ENABLE_FREERTOS_TCP && \ + (MG_ARCH != MG_ARCH_TIRTOS) && !MG_ENABLE_POLL } else if ((long) fd >= FD_SETSIZE) { MG_ERROR(("%ld > %ld", (long) fd, (long) FD_SETSIZE)); closesocket(fd); @@ -499,7 +501,7 @@ static bool skip_iotest(const struct mg_connection *c) { } static void mg_iotest(struct mg_mgr *mgr, int ms) { -#if MG_ARCH == MG_ARCH_FREERTOS_TCP +#if MG_ENABLE_FREERTOS_TCP struct mg_connection *c; for (c = mgr->conns; c != NULL; c = c->next) { c->is_readable = c->is_writable = 0; @@ -511,8 +513,8 @@ static void mg_iotest(struct mg_mgr *mgr, int ms) { FreeRTOS_select(mgr->ss, pdMS_TO_TICKS(ms)); for (c = mgr->conns; c != NULL; c = c->next) { EventBits_t bits = FreeRTOS_FD_ISSET(c->fd, mgr->ss); - c->is_readable = bits & (eSELECT_READ | eSELECT_EXCEPT) ? 1 : 0; - c->is_writable = bits & eSELECT_WRITE ? 1 : 0; + c->is_readable = bits & (eSELECT_READ | eSELECT_EXCEPT) ? 1U : 0; + c->is_writable = bits & eSELECT_WRITE ? 1U : 0; FreeRTOS_FD_CLR(c->fd, mgr->ss, eSELECT_READ | eSELECT_EXCEPT | eSELECT_WRITE); } diff --git a/src/util.c b/src/util.c index 12924867..6f7f5c0c 100644 --- a/src/util.c +++ b/src/util.c @@ -96,9 +96,7 @@ uint64_t mg_millis(void) { return time_us_64() / 1000; #elif MG_ARCH == MG_ARCH_ESP32 return esp_timer_get_time() / 1000; -#elif MG_ARCH == MG_ARCH_ESP8266 - return xTaskGetTickCount() * portTICK_PERIOD_MS; -#elif MG_ARCH == MG_ARCH_FREERTOS_TCP || MG_ARCH == MG_ARCH_FREERTOS_LWIP +#elif MG_ARCH == MG_ARCH_ESP8266 || MG_ARCH == MG_ARCH_FREERTOS return xTaskGetTickCount() * portTICK_PERIOD_MS; #elif MG_ARCH == MG_ARCH_AZURERTOS return tx_time_get() * (1000 /* MS per SEC */ / TX_TIMER_TICKS_PER_SECOND); diff --git a/test/unit_test.c b/test/unit_test.c index 488059ca..e6a3ec7a 100644 --- a/test/unit_test.c +++ b/test/unit_test.c @@ -331,10 +331,10 @@ static void test_sntp(void) { ASSERT(mg_sntp_parse(bad, sizeof(bad)) < 0); ASSERT(mg_sntp_parse(NULL, 0) == -1); - // test_sntp_server("udp://time.windows.com:123"); // NOTE(cpq): temporarily disabled until Github Actions fix their NTP // port blockage issue, https://github.com/actions/runner-images/issues/5615 - test_sntp_server("udp://time.apple.com:123"); + //test_sntp_server("udp://time.apple.com:123"); + test_sntp_server("udp://time.windows.com:123"); test_sntp_server(NULL); }