mirror of
https://github.com/cesanta/mongoose.git
synced 2024-12-27 15:01:03 +08:00
Merge pull request #2032 from cesanta/move
Move mip/ -> src/tcpip/, rename mip_ -> mg_tcpip_
This commit is contained in:
commit
9da80d7b7d
14
.github/workflows/test.yml
vendored
14
.github/workflows/test.yml
vendored
@ -25,7 +25,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
with: { fetch-depth: 2 }
|
||||
- id: check
|
||||
run: /bin/bash test/check.sh '^test|^src'
|
||||
run: /bin/bash test/check.sh '^test|^src/*.[ch]'
|
||||
- if: steps.check.outputs.MATCH == 1
|
||||
run: ./test/setup_ga_network.sh
|
||||
- if: steps.check.outputs.MATCH == 1
|
||||
@ -38,7 +38,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
with: { fetch-depth: 2 }
|
||||
- id: check
|
||||
run: /bin/bash test/check.sh '^test|^src'
|
||||
run: /bin/bash test/check.sh '^test|^src/*.[ch]'
|
||||
- if: steps.check.outputs.MATCH == 1
|
||||
run: sudo apt-get update && sudo apt-get install qemu binfmt-support qemu-user-static
|
||||
- if: steps.check.outputs.MATCH == 1
|
||||
@ -51,7 +51,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
with: { fetch-depth: 2 }
|
||||
- id: check
|
||||
run: /bin/bash test/check.sh '^test|^src'
|
||||
run: /bin/bash test/check.sh '^test|^src/*.[ch]'
|
||||
- if: steps.check.outputs.MATCH == 1
|
||||
run: sudo apt-get update && sudo apt-get install qemu binfmt-support qemu-user-static
|
||||
- if: steps.check.outputs.MATCH == 1
|
||||
@ -64,7 +64,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
with: { fetch-depth: 2 }
|
||||
- id: check
|
||||
run: /bin/bash test/check.sh '^test|^src'
|
||||
run: /bin/bash test/check.sh '^test|^src/*.[ch]'
|
||||
- if: steps.check.outputs.MATCH == 1
|
||||
run: sudo apt-get update ; sudo apt-get install libmbedtls-dev valgrind
|
||||
- if: steps.check.outputs.MATCH == 1
|
||||
@ -95,7 +95,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
with: { fetch-depth: 2 }
|
||||
- id: check
|
||||
run: /bin/bash test/check.sh '^test|^src'
|
||||
run: /bin/bash test/check.sh '^test|^src/*.[ch]'
|
||||
- if: steps.check.outputs.MATCH == 1
|
||||
run: make vc98 vc17 vc22 mingw mingw++
|
||||
arduino-xiao:
|
||||
@ -104,7 +104,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
with: { fetch-depth: 2 }
|
||||
- id: check
|
||||
run: /bin/bash test/check.sh '^examples/arduino|^src'
|
||||
run: /bin/bash test/check.sh '^examples/arduino|^src/*.[ch]'
|
||||
- if: steps.check.outputs.MATCH == 1
|
||||
run: make arduino-xiao
|
||||
arm:
|
||||
@ -186,7 +186,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
with: { fetch-depth: 2 }
|
||||
- id: check
|
||||
run: /bin/bash test/check.sh '^examples/zephyr|^src'
|
||||
run: /bin/bash test/check.sh '^examples/zephyr|^src/*.[ch]'
|
||||
- if: steps.check.outputs.MATCH == 1
|
||||
run: make -C examples/zephyr init
|
||||
- name: minify manifest
|
||||
|
12
Makefile
12
Makefile
@ -1,5 +1,5 @@
|
||||
SRCS = mongoose.c test/unit_test.c test/packed_fs.c
|
||||
HDRS = $(wildcard src/*.h) $(wildcard mip/*.h)
|
||||
HDRS = $(wildcard src/*.h) $(wildcard src/tcpip/*.h)
|
||||
DEFS ?= -DMG_MAX_HTTP_HEADERS=7 -DMG_ENABLE_LINES -DMG_ENABLE_PACKED_FS=1 -DMG_ENABLE_SSI=1
|
||||
WARN ?= -pedantic -W -Wall -Werror -Wshadow -Wdouble-promotion -fno-common -Wconversion -Wundef
|
||||
OPTS ?= -O3 -g3
|
||||
@ -120,11 +120,11 @@ s390: CC = $(DOCKER) mdashnet/s390 cc
|
||||
s390: RUN = $(DOCKER) mdashnet/s390
|
||||
s390: test
|
||||
|
||||
arm: DEFS += -DMG_ENABLE_FILE=0 -DMG_ENABLE_MIP=1 -DMG_ARCH=MG_ARCH_NEWLIB
|
||||
arm: DEFS += -DMG_ENABLE_FILE=0 -DMG_ENABLE_TCPIP=1 -DMG_ARCH=MG_ARCH_NEWLIB
|
||||
arm: mongoose.h $(SRCS)
|
||||
$(DOCKER) mdashnet/armgcc arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb $(SRCS) $(OPTS) $(WARN) $(INCS) $(DEFS) $(TFLAGS) -o unit_test -nostartfiles --specs nosys.specs -e 0
|
||||
|
||||
riscv: DEFS += -DMG_ENABLE_FILE=0 -DMG_ENABLE_MIP=1 -DMG_ARCH=MG_ARCH_NEWLIB
|
||||
riscv: DEFS += -DMG_ENABLE_FILE=0 -DMG_ENABLE_TCPIP=1 -DMG_ARCH=MG_ARCH_NEWLIB
|
||||
riscv: mongoose.h $(SRCS)
|
||||
$(DOCKER) mdashnet/riscv riscv-none-elf-gcc -march=rv32imc -mabi=ilp32 $(SRCS) $(OPTS) $(WARN) $(INCS) $(DEFS) $(TFLAGS) -o unit_test
|
||||
|
||||
@ -175,11 +175,11 @@ install: linux-libs
|
||||
uninstall:
|
||||
rm -rf $(DESTDIR)$(PREFIX)/lib/libmongoose.a $(DESTDIR)$(PREFIX)/lib/libmongoose.so.$(VERSION) $(DESTDIR)$(PREFIX)/include/mongoose.h $(DESTDIR)$(PREFIX)/lib/libmongoose.so
|
||||
|
||||
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.c: Makefile $(wildcard src/*.c) $(wildcard src/tcpip/*.c)
|
||||
(cat src/license.h; echo; echo '#include "mongoose.h"' ; (for F in src/*.c src/tcpip/*.c ; do echo; echo '#ifdef MG_ENABLE_LINES'; echo "#line 1 \"$$F\""; echo '#endif'; cat $$F | sed -e 's,#include ".*,,'; done))> $@
|
||||
|
||||
mongoose.h: $(HDRS) Makefile
|
||||
(cat src/license.h; echo; echo '#ifndef MONGOOSE_H'; echo '#define MONGOOSE_H'; echo; cat src/version.h ; echo; echo '#ifdef __cplusplus'; echo 'extern "C" {'; echo '#endif'; cat src/arch.h src/arch_*.h src/net_*.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 src/tcpip/tcpip.h src/tcpip/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 arduino tmp
|
||||
|
@ -5,7 +5,8 @@
|
||||
[![Code Coverage](https://codecov.io/gh/cesanta/mongoose/branch/master/graph/badge.svg)](https://codecov.io/gh/cesanta/mongoose)
|
||||
[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/mongoose.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:mongoose)
|
||||
|
||||
Mongoose is a networking library for C/C++. It implements event-driven
|
||||
Mongoose is a network library for C/C++.
|
||||
It implements event-driven
|
||||
non-blocking APIs for TCP, UDP, HTTP, WebSocket, MQTT. It is designed for
|
||||
connecting devices and bringing them online. On the market since 2004, used by
|
||||
vast number of open source and commercial products - it even runs on the
|
||||
@ -19,10 +20,10 @@ robust, and easy. Features include:
|
||||
- Asynchronous DNS resolver
|
||||
- Tiny static and run-time footprint
|
||||
- Source code is both ISO C and ISO C++ compliant
|
||||
- Works with any network stack with socket API, like LwIP or FreeRTOS-Plus-TCP
|
||||
- Very easy to integrate: just copy `mongoose.c` and `mongoose.h` files to your build tree
|
||||
- Optional built-in TCP/IP stack with drivers for bare metal or RTOS firmwares
|
||||
- A full device dashboard
|
||||
- Works with any network stack with socket API, like LwIP or FreeRTOS-Plus-TCP
|
||||
- Provides a built-in TCP/IP stack with drivers for bare metal or RTOS systems
|
||||
- A complete Web device dashboard
|
||||
[bare metal example on Nucleo-F429ZI](examples/stm32/nucleo-f429zi-baremetal)
|
||||
is only 6 files
|
||||
- For comparison, a CubeIDE generated HTTP example is 400+ files
|
||||
|
@ -377,7 +377,7 @@ standard BSD socket API.
|
||||
|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 |
|
||||
|MG_ENABLE_TCPIP | 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)
|
||||
@ -448,7 +448,7 @@ systems, follow the outline below:
|
||||
[test/mongoose_custom.c](https://github.com/cesanta/mongoose/blob/master/test/mongoose_custom.c)
|
||||
and the experimental builtin bare metal TCP/IP stack implementation
|
||||
at
|
||||
[src/mip.c](https://github.com/cesanta/mongoose/blob/master/src/mip.c)
|
||||
[src/tcpip/](https://github.com/cesanta/mongoose/blob/master/src/tcpip/)
|
||||
|
||||
## Minimal HTTP server
|
||||
|
||||
|
@ -9,6 +9,6 @@
|
||||
|
||||
#define MG_ARCH MG_ARCH_CUSTOM
|
||||
#define MG_ENABLE_SOCKET 0
|
||||
#define MG_ENABLE_MIP 1
|
||||
#define MG_ENABLE_TCPIP 1
|
||||
#define mkdir(a, b) (-1)
|
||||
//#define MG_ENABLE_LOG 0
|
||||
|
@ -3,13 +3,13 @@
|
||||
|
||||
#define SS_PIN 3 // Slave select pin
|
||||
struct mg_mgr mgr; // Mongoose event manager
|
||||
struct mip_spi spi = {
|
||||
struct mg_tcpip_spi spi = {
|
||||
NULL, // SPI data
|
||||
[](void *) { digitalWrite(SS_PIN, LOW); }, // begin transation
|
||||
[](void *) { digitalWrite(SS_PIN, HIGH); }, // end transaction
|
||||
[](void *, uint8_t c) { return SPI.transfer(c); }, // execute transaction
|
||||
};
|
||||
struct mip_if mif = {.mac = {2, 0, 1, 2, 3, 5}}; // MIP network interface
|
||||
struct mg_tcpip_if mif = {.mac = {2, 0, 1, 2, 3, 5}}; // MIP network interface
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
@ -23,15 +23,15 @@ void setup() {
|
||||
delay(3000);
|
||||
MG_INFO(("Starting TCP/IP stack..."));
|
||||
|
||||
mif.driver = &mip_driver_w5500;
|
||||
mif.driver = &mg_tcpip_driver_w5500;
|
||||
mif.driver_data = &spi;
|
||||
mip_init(&mgr, &mif);
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
|
||||
// Start a 5 sec timer, print status message periodically
|
||||
mg_timer_add(
|
||||
&mgr, 5000, MG_TIMER_REPEAT,
|
||||
[](void *) {
|
||||
MG_INFO(("ethernet: %s", mip_driver_w5500.up(&mif) ? "up" : "down"));
|
||||
MG_INFO(("ethernet: %s", mg_tcpip_driver_w5500.up(&mif) ? "up" : "down"));
|
||||
},
|
||||
NULL);
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
PROG ?= example
|
||||
DEFS ?= -DMG_ENABLE_LINES=1 -DMG_ENABLE_MIP=1 -DMG_ENABLE_SOCKET=0 -DMG_ENABLE_PACKED_FS=1 -I../..
|
||||
DEFS ?= -DMG_ENABLE_LINES=1 -DMG_ENABLE_TCPIP=1 -DMG_ENABLE_SOCKET=0 -DMG_ENABLE_PACKED_FS=1 -I../..
|
||||
CFLAGS ?= -W -Wall $(EXTRA_CFLAGS)
|
||||
LIBS ?= -lpcap
|
||||
SOURCES = main.c ../../mongoose.c ../device-dashboard/net.c ../device-dashboard/packed_fs.c
|
||||
|
@ -18,7 +18,7 @@ void signal_handler(int signo) {
|
||||
s_signo = signo;
|
||||
}
|
||||
|
||||
static size_t pcap_tx(const void *buf, size_t len, struct mip_if *ifp) {
|
||||
static size_t pcap_tx(const void *buf, size_t len, struct mg_tcpip_if *ifp) {
|
||||
int res = pcap_inject((pcap_t *) ifp->driver_data, buf, len);
|
||||
if (res == PCAP_ERROR) {
|
||||
MG_ERROR(("pcap_inject: %d", res));
|
||||
@ -26,11 +26,11 @@ static size_t pcap_tx(const void *buf, size_t len, struct mip_if *ifp) {
|
||||
return res == PCAP_ERROR ? 0 : len;
|
||||
}
|
||||
|
||||
static bool pcap_up(struct mip_if *ifp) {
|
||||
static bool pcap_up(struct mg_tcpip_if *ifp) {
|
||||
return ifp->driver_data ? true : false;
|
||||
}
|
||||
|
||||
static size_t pcap_rx(void *buf, size_t len, struct mip_if *ifp) {
|
||||
static size_t pcap_rx(void *buf, size_t len, struct mg_tcpip_if *ifp) {
|
||||
size_t received = 0;
|
||||
struct pcap_pkthdr *hdr = NULL;
|
||||
const unsigned char *pkt = NULL;
|
||||
@ -132,11 +132,11 @@ int main(int argc, char *argv[]) {
|
||||
mg_mgr_init(&mgr); // Initialise event manager
|
||||
mg_log_set(MG_LL_DEBUG); // Set log level
|
||||
|
||||
struct mip_driver driver = {.tx = pcap_tx, .up = pcap_up, .rx = pcap_rx};
|
||||
struct mip_if mif = {.driver = &driver, .driver_data = ph};
|
||||
struct mg_tcpip_driver driver = {.tx = pcap_tx, .up = pcap_up, .rx = pcap_rx};
|
||||
struct mg_tcpip_if mif = {.driver = &driver, .driver_data = ph};
|
||||
sscanf(mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &mif.mac[0], &mif.mac[1],
|
||||
&mif.mac[2], &mif.mac[3], &mif.mac[4], &mif.mac[5]);
|
||||
mip_init(&mgr, &mif);
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
MG_INFO(("Init done, starting main loop"));
|
||||
|
||||
// extern void device_dashboard_fn(struct mg_connection *, int, void *, void
|
||||
|
@ -1,5 +1,5 @@
|
||||
PROG ?= example
|
||||
DEFS ?= -DMG_ENABLE_LINES=1 -DMG_ENABLE_MIP=1 -DMG_ENABLE_SOCKET=0 -DMG_ENABLE_PACKED_FS=1 -I../..
|
||||
DEFS ?= -DMG_ENABLE_LINES=1 -DMG_ENABLE_TCPIP=1 -DMG_ENABLE_SOCKET=0 -DMG_ENABLE_PACKED_FS=1 -I../..
|
||||
CFLAGS ?= -W -Wall $(EXTRA_CFLAGS)
|
||||
LIBS ?=
|
||||
SOURCES = main.c ../../mongoose.c ../device-dashboard/net.c ../device-dashboard/packed_fs.c
|
||||
|
@ -22,7 +22,7 @@ void signal_handler(int signo) {
|
||||
s_signo = signo;
|
||||
}
|
||||
|
||||
static size_t tap_tx(const void *buf, size_t len, struct mip_if *ifp) {
|
||||
static size_t tap_tx(const void *buf, size_t len, struct mg_tcpip_if *ifp) {
|
||||
ssize_t res = write(*(int*) ifp->driver_data, buf, len);
|
||||
if (res < 0) {
|
||||
MG_ERROR(("tap_tx failed: %d", errno));
|
||||
@ -31,11 +31,11 @@ static size_t tap_tx(const void *buf, size_t len, struct mip_if *ifp) {
|
||||
return (size_t) res;
|
||||
}
|
||||
|
||||
static bool tap_up(struct mip_if *ifp) {
|
||||
static bool tap_up(struct mg_tcpip_if *ifp) {
|
||||
return ifp->driver_data ? true : false;
|
||||
}
|
||||
|
||||
static size_t tap_rx(void *buf, size_t len, struct mip_if *ifp) {
|
||||
static size_t tap_rx(void *buf, size_t len, struct mg_tcpip_if *ifp) {
|
||||
ssize_t received = read(*(int *) ifp->driver_data, buf, len);
|
||||
usleep(1); // This is to avoid 100% CPU
|
||||
if (received < 0) return 0;
|
||||
@ -92,11 +92,11 @@ int main(int argc, char *argv[]) {
|
||||
struct mg_mgr mgr; // Event manager
|
||||
mg_mgr_init(&mgr); // Initialise event manager
|
||||
|
||||
struct mip_driver driver = {.tx = tap_tx, .up = tap_up, .rx = tap_rx};
|
||||
struct mip_if mif = {.driver = &driver, .driver_data = &fd};
|
||||
struct mg_tcpip_driver driver = {.tx = tap_tx, .up = tap_up, .rx = tap_rx};
|
||||
struct mg_tcpip_if mif = {.driver = &driver, .driver_data = &fd};
|
||||
sscanf(mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &mif.mac[0], &mif.mac[1],
|
||||
&mif.mac[2], &mif.mac[3], &mif.mac[4], &mif.mac[5]);
|
||||
mip_init(&mgr, &mif);
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
MG_INFO(("Init done, starting main loop"));
|
||||
|
||||
// Start infinite event loop
|
||||
|
@ -9,7 +9,7 @@ pico_sdk_init()
|
||||
add_compile_definitions(
|
||||
MIP_DEBUG=1
|
||||
MG_ENABLE_PACKED_FS=1
|
||||
MG_ENABLE_MIP=1
|
||||
MG_ENABLE_TCPIP=1
|
||||
)
|
||||
|
||||
add_executable(firmware
|
||||
|
@ -29,7 +29,7 @@ static dma_channel_config dmacfg_tx;
|
||||
|
||||
static uint8_t s_rxbuf[2][ETH_PKT_SIZE]; // ping-pong buffer
|
||||
static uint8_t s_txbuf[ETH_PKT_SIZE];
|
||||
static struct mip_if *s_ifp; // MIP interface
|
||||
static struct mg_tcpip_if *s_ifp; // MIP interface
|
||||
|
||||
#define rmii_tx_wrap_target 0
|
||||
#define rmii_tx_wrap 8
|
||||
@ -251,9 +251,9 @@ static uint16_t eth_read_phy(uint addr, uint reg, uint8_t gpio) {
|
||||
|
||||
static void rx_irq(void);
|
||||
|
||||
static bool mip_driver_rp2040_rmii_init(struct mip_if *ifp) {
|
||||
struct mip_driver_rp2040_rmii_data *d =
|
||||
(struct mip_driver_rp2040_rmii_data *) ifp->driver_data;
|
||||
static bool mg_tcpip_driver_rp2040_rmii_init(struct mg_tcpip_if *ifp) {
|
||||
struct mg_tcpip_driver_rp2040_rmii_data *d =
|
||||
(struct mg_tcpip_driver_rp2040_rmii_data *) ifp->driver_data;
|
||||
uint rx_sm_addr, tx_sm_addr;
|
||||
s_ifp = ifp;
|
||||
if (ifp->queue.len == 0) ifp->queue.len = 8192;
|
||||
@ -299,8 +299,8 @@ static bool mip_driver_rp2040_rmii_init(struct mip_if *ifp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static size_t mip_driver_rp2040_rmii_tx(const void *buf, size_t len,
|
||||
struct mip_if *ifp) {
|
||||
static size_t mg_tcpip_driver_rp2040_rmii_tx(const void *buf, size_t len,
|
||||
struct mg_tcpip_if *ifp) {
|
||||
dma_channel_wait_for_finish_blocking(dma_tx);
|
||||
memset(s_txbuf, 0, 60); // pre-pad
|
||||
memcpy(s_txbuf, buf, len);
|
||||
@ -333,12 +333,12 @@ static void rx_irq(void) {
|
||||
// time we can linger here is what it takes for the other buffer to fill
|
||||
// (<8us) and that includes irq chaining
|
||||
if (len >= 64 && len <= ETH_PKT_SIZE)
|
||||
mip_qwrite(s_rxbuf[s_rxno], len, s_ifp);
|
||||
mg_tcpip_qwrite(s_rxbuf[s_rxno], len, s_ifp);
|
||||
s_rxno = rxno;
|
||||
}
|
||||
|
||||
static size_t mip_driver_rp2040_rmii_rx(void *buf, size_t buflen, struct mip_if *ifp) {
|
||||
size_t len = mip_qread(buf, ifp);
|
||||
static size_t mg_tcpip_driver_rp2040_rmii_rx(void *buf, size_t buflen, struct mg_tcpip_if *ifp) {
|
||||
size_t len = mg_tcpip_qread(buf, ifp);
|
||||
if (len == 0) return 0;
|
||||
len -= 4; // exclude CRC from frame length
|
||||
uint32_t crc = crc_calc(buf, len); // calculate CRC and compare
|
||||
@ -350,17 +350,17 @@ static size_t mip_driver_rp2040_rmii_rx(void *buf, size_t buflen, struct mip_if
|
||||
return len;
|
||||
}
|
||||
|
||||
static bool mip_driver_rp2040_rmii_up(struct mip_if *ifp) {
|
||||
struct mip_driver_rp2040_rmii_data *d =
|
||||
(struct mip_driver_rp2040_rmii_data *) ifp->driver_data;
|
||||
static bool mg_tcpip_driver_rp2040_rmii_up(struct mg_tcpip_if *ifp) {
|
||||
struct mg_tcpip_driver_rp2040_rmii_data *d =
|
||||
(struct mg_tcpip_driver_rp2040_rmii_data *) ifp->driver_data;
|
||||
uint32_t bsr =
|
||||
eth_read_phy(d->phy_addr, 1, d->mdio); // Basic Status Register
|
||||
return (bsr & (1 << 2)) ? 1 : 0; // check Link Status flag
|
||||
}
|
||||
|
||||
struct mip_driver mip_driver_rp2040_rmii = {
|
||||
mip_driver_rp2040_rmii_init,
|
||||
mip_driver_rp2040_rmii_tx,
|
||||
mip_driver_rp2040_rmii_rx,
|
||||
mip_driver_rp2040_rmii_up,
|
||||
struct mg_tcpip_driver mg_tcpip_driver_rp2040_rmii = {
|
||||
mg_tcpip_driver_rp2040_rmii_init,
|
||||
mg_tcpip_driver_rp2040_rmii_tx,
|
||||
mg_tcpip_driver_rp2040_rmii_rx,
|
||||
mg_tcpip_driver_rp2040_rmii_up,
|
||||
};
|
||||
|
@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
struct mip_driver_rp2040_rmii_data {
|
||||
struct mg_tcpip_driver_rp2040_rmii_data {
|
||||
uint8_t rx0; // RX0, RX1, CRS_DV; consecutive GPIO pins
|
||||
uint8_t tx0; // TX0, TX1, TX-EN; consecutive GPIO pins
|
||||
uint8_t mdio; // MDIO, MDC; consecutive GPIO pins
|
||||
uint8_t phy_addr; // PHY address
|
||||
};
|
||||
|
||||
extern struct mip_driver mip_driver_rp2040_rmii;
|
||||
extern struct mg_tcpip_driver mg_tcpip_driver_rp2040_rmii;
|
||||
|
@ -30,7 +30,7 @@ int main(void) {
|
||||
MG_INFO(("Init MIP"));
|
||||
// Initialise Mongoose network stack and specific driver
|
||||
// Set consecutive GPIOs for RMII (tx and rx) and SMI function groups
|
||||
struct mip_driver_rp2040_rmii_data driver_data = {
|
||||
struct mg_tcpip_driver_rp2040_rmii_data driver_data = {
|
||||
// see driver_rp2040_rmii.h
|
||||
.rx0 = 6, // 6, 7, 8 : RX0, RX1, CRS_DV
|
||||
.tx0 = 10, // 10, 11, 12 : TX0, TX1, TX-EN
|
||||
@ -39,13 +39,13 @@ int main(void) {
|
||||
};
|
||||
// Specify MAC address, either set use_dhcp or enter a static config.
|
||||
// For static configuration, specify IP/mask/GW in network byte order
|
||||
struct mip_if mif = {
|
||||
struct mg_tcpip_if mif = {
|
||||
.mac = {2, 0, 1, 2, 3, 5},
|
||||
.ip = 0,
|
||||
.driver = &mip_driver_rp2040_rmii,
|
||||
.driver = &mg_tcpip_driver_rp2040_rmii,
|
||||
.driver_data = &driver_data,
|
||||
};
|
||||
mip_init(&mgr, &mif);
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
mg_http_listen(&mgr, "http://0.0.0.0", fn, NULL); // HTTP listener
|
||||
MG_INFO(("Init done, starting main loop"));
|
||||
|
||||
|
@ -24,7 +24,7 @@ pico_enable_stdio_usb(firmware 0) # Route stdio
|
||||
pico_enable_stdio_uart(firmware 1) # to the UART
|
||||
|
||||
# Mongoose build flags
|
||||
add_definitions(-DMG_ENABLE_MIP=1)
|
||||
add_definitions(-DMG_ENABLE_TCPIP=1)
|
||||
add_definitions(-DMG_ENABLE_PACKED_FS=1)
|
||||
add_definitions(-DMG_ENABLE_FILE=0)
|
||||
add_definitions(-DDISABLE_ROUTING=1)
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "pico/stdlib.h"
|
||||
#include "tusb.h"
|
||||
|
||||
static struct mip_if *s_ifp;
|
||||
static struct mg_tcpip_if *s_ifp;
|
||||
|
||||
const uint8_t tud_network_mac_address[6] = {2, 2, 0x84, 0x6A, 0x96, 0};
|
||||
|
||||
@ -15,7 +15,7 @@ static void blink_cb(void *arg) { // Blink periodically
|
||||
}
|
||||
|
||||
bool tud_network_recv_cb(const uint8_t *buf, uint16_t len) {
|
||||
mip_qwrite((void *) buf, len, s_ifp);
|
||||
mg_tcpip_qwrite((void *) buf, len, s_ifp);
|
||||
// MG_INFO(("RECV %hu", len));
|
||||
// mg_hexdump(buf, len);
|
||||
tud_network_recv_renew();
|
||||
@ -30,7 +30,7 @@ uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
static size_t usb_tx(const void *buf, size_t len, struct mip_if *ifp) {
|
||||
static size_t usb_tx(const void *buf, size_t len, struct mg_tcpip_if *ifp) {
|
||||
if (!tud_ready()) return 0;
|
||||
while (!tud_network_can_xmit(len)) tud_task();
|
||||
tud_network_xmit((void *) buf, len);
|
||||
@ -38,7 +38,7 @@ static size_t usb_tx(const void *buf, size_t len, struct mip_if *ifp) {
|
||||
return len;
|
||||
}
|
||||
|
||||
static bool usb_up(struct mip_if *ifp) {
|
||||
static bool usb_up(struct mg_tcpip_if *ifp) {
|
||||
(void) ifp;
|
||||
return tud_inited() && tud_ready() && tud_connected();
|
||||
}
|
||||
@ -56,15 +56,15 @@ int main(void) {
|
||||
mg_mgr_init(&mgr); // and attach it to the MIP interface
|
||||
mg_timer_add(&mgr, 500, MG_TIMER_REPEAT, blink_cb, &mgr);
|
||||
|
||||
struct mip_driver driver = {.tx = usb_tx, .rx = mip_driver_rx, .up = usb_up};
|
||||
struct mip_if mif = {.mac = {2, 0, 1, 2, 3, 0x77},
|
||||
struct mg_tcpip_driver driver = {.tx = usb_tx, .rx = mg_tcpip_driver_rx, .up = usb_up};
|
||||
struct mg_tcpip_if mif = {.mac = {2, 0, 1, 2, 3, 0x77},
|
||||
.ip = mg_htonl(MG_U32(192, 168, 3, 1)),
|
||||
.mask = mg_htonl(MG_U32(255, 255, 255, 0)),
|
||||
.enable_dhcp_server = true,
|
||||
.driver = &driver,
|
||||
.queue.len = 4096};
|
||||
s_ifp = &mif;
|
||||
mip_init(&mgr, &mif);
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
tusb_init();
|
||||
|
||||
MG_INFO(("Initialising application..."));
|
||||
|
@ -21,7 +21,7 @@ pico_enable_stdio_usb(firmware 0)
|
||||
pico_enable_stdio_uart(firmware 1)
|
||||
|
||||
# Mongoose build flags
|
||||
add_definitions(-DMG_ENABLE_MIP=1)
|
||||
add_definitions(-DMG_ENABLE_TCPIP=1)
|
||||
add_definitions(-DMG_ENABLE_PACKED_FS=1)
|
||||
add_definitions(-DMG_ENABLE_FILE=0)
|
||||
|
||||
|
@ -21,7 +21,7 @@ static uint8_t spi_txn(void *spi, uint8_t byte) {
|
||||
|
||||
static void timer_cb(void *arg) {
|
||||
gpio_put(PICO_DEFAULT_LED_PIN, !gpio_get_out_level(PICO_DEFAULT_LED_PIN));
|
||||
bool up = ((struct mip_if *) arg)->state == MIP_STATE_READY;
|
||||
bool up = ((struct mg_tcpip_if *) arg)->state == MIP_STATE_READY;
|
||||
MG_INFO(("Ethernet: %s", up ? "up" : "down")); // Show network status
|
||||
}
|
||||
|
||||
@ -43,14 +43,14 @@ int main(void) {
|
||||
gpio_put(SPI_CS, 1); // And drive CS high (inactive)
|
||||
|
||||
// Init Mongoose
|
||||
struct mip_spi spi = {NULL, spi_begin, spi_end, spi_txn};
|
||||
struct mip_if mif = {.mac = {2, 0, 1, 2, 3, 5},
|
||||
.driver = &mip_driver_w5500,
|
||||
struct mg_tcpip_spi spi = {NULL, spi_begin, spi_end, spi_txn};
|
||||
struct mg_tcpip_if mif = {.mac = {2, 0, 1, 2, 3, 5},
|
||||
.driver = &mg_tcpip_driver_w5500,
|
||||
.driver_data = &spi};
|
||||
struct mg_mgr mgr; // Declare event manager
|
||||
mg_mgr_init(&mgr); // Init event manager
|
||||
mg_log_set(MG_LL_DEBUG); // Set DEBUG log level
|
||||
mip_init(&mgr, &mif); // Init TCP/IP stack
|
||||
mg_tcpip_init(&mgr, &mif); // Init TCP/IP stack
|
||||
mg_timer_add(&mgr, BLINK_PERIOD_MS, MG_TIMER_REPEAT, timer_cb, &mif);
|
||||
|
||||
MG_INFO(("Waiting until network is up..."));
|
||||
|
@ -14,7 +14,7 @@ SOURCES = main.c syscalls.c cmsis_device_f4/Source/Templates/gcc/startup_stm32f4
|
||||
|
||||
# Mongoose-specific build flags and source code files
|
||||
# Build options reference: https://mongoose.ws/documentation/#build-options
|
||||
CFLAGS += -I../../.. -DMG_ARCH=MG_ARCH_NEWLIB -DMG_ENABLE_CUSTOM_MILLIS=1 -DMG_ENABLE_MIP=1 -DMG_ENABLE_PACKED_FS=1
|
||||
CFLAGS += -I../../.. -DMG_ARCH=MG_ARCH_NEWLIB -DMG_ENABLE_CUSTOM_MILLIS=1 -DMG_ENABLE_TCPIP=1 -DMG_ENABLE_PACKED_FS=1
|
||||
SOURCES += ../../../mongoose.c ../../device-dashboard/net.c ../../device-dashboard/packed_fs.c
|
||||
|
||||
# Build flashable .bin file
|
||||
|
@ -10,7 +10,7 @@ which implements the following:
|
||||
- MQTT communication with a remote MQTT server
|
||||
- No dependencies: no HAL, no CMSIS, no RTOS
|
||||
- Hand-written [mcu.h](mcu.h) header based on a [datasheet](https://www.st.com/resource/en/reference_manual/rm0090-stm32f405415-stm32f407417-stm32f427437-and-stm32f429439-advanced-armbased-32bit-mcus-stmicroelectronics.pdf)
|
||||
- Interrupt-driven [Ethernet driver](../../../drivers/mip_driver_stm32.c)
|
||||
- Interrupt-driven [Ethernet driver](../../../drivers/driver_stm32.c)
|
||||
- Blue LED blinky, based on SysTick interrupt
|
||||
- User button handler, turns off/on green LED, based on EXTI, interrupt-driven
|
||||
- HardFault handler that blinks red LED
|
||||
|
@ -38,7 +38,7 @@ void SystemInit(void) { // Called automatically by startup code
|
||||
|
||||
static void timer_fn(void *arg) {
|
||||
gpio_toggle(LED2); // Blink LED
|
||||
bool up = ((struct mip_if *) arg)->state == MIP_STATE_READY;
|
||||
bool up = ((struct mg_tcpip_if *) arg)->state == MIP_STATE_READY;
|
||||
MG_INFO(("Ethernet: %s", up ? "up" : "down")); // Show network status
|
||||
}
|
||||
|
||||
@ -74,11 +74,11 @@ int main(void) {
|
||||
// Initialise Mongoose network stack
|
||||
// Specify MAC address, and IP/mask/GW in network byte order for static
|
||||
// IP configuration. If IP/mask/GW are unset, DHCP is going to be used
|
||||
struct mip_driver_stm32_data driver_data = {.mdc_cr = 4}; // driver_stm32.h
|
||||
struct mip_if mif = {.mac = {2, 0, 1, 2, 3, 5},
|
||||
.driver = &mip_driver_stm32,
|
||||
.driver_data = &driver_data};
|
||||
mip_init(&mgr, &mif);
|
||||
struct mg_tcpip_driver_stm32_data driver_data = {.mdc_cr = 4};
|
||||
struct mg_tcpip_if mif = {.mac = {2, 0, 1, 2, 3, 5},
|
||||
.driver = &mg_tcpip_driver_stm32,
|
||||
.driver_data = &driver_data};
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
mg_timer_add(&mgr, BLINK_PERIOD_MS, MG_TIMER_REPEAT, timer_fn, &mif);
|
||||
|
||||
MG_INFO(("Waiting until network is up..."));
|
||||
|
@ -4,7 +4,7 @@ This firmware uses MIP, an experimental TCP/IP stack of the Mongoose Network Lib
|
||||
It implements the following:
|
||||
|
||||
- Minimal elementary web server, as simple as possible
|
||||
- Interrupt-driven [Ethernet driver](../../../drivers/mip_driver_stm32.c)
|
||||
- Interrupt-driven [Ethernet driver](../../../drivers/driver_stm32.c)
|
||||
- Basic HAL header [mcu.h](mcu.h) based on CMSIS
|
||||
- Blue LED blinky, based on another FreeRTOS task
|
||||
- Debug log on UART3 (st-link)
|
||||
|
@ -48,14 +48,13 @@ static void server(void *args) {
|
||||
// IP configuration. If IP/mask/GW are unset, DHCP is going to be used
|
||||
MG_INFO(("Initializing Ethernet driver"));
|
||||
ethernet_init();
|
||||
struct mip_driver_stm32_data driver_data = {.mdc_cr =
|
||||
4}; // See driver_stm32.h
|
||||
struct mip_if mif = {
|
||||
struct mg_tcpip_driver_stm32_data driver_data = {.mdc_cr = 4};
|
||||
struct mg_tcpip_if mif = {
|
||||
.mac = {2, 0, 1, 2, 3, 5},
|
||||
.driver = &mip_driver_stm32,
|
||||
.driver = &mg_tcpip_driver_stm32,
|
||||
.driver_data = &driver_data,
|
||||
};
|
||||
mip_init(&mgr, &mif);
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
|
||||
MG_INFO(("Starting Mongoose v%s", MG_VERSION)); // Tell the world
|
||||
mg_http_listen(&mgr, "http://0.0.0.0", fn, &mgr); // Web listener
|
||||
|
@ -3,5 +3,5 @@
|
||||
#include <errno.h>
|
||||
|
||||
#define MG_ARCH MG_ARCH_FREERTOS
|
||||
#define MG_ENABLE_MIP 1
|
||||
#define MG_ENABLE_TCPIP 1
|
||||
#define MG_IO_SIZE 256
|
||||
|
@ -18,7 +18,7 @@ SOURCES += tinyusb/src/tusb.c \
|
||||
tinyusb/lib/networking/rndis_reports.c \
|
||||
usb_descriptors.c
|
||||
CFLAGS += -Itinyusb/src -Itinyusb/lib/networking
|
||||
CFLAGS += -DMG_ARCH=MG_ARCH_NEWLIB -DMG_ENABLE_MIP=1 -DMG_ENABLE_PACKED_FS=1 -DMG_IO_SIZE=512 -DMG_ENABLE_CUSTOM_MILLIS=1
|
||||
CFLAGS += -DMG_ARCH=MG_ARCH_NEWLIB -DMG_ENABLE_TCPIP=1 -DMG_ENABLE_PACKED_FS=1 -DMG_IO_SIZE=512 -DMG_ENABLE_CUSTOM_MILLIS=1
|
||||
CFLAGS += -DSTM32F429xx
|
||||
CFLAGS += -Wno-conversion -Wno-sign-conversion
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#define LED PIN('B', 7) // On-board LED pin (blue)
|
||||
static uint64_t s_ticks;
|
||||
static struct mip_if *s_ifp;
|
||||
static struct mg_tcpip_if *s_ifp;
|
||||
uint32_t SystemCoreClock = SYS_FREQUENCY;
|
||||
const uint8_t tud_network_mac_address[6] = {2, 2, 0x84, 0x6A, 0x96, 0};
|
||||
|
||||
@ -25,7 +25,7 @@ void SysTick_Handler(void) { // SyStick IRQ handler, triggered every 1ms
|
||||
}
|
||||
|
||||
bool tud_network_recv_cb(const uint8_t *buf, uint16_t len) {
|
||||
mip_qwrite((void *) buf, len, s_ifp);
|
||||
mg_tcpip_qwrite((void *) buf, len, s_ifp);
|
||||
// MG_INFO(("RECV %hu", len));
|
||||
// mg_hexdump(buf, len);
|
||||
tud_network_recv_renew();
|
||||
@ -45,7 +45,7 @@ uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
static size_t usb_tx(const void *buf, size_t len, struct mip_if *ifp) {
|
||||
static size_t usb_tx(const void *buf, size_t len, struct mg_tcpip_if *ifp) {
|
||||
if (!tud_ready()) return 0;
|
||||
while (!tud_network_can_xmit(len)) tud_task();
|
||||
tud_network_xmit((void *) buf, len);
|
||||
@ -53,7 +53,7 @@ static size_t usb_tx(const void *buf, size_t len, struct mip_if *ifp) {
|
||||
return len;
|
||||
}
|
||||
|
||||
static bool usb_up(struct mip_if *ifp) {
|
||||
static bool usb_up(struct mg_tcpip_if *ifp) {
|
||||
(void) ifp;
|
||||
return tud_inited() && tud_ready() && tud_connected();
|
||||
}
|
||||
@ -84,15 +84,16 @@ int main(void) {
|
||||
mg_timer_add(&mgr, 500, MG_TIMER_REPEAT, blink_cb, &mgr);
|
||||
|
||||
MG_INFO(("Init TCP/IP stack ..."));
|
||||
struct mip_driver driver = {.tx = usb_tx, .rx = mip_driver_rx, .up = usb_up};
|
||||
struct mip_if mif = {.mac = {2, 0, 1, 2, 3, 0x77},
|
||||
.ip = mg_htonl(MG_U32(192, 168, 3, 1)),
|
||||
.mask = mg_htonl(MG_U32(255, 255, 255, 0)),
|
||||
.enable_dhcp_server = true,
|
||||
.driver = &driver,
|
||||
.queue.len = 4096};
|
||||
struct mg_tcpip_driver driver = {
|
||||
.tx = usb_tx, .rx = mg_tcpip_driver_rx, .up = usb_up};
|
||||
struct mg_tcpip_if mif = {.mac = {2, 0, 1, 2, 3, 0x77},
|
||||
.ip = mg_htonl(MG_U32(192, 168, 3, 1)),
|
||||
.mask = mg_htonl(MG_U32(255, 255, 255, 0)),
|
||||
.enable_dhcp_server = true,
|
||||
.driver = &driver,
|
||||
.queue.len = 4096};
|
||||
s_ifp = &mif;
|
||||
mip_init(&mgr, &mif);
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
mg_http_listen(&mgr, "tcp://0.0.0.0:80", fn, &mgr);
|
||||
|
||||
MG_INFO(("Init USB ..."));
|
||||
|
@ -9,9 +9,9 @@ SOURCES = main.c syscalls.c sysinit.c
|
||||
SOURCES += cmsis_f7/Source/Templates/gcc/startup_stm32f746xx.s # ST startup file. Compiler-dependent!
|
||||
|
||||
# Mongoose-specific source code files and build options. See https://mongoose.ws/documentation/#build-options
|
||||
SOURCES += ../../../mongoose.c ../../device-dashboard/net.c ../../device-dashboard/packed_fs.c
|
||||
CFLAGS += -I../../.. -DMG_ARCH=MG_ARCH_NEWLIB -DMG_ENABLE_CUSTOM_MILLIS=1
|
||||
CFLAGS += -DMG_ENABLE_CUSTOM_RANDOM=1 -DMG_ENABLE_MIP=1 -DMG_ENABLE_PACKED_FS=1 $(CFLAGS_EXTRA)
|
||||
SOURCES += mongoose.c net.c packed_fs.c
|
||||
CFLAGS += -DMG_ENABLE_TCPIP=1 -DMG_ARCH=MG_ARCH_NEWLIB -DMG_ENABLE_CUSTOM_MILLIS=1
|
||||
CFLAGS += -DMG_ENABLE_CUSTOM_RANDOM=1 -DMG_ENABLE_PACKED_FS=1 $(CFLAGS_EXTRA)
|
||||
|
||||
all build example: firmware.bin
|
||||
|
||||
|
@ -30,7 +30,7 @@ void mg_random(void *buf, size_t len) { // Use on-board RNG
|
||||
|
||||
static void timer_fn(void *arg) {
|
||||
gpio_toggle(LED); // Blink LED
|
||||
struct mip_if *ifp = arg; // And show
|
||||
struct mg_tcpip_if *ifp = arg; // And show
|
||||
const char *names[] = {"down", "up", "ready"}; // network stats
|
||||
MG_INFO(("Ethernet: %s, IP: %M, rx:%u, tx:%u, dr:%u, er:%u",
|
||||
names[ifp->state], mg_print_ip4, &ifp->ip, ifp->nrecv, ifp->nsent,
|
||||
@ -66,10 +66,10 @@ int main(void) {
|
||||
// Initialise Mongoose network stack
|
||||
// Specify MAC address, and IP/mask/GW in network byte order for static
|
||||
// IP configuration. If IP/mask/GW are unset, DHCP is going to be used
|
||||
struct mip_driver_stm32_data driver_data = {.mdc_cr = 4}; // driver_stm32.h
|
||||
struct mip_if mif = {.driver = &mip_driver_stm32,
|
||||
struct mg_tcpip_driver_stm32_data driver_data = {.mdc_cr = 4}; // driver_stm32.h
|
||||
struct mg_tcpip_if mif = {.driver = &mg_tcpip_driver_stm32,
|
||||
.driver_data = &driver_data};
|
||||
mip_init(&mgr, &mif);
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
mg_timer_add(&mgr, BLINK_PERIOD_MS, MG_TIMER_REPEAT, timer_fn, &mif);
|
||||
|
||||
MG_INFO(("Waiting until network is up..."));
|
||||
|
1
examples/stm32/nucleo-f746zg-baremetal/mongoose.c
Symbolic link
1
examples/stm32/nucleo-f746zg-baremetal/mongoose.c
Symbolic link
@ -0,0 +1 @@
|
||||
../../../mongoose.c
|
1
examples/stm32/nucleo-f746zg-baremetal/mongoose.h
Symbolic link
1
examples/stm32/nucleo-f746zg-baremetal/mongoose.h
Symbolic link
@ -0,0 +1 @@
|
||||
../../../mongoose.h
|
1
examples/stm32/nucleo-f746zg-baremetal/net.c
Symbolic link
1
examples/stm32/nucleo-f746zg-baremetal/net.c
Symbolic link
@ -0,0 +1 @@
|
||||
../../device-dashboard/net.c
|
1
examples/stm32/nucleo-f746zg-baremetal/packed_fs.c
Symbolic link
1
examples/stm32/nucleo-f746zg-baremetal/packed_fs.c
Symbolic link
@ -0,0 +1 @@
|
||||
../../device-dashboard/packed_fs.c
|
@ -6,7 +6,7 @@ It implements the following:
|
||||
- Minimal elementary web server, as simple as possible
|
||||
- No dependencies: no HAL, no CMSIS
|
||||
- Hand-written [mcu.h](mcu.h) header based on the [datasheet](https://www.st.com/resource/en/reference_manual/rm0385-stm32f75xxx-and-stm32f74xxx-advanced-armbased-32bit-mcus-stmicroelectronics.pdf)
|
||||
- Interrupt-driven [Ethernet driver](../../../drivers/mip_driver_stm32.c)
|
||||
- Interrupt-driven [Ethernet driver](../../../drivers/driver_stm32.c)
|
||||
- Blue LED blinky, based on another FreeRTOS task
|
||||
- Debug log on UART3 (st-link)
|
||||
|
||||
|
@ -51,7 +51,7 @@ static void ethernet_init(void) {
|
||||
}
|
||||
|
||||
static void timer_fn(void *arg) {
|
||||
struct mip_if *ifp = arg; // And show
|
||||
struct mg_tcpip_if *ifp = arg; // And show
|
||||
const char *names[] = {"down", "up", "ready"}; // network stats
|
||||
MG_INFO(("Ethernet: %s, IP: %M, rx:%u, tx:%u, dr:%u, er:%u",
|
||||
names[ifp->state], mg_print_ip4, &ifp->ip, ifp->nrecv, ifp->nsent,
|
||||
@ -68,10 +68,10 @@ static void server(void *args) {
|
||||
// IP configuration. If IP/mask/GW are unset, DHCP is going to be used
|
||||
MG_INFO(("Initializing Ethernet driver"));
|
||||
ethernet_init();
|
||||
struct mip_driver_stm32_data driver_data = {.mdc_cr = 4};
|
||||
struct mip_if mif = {.driver = &mip_driver_stm32,
|
||||
.driver_data = &driver_data};
|
||||
mip_init(&mgr, &mif);
|
||||
struct mg_tcpip_driver_stm32_data driver_data = {.mdc_cr = 4};
|
||||
struct mg_tcpip_if mif = {.driver = &mg_tcpip_driver_stm32,
|
||||
.driver_data = &driver_data};
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
|
||||
MG_INFO(("Starting Mongoose v%s", MG_VERSION)); // Tell the world
|
||||
mg_http_listen(&mgr, "http://0.0.0.0", fn, &mgr); // Web listener
|
||||
|
@ -4,6 +4,6 @@
|
||||
|
||||
// See https://mongoose.ws/documentation/#build-options
|
||||
#define MG_ARCH MG_ARCH_FREERTOS
|
||||
#define MG_ENABLE_MIP 1
|
||||
#define MG_ENABLE_TCPIP 1
|
||||
#define MG_IO_SIZE 256
|
||||
#define MG_ENABLE_CUSTOM_RANDOM 1
|
||||
|
@ -18,7 +18,7 @@ SOURCES += tinyusb/src/tusb.c \
|
||||
tinyusb/lib/networking/rndis_reports.c \
|
||||
usb_descriptors.c
|
||||
CFLAGS += -Itinyusb/src -Itinyusb/lib/networking
|
||||
CFLAGS += -DMG_ARCH=MG_ARCH_NEWLIB -DMG_ENABLE_MIP=1 -DMG_ENABLE_PACKED_FS=1 -DMG_IO_SIZE=512 -DMG_ENABLE_CUSTOM_MILLIS=1
|
||||
CFLAGS += -DMG_ARCH=MG_ARCH_NEWLIB -DMG_ENABLE_TCPIP=1 -DMG_ENABLE_PACKED_FS=1 -DMG_IO_SIZE=512 -DMG_ENABLE_CUSTOM_MILLIS=1
|
||||
CFLAGS += -DSTM32F746xx
|
||||
CFLAGS += -Wno-conversion -Wno-sign-conversion
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#define LED PIN('B', 7) // On-board LED pin (blue)
|
||||
static uint64_t s_ticks;
|
||||
static struct mip_if *s_ifp;
|
||||
static struct mg_tcpip_if *s_ifp;
|
||||
uint32_t SystemCoreClock = SYS_FREQUENCY;
|
||||
const uint8_t tud_network_mac_address[6] = {2, 2, 0x84, 0x6A, 0x96, 0};
|
||||
|
||||
@ -25,7 +25,7 @@ void SysTick_Handler(void) { // SyStick IRQ handler, triggered every 1ms
|
||||
}
|
||||
|
||||
bool tud_network_recv_cb(const uint8_t *buf, uint16_t len) {
|
||||
mip_qwrite((void *) buf, len, s_ifp);
|
||||
mg_tcpip_qwrite((void *) buf, len, s_ifp);
|
||||
// MG_INFO(("RECV %hu", len));
|
||||
// mg_hexdump(buf, len);
|
||||
tud_network_recv_renew();
|
||||
@ -45,7 +45,7 @@ uint16_t tud_network_xmit_cb(uint8_t *dst, void *ref, uint16_t arg) {
|
||||
return arg;
|
||||
}
|
||||
|
||||
static size_t usb_tx(const void *buf, size_t len, struct mip_if *ifp) {
|
||||
static size_t usb_tx(const void *buf, size_t len, struct mg_tcpip_if *ifp) {
|
||||
if (!tud_ready()) return 0;
|
||||
while (!tud_network_can_xmit(len)) tud_task();
|
||||
tud_network_xmit((void *) buf, len);
|
||||
@ -53,7 +53,7 @@ static size_t usb_tx(const void *buf, size_t len, struct mip_if *ifp) {
|
||||
return len;
|
||||
}
|
||||
|
||||
static bool usb_up(struct mip_if *ifp) {
|
||||
static bool usb_up(struct mg_tcpip_if *ifp) {
|
||||
(void) ifp;
|
||||
return tud_inited() && tud_ready() && tud_connected();
|
||||
}
|
||||
@ -84,15 +84,16 @@ int main(void) {
|
||||
mg_timer_add(&mgr, 500, MG_TIMER_REPEAT, blink_cb, &mgr);
|
||||
|
||||
MG_INFO(("Init TCP/IP stack ..."));
|
||||
struct mip_driver driver = {.tx = usb_tx, .rx = mip_driver_rx, .up = usb_up};
|
||||
struct mip_if mif = {.mac = {2, 0, 1, 2, 3, 0x77},
|
||||
.ip = mg_htonl(MG_U32(192, 168, 3, 1)),
|
||||
.mask = mg_htonl(MG_U32(255, 255, 255, 0)),
|
||||
.enable_dhcp_server = true,
|
||||
.driver = &driver,
|
||||
.queue.len = 4096};
|
||||
struct mg_tcpip_driver driver = {
|
||||
.tx = usb_tx, .rx = mg_tcpip_driver_rx, .up = usb_up};
|
||||
struct mg_tcpip_if mif = {.mac = {2, 0, 1, 2, 3, 0x77},
|
||||
.ip = mg_htonl(MG_U32(192, 168, 3, 1)),
|
||||
.mask = mg_htonl(MG_U32(255, 255, 255, 0)),
|
||||
.enable_dhcp_server = true,
|
||||
.driver = &driver,
|
||||
.queue.len = 4096};
|
||||
s_ifp = &mif;
|
||||
mip_init(&mgr, &mif);
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
mg_http_listen(&mgr, "tcp://0.0.0.0:80", fn, &mgr);
|
||||
|
||||
MG_INFO(("Init USB ..."));
|
||||
@ -103,8 +104,8 @@ int main(void) {
|
||||
gpio_init(PIN('A', 9), GPIO_MODE_INPUT, GPIO_OTYPE_PUSH_PULL, GPIO_SPEED_HIGH,
|
||||
GPIO_PULL_NONE, 0); // VBUS
|
||||
gpio_init(PIN('A', 10), GPIO_MODE_AF, GPIO_OTYPE_OPEN_DRAIN, GPIO_SPEED_HIGH,
|
||||
GPIO_PULL_UP, 10); // ID
|
||||
RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN; // Enable USB FS clock
|
||||
GPIO_PULL_UP, 10); // ID
|
||||
RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN; // Enable USB FS clock
|
||||
tusb_init();
|
||||
|
||||
MG_INFO(("Init done, starting main loop ..."));
|
||||
|
@ -8,7 +8,7 @@ LDFLAGS ?= -Tlink.ld -nostartfiles -nostdlib --specs nano.specs -lc -lgcc -Wl,--
|
||||
SOURCES = startup.c main.c syscalls.c
|
||||
|
||||
# Add Mongoose-specific flags and source files
|
||||
CFLAGS += -I../../.. -DMG_ARCH=MG_ARCH_NEWLIB -DMG_ENABLE_CUSTOM_MILLIS=1 -DMG_ENABLE_MIP=1 -DMG_ENABLE_DRIVER_STM32H=1 -DMG_ENABLE_PACKED_FS=1
|
||||
CFLAGS += -I../../.. -DMG_ARCH=MG_ARCH_NEWLIB -DMG_ENABLE_CUSTOM_MILLIS=1 -DMG_ENABLE_TCPIP=1 -DMG_ENABLE_DRIVER_STM32H=1 -DMG_ENABLE_PACKED_FS=1
|
||||
SOURCES += ../../../mongoose.c ../../device-dashboard/net.c ../../device-dashboard/packed_fs.c
|
||||
|
||||
all build example: firmware.bin
|
||||
|
@ -10,7 +10,7 @@ which implements the following:
|
||||
- MQTT communication with a remote MQTT server
|
||||
- No dependencies: no HAL, no CMSIS, no RTOS
|
||||
- Hand-written [mcu.h](mcu.h) header based on the [datasheet](https://www.st.com/resource/en/reference_manual/rm0433-stm32h742-stm32h743753-and-stm32h750-value-line-advanced-armbased-32bit-mcus-stmicroelectronics.pdf)
|
||||
- Interrupt-driven [Ethernet driver](../../../drivers/mip_driver_stm32h.c)
|
||||
- Interrupt-driven [Ethernet driver](../../../drivers/driver_stm32h.c)
|
||||
- Debug log on UART3 (st-link)
|
||||
|
||||
## Requirements
|
||||
|
@ -55,14 +55,13 @@ int main(void) {
|
||||
// Initialise Mongoose network stack
|
||||
// Specify MAC address, and IP/mask/GW in network byte order for static
|
||||
// IP configuration. If IP/mask/GW are unset, DHCP is going to be used
|
||||
struct mip_driver_stm32h_data driver_data = {.mdc_cr =
|
||||
4}; // See driver_stm32h.h
|
||||
struct mip_if mif = {
|
||||
struct mg_tcpip_driver_stm32h_data driver_data = {.mdc_cr = 4};
|
||||
struct mg_tcpip_if mif = {
|
||||
.mac = {2, 0, 1, 2, 3, 5},
|
||||
.driver = &mip_driver_stm32h,
|
||||
.driver = &mg_tcpip_driver_stm32h,
|
||||
.driver_data = &driver_data,
|
||||
};
|
||||
mip_init(&mgr, &mif);
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
|
||||
MG_INFO(("Waiting until network is up..."));
|
||||
while (mif.state != MIP_STATE_READY) {
|
||||
|
@ -4,7 +4,7 @@ CFLAGS ?= -W -Wall -Wextra -Werror -Wundef -Wshadow -Wdouble-promotion \
|
||||
-Wformat-truncation -fno-common -Wconversion \
|
||||
-g3 -Os -ffunction-sections -fdata-sections -I. -I$(ROOT) \
|
||||
-DMG_ARCH=MG_ARCH_NEWLIB -DMIP_DEBUG=1 -DMG_ENABLE_PACKED_FS=1 \
|
||||
-DMG_ENABLE_CUSTOM_MILLIS=1 -DxMG_ENABLE_LINES=1 -DMG_ENABLE_MIP=1 -DMG_ENABLE_DRIVER_TM4C=1\
|
||||
-DMG_ENABLE_CUSTOM_MILLIS=1 -DxMG_ENABLE_LINES=1 -DMG_ENABLE_TCPIP=1 -DMG_ENABLE_DRIVER_TM4C=1\
|
||||
-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 $(EXTRA_CFLAGS)
|
||||
LDFLAGS ?= -Tlink.ld -nostartfiles -nostdlib --specs nano.specs -lc -lgcc -Wl,--gc-sections -Wl,-Map=$@.map
|
||||
SOURCES = boot.c main.c syscalls.c \
|
||||
|
@ -10,7 +10,7 @@ which implements the following:
|
||||
- MQTT communication with a remote MQTT server
|
||||
- No dependencies: no HAL, no CMSIS, no RTOS
|
||||
- Hand-written [mcu.h](mcu.h) header based on the [datasheet](https://www.ti.com/lit/pdf/spms433)
|
||||
- Interrupt-driven [Ethernet driver](../../../drivers/mip_driver_tm4c.c)
|
||||
- Interrupt-driven Ethernet driver
|
||||
- LED blinky, based on SysTick interrupt
|
||||
- User button handler, turns off/on an LED, based on GPIO IRQs (interrupt-driven)
|
||||
- HardFault handler alternate blinks LEDs
|
||||
|
@ -14,7 +14,7 @@
|
||||
static uint64_t s_ticks, s_exti; // Counters, increased by IRQ handlers
|
||||
|
||||
static void blink_cb(void *arg) { // Blink periodically
|
||||
struct mip_if *ifp = arg;
|
||||
struct mg_tcpip_if *ifp = arg;
|
||||
gpio_toggle(LED1);
|
||||
MG_INFO(("Ethernet: %s", ifp->driver->up(ifp) ? "up": "down"));
|
||||
}
|
||||
@ -86,13 +86,13 @@ int main(void) {
|
||||
// Initialize Mongoose network stack
|
||||
// Specify MAC address, and IP/mask/GW in network byte order for static
|
||||
// IP configuration. If IP/mask/GW are unset, DHCP is going to be used
|
||||
struct mip_driver_tm4c_data driver_data = {.mdc_cr = 1}; // See driver_tm4c.h
|
||||
struct mip_if mif = {
|
||||
struct mg_tcpip_driver_tm4c_data driver_data = {.mdc_cr = 1}; // See driver_tm4c.h
|
||||
struct mg_tcpip_if mif = {
|
||||
.mac = {2, 0, 1, 2, 3, 5},
|
||||
.driver = &mip_driver_tm4c,
|
||||
.driver = &mg_tcpip_driver_tm4c,
|
||||
.driver_data = &driver_data,
|
||||
};
|
||||
mip_init(&mgr, &mif);
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
val = IMC[0xFC8 / sizeof(*IMC)]; // Turn Flash Prefetch on again
|
||||
val &= ~BIT(16);
|
||||
val |= BIT(17);
|
||||
|
@ -6,7 +6,7 @@ It implements the following:
|
||||
- Minimal elementary web server, as simple as possible
|
||||
- No dependencies: no HAL, no CMSIS
|
||||
- Hand-written [mcu.h](mcu.h) header based on the [datasheet](https://www.ti.com/lit/pdf/spms433)
|
||||
- Interrupt-driven [Ethernet driver](../../../drivers/mip_driver_tm4c.c)
|
||||
- Interrupt-driven Ethernet driver
|
||||
- LED blinky, based on another FreeRTOS task
|
||||
- Debug log on UART0 (ICDI)
|
||||
|
||||
|
@ -60,13 +60,13 @@ static void server(void *args) {
|
||||
// IP configuration. If IP/mask/GW are unset, DHCP is going to be used
|
||||
MG_INFO(("Initializing Ethernet driver"));
|
||||
ethernet_init();
|
||||
struct mip_driver_tm4c_data driver_data = {.mdc_cr = 1}; // See driver_tm4c.h
|
||||
struct mip_if mif = {
|
||||
struct mg_tcpip_driver_tm4c_data driver_data = {.mdc_cr = 1}; // See driver_tm4c.h
|
||||
struct mg_tcpip_if mif = {
|
||||
.mac = {2, 0, 1, 2, 3, 5},
|
||||
.driver = &mip_driver_tm4c,
|
||||
.driver = &mg_tcpip_driver_tm4c,
|
||||
.driver_data = &driver_data,
|
||||
};
|
||||
mip_init(&mgr, &mif);
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
volatile uint32_t *IMC = (uint32_t *) 0x400FD000;
|
||||
uint32_t val = IMC[0xFC8 / sizeof(*IMC)]; // Turn Flash Prefetch on again
|
||||
val &= ~BIT(16);
|
||||
|
@ -3,6 +3,6 @@
|
||||
#include <errno.h> // we are not using lwIP
|
||||
|
||||
#define MG_ARCH MG_ARCH_FREERTOS
|
||||
#define MG_ENABLE_MIP 1
|
||||
#define MG_ENABLE_TCPIP 1
|
||||
#define MG_ENABLE_DRIVER_TM4C 1
|
||||
#define MG_IO_SIZE 256
|
||||
|
@ -1,19 +0,0 @@
|
||||
# MIP - a built-in TCP/IP stack for Mongoose Library
|
||||
|
||||
This bare-metal embedded TCP/IP stack is designed specifically for Mongoose.
|
||||
Works with or without RTOS. Makes it possible to implement networking without
|
||||
any extra software - just drop `mongoose.c` and `mongoose.h` into your sources,
|
||||
and you're done!
|
||||
|
||||
## Implemented drivers
|
||||
|
||||
- STM32F4xx
|
||||
- STM32F7xx
|
||||
- W5500
|
||||
|
||||
## Example usage
|
||||
|
||||
- [nucleo-f746 bare metal](../examples/stm32/nucleo-f746zg-baremetal)
|
||||
- [nucleo-f429 bare metal](../examples/stm32/nucleo-f429zi-baremetal)
|
||||
- (VIDEO) [stm32f7 with CubeIDE](https://www.youtube.com/watch?v=8htC_TSBeO0)
|
||||
- [Xiao M0 SAMD21 Arduino + W5500](../examples/arduino/w5500)
|
79
mip/mip.h
79
mip/mip.h
@ -1,79 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "arch.h"
|
||||
#include "net.h"
|
||||
|
||||
struct mip_if; // MIP network interface
|
||||
|
||||
struct mip_driver {
|
||||
bool (*init)(struct mip_if *); // Initialise driver
|
||||
size_t (*tx)(const void *, size_t, struct mip_if *); // Transmit frame
|
||||
size_t (*rx)(void *buf, size_t len, struct mip_if *); // Receive frame (poll)
|
||||
bool (*up)(struct mip_if *); // Up/down status
|
||||
};
|
||||
|
||||
// Receive queue - single producer, single consumer queue. Interrupt-based
|
||||
// drivers copy received frames to the queue in interrupt context. mip_poll()
|
||||
// function runs in event loop context, reads from the queue
|
||||
struct queue {
|
||||
uint8_t *buf;
|
||||
size_t len;
|
||||
volatile size_t tail, head;
|
||||
};
|
||||
|
||||
// Network interface
|
||||
struct mip_if {
|
||||
uint8_t mac[6]; // MAC address. Must be set to a valid MAC
|
||||
uint32_t ip, mask, gw; // IP address, mask, default gateway
|
||||
struct mg_str rx; // Output (TX) buffer
|
||||
struct mg_str tx; // Input (RX) buffer
|
||||
bool enable_dhcp_client; // Enable DCHP client
|
||||
bool enable_dhcp_server; // Enable DCHP server
|
||||
struct mip_driver *driver; // Low level driver
|
||||
void *driver_data; // Driver-specific data
|
||||
struct mg_mgr *mgr; // Mongoose event manager
|
||||
struct queue queue; // Set queue.len for interrupt based drivers
|
||||
|
||||
// Internal state, user can use it but should not change it
|
||||
uint8_t gwmac[6]; // Router's MAC
|
||||
uint64_t now; // Current time
|
||||
uint64_t timer_1000ms; // 1000 ms timer: for DHCP and link state
|
||||
uint64_t lease_expire; // Lease expiration time
|
||||
uint16_t eport; // Next ephemeral port
|
||||
volatile uint32_t ndrop; // Number of received, but dropped frames
|
||||
volatile uint32_t nrecv; // Number of received frames
|
||||
volatile uint32_t nsent; // Number of transmitted frames
|
||||
volatile uint32_t nerr; // Number of driver errors
|
||||
uint8_t state; // Current state
|
||||
#define MIP_STATE_DOWN 0 // Interface is down
|
||||
#define MIP_STATE_UP 1 // Interface is up
|
||||
#define MIP_STATE_READY 2 // Interface is up and has IP
|
||||
};
|
||||
|
||||
void mip_init(struct mg_mgr *, struct mip_if *);
|
||||
void mip_free(struct mip_if *);
|
||||
void mip_qwrite(void *buf, size_t len, struct mip_if *ifp);
|
||||
size_t mip_qread(void *buf, struct mip_if *ifp);
|
||||
// conveniency rx function for IRQ-driven drivers
|
||||
size_t mip_driver_rx(void *buf, size_t len, struct mip_if *ifp);
|
||||
|
||||
extern struct mip_driver mip_driver_stm32;
|
||||
extern struct mip_driver mip_driver_w5500;
|
||||
extern struct mip_driver mip_driver_tm4c;
|
||||
extern struct mip_driver mip_driver_stm32h;
|
||||
|
||||
// Drivers that require SPI, can use this SPI abstraction
|
||||
struct mip_spi {
|
||||
void *spi; // Opaque SPI bus descriptor
|
||||
void (*begin)(void *); // SPI begin: slave select low
|
||||
void (*end)(void *); // SPI end: slave select high
|
||||
uint8_t (*txn)(void *, uint8_t); // SPI transaction: write 1 byte, read reply
|
||||
};
|
||||
|
||||
#if MG_ENABLE_MIP
|
||||
#if !defined(MG_ENABLE_DRIVER_STM32H) && !defined(MG_ENABLE_DRIVER_TM4C)
|
||||
#define MG_ENABLE_DRIVER_STM32 1
|
||||
#else
|
||||
#define MG_ENABLE_DRIVER_STM32 0
|
||||
#endif
|
||||
#endif
|
212
mongoose.c
212
mongoose.c
@ -5935,11 +5935,11 @@ size_t mg_ws_wrap(struct mg_connection *c, size_t len, int op) {
|
||||
}
|
||||
|
||||
#ifdef MG_ENABLE_LINES
|
||||
#line 1 "mip/driver_stm32.c"
|
||||
#line 1 "src/tcpip/driver_stm32.c"
|
||||
#endif
|
||||
|
||||
|
||||
#if MG_ENABLE_MIP && MG_ENABLE_DRIVER_STM32
|
||||
#if MG_ENABLE_TCPIP && MG_ENABLE_DRIVER_STM32
|
||||
struct stm32_eth {
|
||||
volatile uint32_t MACCR, MACFFR, MACHTHR, MACHTLR, MACMIIAR, MACMIIDR, MACFCR,
|
||||
MACVLANTR, RESERVED0[2], MACRWUFFR, MACPMTCSR, RESERVED1, MACDBGR, MACSR,
|
||||
@ -5966,10 +5966,10 @@ static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS]; // RX descriptors
|
||||
static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]; // TX descriptors
|
||||
static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // RX ethernet buffers
|
||||
static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // TX ethernet buffers
|
||||
static uint8_t s_txno; // Current TX descriptor
|
||||
static uint8_t s_rxno; // Current RX descriptor
|
||||
static uint8_t s_txno; // Current TX descriptor
|
||||
static uint8_t s_rxno; // Current RX descriptor
|
||||
|
||||
static struct mip_if *s_ifp; // MIP interface
|
||||
static struct mg_tcpip_if *s_ifp; // MIP interface
|
||||
enum { PHY_ADDR = 0, PHY_BCR = 0, PHY_BSR = 1, PHY_CSCR = 31 };
|
||||
|
||||
static uint32_t eth_read_phy(uint8_t addr, uint8_t reg) {
|
||||
@ -6042,9 +6042,9 @@ static int guess_mdc_cr(void) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool mip_driver_stm32_init(struct mip_if *ifp) {
|
||||
struct mip_driver_stm32_data *d =
|
||||
(struct mip_driver_stm32_data *) ifp->driver_data;
|
||||
static bool mg_tcpip_driver_stm32_init(struct mg_tcpip_if *ifp) {
|
||||
struct mg_tcpip_driver_stm32_data *d =
|
||||
(struct mg_tcpip_driver_stm32_data *) ifp->driver_data;
|
||||
s_ifp = ifp;
|
||||
|
||||
// Init RX descriptors
|
||||
@ -6093,8 +6093,8 @@ static bool mip_driver_stm32_init(struct mip_if *ifp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static size_t mip_driver_stm32_tx(const void *buf, size_t len,
|
||||
struct mip_if *ifp) {
|
||||
static size_t mg_tcpip_driver_stm32_tx(const void *buf, size_t len,
|
||||
struct mg_tcpip_if *ifp) {
|
||||
if (len > sizeof(s_txbuf[s_txno])) {
|
||||
MG_ERROR(("Frame too big, %ld", (long) len));
|
||||
len = 0; // Frame is too big
|
||||
@ -6115,7 +6115,7 @@ static size_t mip_driver_stm32_tx(const void *buf, size_t len,
|
||||
return len;
|
||||
}
|
||||
|
||||
static bool mip_driver_stm32_up(struct mip_if *ifp) {
|
||||
static bool mg_tcpip_driver_stm32_up(struct mg_tcpip_if *ifp) {
|
||||
uint32_t bsr = eth_read_phy(PHY_ADDR, PHY_BSR);
|
||||
bool up = bsr & BIT(2) ? 1 : 0;
|
||||
if ((ifp->state == MIP_STATE_DOWN) && up) { // link state just went up
|
||||
@ -6141,7 +6141,7 @@ void ETH_IRQHandler(void) {
|
||||
uint32_t len = ((s_rxdesc[s_rxno][0] >> 16) & (BIT(14) - 1));
|
||||
// printf("%lx %lu %lx %.8lx\n", s_rxno, len, s_rxdesc[s_rxno][0],
|
||||
// ETH->DMASR);
|
||||
mip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
|
||||
mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
|
||||
}
|
||||
s_rxdesc[s_rxno][0] = BIT(31);
|
||||
if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
|
||||
@ -6151,17 +6151,18 @@ void ETH_IRQHandler(void) {
|
||||
ETH->DMARPDR = 0; // and resume RX
|
||||
}
|
||||
|
||||
struct mip_driver mip_driver_stm32 = {mip_driver_stm32_init,
|
||||
mip_driver_stm32_tx, mip_driver_rx,
|
||||
mip_driver_stm32_up};
|
||||
struct mg_tcpip_driver mg_tcpip_driver_stm32 = {
|
||||
mg_tcpip_driver_stm32_init, mg_tcpip_driver_stm32_tx, mg_tcpip_driver_rx,
|
||||
mg_tcpip_driver_stm32_up};
|
||||
#endif
|
||||
|
||||
#ifdef MG_ENABLE_LINES
|
||||
#line 1 "mip/driver_stm32h.c"
|
||||
#line 1 "src/tcpip/driver_stm32h.c"
|
||||
#endif
|
||||
|
||||
|
||||
#if MG_ENABLE_MIP && defined(MG_ENABLE_DRIVER_STM32H) && MG_ENABLE_DRIVER_STM32H
|
||||
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_STM32H) && \
|
||||
MG_ENABLE_DRIVER_STM32H
|
||||
struct stm32h_eth {
|
||||
volatile uint32_t MACCR, MACECR, MACPFR, MACWTR, MACHT0R, MACHT1R,
|
||||
RESERVED1[14], MACVTR, RESERVED2, MACVHTR, RESERVED3, MACVIR, MACIVIR,
|
||||
@ -6206,7 +6207,7 @@ static volatile uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS]; // RX descriptors
|
||||
static volatile uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]; // TX descriptors
|
||||
static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // RX ethernet buffers
|
||||
static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // TX ethernet buffers
|
||||
static struct mip_if *s_ifp; // MIP interface
|
||||
static struct mg_tcpip_if *s_ifp; // MIP interface
|
||||
enum {
|
||||
PHY_ADDR = 0,
|
||||
PHY_BCR = 0,
|
||||
@ -6306,9 +6307,9 @@ static int guess_mdc_cr(void) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool mip_driver_stm32h_init(struct mip_if *ifp) {
|
||||
struct mip_driver_stm32h_data *d =
|
||||
(struct mip_driver_stm32h_data *) ifp->driver_data;
|
||||
static bool mg_tcpip_driver_stm32h_init(struct mg_tcpip_if *ifp) {
|
||||
struct mg_tcpip_driver_stm32h_data *d =
|
||||
(struct mg_tcpip_driver_stm32h_data *) ifp->driver_data;
|
||||
s_ifp = ifp;
|
||||
|
||||
// Init RX descriptors
|
||||
@ -6368,8 +6369,8 @@ static bool mip_driver_stm32h_init(struct mip_if *ifp) {
|
||||
}
|
||||
|
||||
static uint32_t s_txno;
|
||||
static size_t mip_driver_stm32h_tx(const void *buf, size_t len,
|
||||
struct mip_if *ifp) {
|
||||
static size_t mg_tcpip_driver_stm32h_tx(const void *buf, size_t len,
|
||||
struct mg_tcpip_if *ifp) {
|
||||
if (len > sizeof(s_txbuf[s_txno])) {
|
||||
MG_ERROR(("Frame too big, %ld", (long) len));
|
||||
len = 0; // Frame is too big
|
||||
@ -6391,7 +6392,7 @@ static size_t mip_driver_stm32h_tx(const void *buf, size_t len,
|
||||
(void) ifp;
|
||||
}
|
||||
|
||||
static bool mip_driver_stm32h_up(struct mip_if *ifp) {
|
||||
static bool mg_tcpip_driver_stm32h_up(struct mg_tcpip_if *ifp) {
|
||||
uint32_t bsr = eth_read_phy(PHY_ADDR, PHY_BSR);
|
||||
bool up = bsr & BIT(2) ? 1 : 0;
|
||||
if ((ifp->state == MIP_STATE_DOWN) && up) { // link state just went up
|
||||
@ -6419,7 +6420,7 @@ void ETH_IRQHandler(void) {
|
||||
uint32_t len = s_rxdesc[s_rxno][3] & (BIT(15) - 1);
|
||||
// MG_DEBUG(("%lx %lu %lx %08lx", s_rxno, len, s_rxdesc[s_rxno][3],
|
||||
// ETH->DMACSR));
|
||||
mip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
|
||||
mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
|
||||
}
|
||||
s_rxdesc[s_rxno][3] = BIT(31) | BIT(30) | BIT(24); // OWN, IOC, BUF1V
|
||||
if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
|
||||
@ -6430,17 +6431,17 @@ void ETH_IRQHandler(void) {
|
||||
(uint32_t) (uintptr_t) &s_rxdesc[ETH_DESC_CNT - 1]; // and resume RX
|
||||
}
|
||||
|
||||
struct mip_driver mip_driver_stm32h = {mip_driver_stm32h_init,
|
||||
mip_driver_stm32h_tx, mip_driver_rx,
|
||||
mip_driver_stm32h_up};
|
||||
struct mg_tcpip_driver mg_tcpip_driver_stm32h = {
|
||||
mg_tcpip_driver_stm32h_init, mg_tcpip_driver_stm32h_tx, mg_tcpip_driver_rx,
|
||||
mg_tcpip_driver_stm32h_up};
|
||||
#endif
|
||||
|
||||
#ifdef MG_ENABLE_LINES
|
||||
#line 1 "mip/driver_tm4c.c"
|
||||
#line 1 "src/tcpip/driver_tm4c.c"
|
||||
#endif
|
||||
|
||||
|
||||
#if MG_ENABLE_MIP && defined(MG_ENABLE_DRIVER_TM4C) && MG_ENABLE_DRIVER_TM4C
|
||||
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_TM4C) && MG_ENABLE_DRIVER_TM4C
|
||||
struct tm4c_emac {
|
||||
volatile uint32_t EMACCFG, EMACFRAMEFLTR, EMACHASHTBLH, EMACHASHTBLL,
|
||||
EMACMIIADDR, EMACMIIDATA, EMACFLOWCTL, EMACVLANTG, RESERVED0, EMACSTATUS,
|
||||
@ -6474,7 +6475,7 @@ static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS]; // RX descriptors
|
||||
static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]; // TX descriptors
|
||||
static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // RX ethernet buffers
|
||||
static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // TX ethernet buffers
|
||||
static struct mip_if *s_ifp; // MIP interface
|
||||
static struct mg_tcpip_if *s_ifp; // MIP interface
|
||||
enum {
|
||||
EPHY_ADDR = 0,
|
||||
EPHYBMCR = 0,
|
||||
@ -6568,9 +6569,9 @@ static int guess_mdc_cr(void) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool mip_driver_tm4c_init(struct mip_if *ifp) {
|
||||
struct mip_driver_tm4c_data *d =
|
||||
(struct mip_driver_tm4c_data *) ifp->driver_data;
|
||||
static bool mg_tcpip_driver_tm4c_init(struct mg_tcpip_if *ifp) {
|
||||
struct mg_tcpip_driver_tm4c_data *d =
|
||||
(struct mg_tcpip_driver_tm4c_data *) ifp->driver_data;
|
||||
s_ifp = ifp;
|
||||
|
||||
// Init RX descriptors
|
||||
@ -6624,8 +6625,8 @@ static bool mip_driver_tm4c_init(struct mip_if *ifp) {
|
||||
}
|
||||
|
||||
static uint32_t s_txno;
|
||||
static size_t mip_driver_tm4c_tx(const void *buf, size_t len,
|
||||
struct mip_if *ifp) {
|
||||
static size_t mg_tcpip_driver_tm4c_tx(const void *buf, size_t len,
|
||||
struct mg_tcpip_if *ifp) {
|
||||
if (len > sizeof(s_txbuf[s_txno])) {
|
||||
MG_ERROR(("Frame too big, %ld", (long) len));
|
||||
len = 0; // fail
|
||||
@ -6648,7 +6649,7 @@ static size_t mip_driver_tm4c_tx(const void *buf, size_t len,
|
||||
(void) ifp;
|
||||
}
|
||||
|
||||
static bool mip_driver_tm4c_up(struct mip_if *ifp) {
|
||||
static bool mg_tcpip_driver_tm4c_up(struct mg_tcpip_if *ifp) {
|
||||
uint32_t bmsr = emac_read_phy(EPHY_ADDR, EPHYBMSR);
|
||||
bool up = (bmsr & BIT(2)) ? 1 : 0;
|
||||
if ((ifp->state == MIP_STATE_DOWN) && up) { // link state just went up
|
||||
@ -6675,7 +6676,7 @@ void EMAC0_IRQHandler(void) {
|
||||
uint32_t len = ((s_rxdesc[s_rxno][0] >> 16) & (BIT(14) - 1));
|
||||
// printf("%lx %lu %lx %.8lx\n", s_rxno, len, s_rxdesc[s_rxno][0],
|
||||
// EMAC->EMACDMARIS);
|
||||
mip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
|
||||
mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
|
||||
}
|
||||
s_rxdesc[s_rxno][0] = BIT(31);
|
||||
if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
|
||||
@ -6685,20 +6686,21 @@ void EMAC0_IRQHandler(void) {
|
||||
EMAC->EMACRXPOLLD = 0; // and resume RX
|
||||
}
|
||||
|
||||
struct mip_driver mip_driver_tm4c = {mip_driver_tm4c_init, mip_driver_tm4c_tx,
|
||||
mip_driver_rx, mip_driver_tm4c_up};
|
||||
struct mg_tcpip_driver mg_tcpip_driver_tm4c = {
|
||||
mg_tcpip_driver_tm4c_init, mg_tcpip_driver_tm4c_tx, mg_tcpip_driver_rx,
|
||||
mg_tcpip_driver_tm4c_up};
|
||||
#endif
|
||||
|
||||
#ifdef MG_ENABLE_LINES
|
||||
#line 1 "mip/driver_w5500.c"
|
||||
#line 1 "src/tcpip/driver_w5500.c"
|
||||
#endif
|
||||
|
||||
|
||||
#if MG_ENABLE_MIP
|
||||
#if MG_ENABLE_TCPIP
|
||||
|
||||
enum { W5500_CR = 0, W5500_S0 = 1, W5500_TX0 = 2, W5500_RX0 = 3 };
|
||||
|
||||
static void w5500_txn(struct mip_spi *s, uint8_t block, uint16_t addr, bool wr,
|
||||
static void w5500_txn(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, bool wr,
|
||||
void *buf, size_t len) {
|
||||
uint8_t *p = (uint8_t *) buf;
|
||||
uint8_t cmd[] = {(uint8_t) (addr >> 8), (uint8_t) (addr & 255),
|
||||
@ -6713,16 +6715,16 @@ static void w5500_txn(struct mip_spi *s, uint8_t block, uint16_t addr, bool wr,
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
static void w5500_wn(struct mip_spi *s, uint8_t block, uint16_t addr, void *buf, size_t len) { w5500_txn(s, block, addr, true, buf, len); }
|
||||
static void w5500_w1(struct mip_spi *s, uint8_t block, uint16_t addr, uint8_t val) { w5500_wn(s, block, addr, &val, 1); }
|
||||
static void w5500_w2(struct mip_spi *s, uint8_t block, uint16_t addr, uint16_t val) { uint8_t buf[2] = {(uint8_t) (val >> 8), (uint8_t) (val & 255)}; w5500_wn(s, block, addr, buf, sizeof(buf)); }
|
||||
static void w5500_rn(struct mip_spi *s, uint8_t block, uint16_t addr, void *buf, size_t len) { w5500_txn(s, block, addr, false, buf, len); }
|
||||
static uint8_t w5500_r1(struct mip_spi *s, uint8_t block, uint16_t addr) { uint8_t r = 0; w5500_rn(s, block, addr, &r, 1); return r; }
|
||||
static uint16_t w5500_r2(struct mip_spi *s, uint8_t block, uint16_t addr) { uint8_t buf[2] = {0, 0}; w5500_rn(s, block, addr, buf, sizeof(buf)); return (uint16_t) ((buf[0] << 8) | buf[1]); }
|
||||
static void w5500_wn(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, void *buf, size_t len) { w5500_txn(s, block, addr, true, buf, len); }
|
||||
static void w5500_w1(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, uint8_t val) { w5500_wn(s, block, addr, &val, 1); }
|
||||
static void w5500_w2(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, uint16_t val) { uint8_t buf[2] = {(uint8_t) (val >> 8), (uint8_t) (val & 255)}; w5500_wn(s, block, addr, buf, sizeof(buf)); }
|
||||
static void w5500_rn(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, void *buf, size_t len) { w5500_txn(s, block, addr, false, buf, len); }
|
||||
static uint8_t w5500_r1(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr) { uint8_t r = 0; w5500_rn(s, block, addr, &r, 1); return r; }
|
||||
static uint16_t w5500_r2(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr) { uint8_t buf[2] = {0, 0}; w5500_rn(s, block, addr, buf, sizeof(buf)); return (uint16_t) ((buf[0] << 8) | buf[1]); }
|
||||
// clang-format on
|
||||
|
||||
static size_t w5500_rx(void *buf, size_t buflen, struct mip_if *ifp) {
|
||||
struct mip_spi *s = (struct mip_spi *) ifp->driver_data;
|
||||
static size_t w5500_rx(void *buf, size_t buflen, struct mg_tcpip_if *ifp) {
|
||||
struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
|
||||
uint16_t r = 0, n = 0, len = (uint16_t) buflen, n2; // Read recv len
|
||||
while ((n2 = w5500_r2(s, W5500_S0, 0x26)) > n) n = n2; // Until it is stable
|
||||
// printf("RSR: %d\n", (int) n);
|
||||
@ -6740,8 +6742,8 @@ static size_t w5500_rx(void *buf, size_t buflen, struct mip_if *ifp) {
|
||||
return r;
|
||||
}
|
||||
|
||||
static size_t w5500_tx(const void *buf, size_t buflen, struct mip_if *ifp) {
|
||||
struct mip_spi *s = (struct mip_spi *) ifp->driver_data;
|
||||
static size_t w5500_tx(const void *buf, size_t buflen, struct mg_tcpip_if *ifp) {
|
||||
struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
|
||||
uint16_t n = 0, len = (uint16_t) buflen;
|
||||
while (n < len) n = w5500_r2(s, W5500_S0, 0x20); // Wait for space
|
||||
uint16_t ptr = w5500_r2(s, W5500_S0, 0x24); // Get write pointer
|
||||
@ -6759,8 +6761,8 @@ static size_t w5500_tx(const void *buf, size_t buflen, struct mip_if *ifp) {
|
||||
return len;
|
||||
}
|
||||
|
||||
static bool w5500_init(struct mip_if *ifp) {
|
||||
struct mip_spi *s = (struct mip_spi *) ifp->driver_data;
|
||||
static bool w5500_init(struct mg_tcpip_if *ifp) {
|
||||
struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
|
||||
s->end(s->spi);
|
||||
w5500_w1(s, W5500_CR, 0, 0x80); // Reset chip: CR -> 0x80
|
||||
w5500_w1(s, W5500_CR, 0x2e, 0); // CR PHYCFGR -> reset
|
||||
@ -6773,21 +6775,21 @@ static bool w5500_init(struct mip_if *ifp) {
|
||||
return w5500_r1(s, W5500_S0, 3) == 0x42; // Sock0 SR == MACRAW
|
||||
}
|
||||
|
||||
static bool w5500_up(struct mip_if *ifp) {
|
||||
struct mip_spi *spi = (struct mip_spi *) ifp->driver_data;
|
||||
static bool w5500_up(struct mg_tcpip_if *ifp) {
|
||||
struct mg_tcpip_spi *spi = (struct mg_tcpip_spi *) ifp->driver_data;
|
||||
uint8_t phycfgr = w5500_r1(spi, W5500_CR, 0x2e);
|
||||
return phycfgr & 1; // Bit 0 of PHYCFGR is LNK (0 - down, 1 - up)
|
||||
}
|
||||
|
||||
struct mip_driver mip_driver_w5500 = {w5500_init, w5500_tx, w5500_rx, w5500_up};
|
||||
struct mg_tcpip_driver mg_tcpip_driver_w5500 = {w5500_init, w5500_tx, w5500_rx, w5500_up};
|
||||
#endif
|
||||
|
||||
#ifdef MG_ENABLE_LINES
|
||||
#line 1 "mip/mip.c"
|
||||
#line 1 "src/tcpip/tcpip.c"
|
||||
#endif
|
||||
|
||||
|
||||
#if MG_ENABLE_MIP
|
||||
#if MG_ENABLE_TCPIP
|
||||
|
||||
#define MIP_EPHEMERAL_PORT 49152
|
||||
#define PDIFF(a, b) ((size_t) (((char *) (b)) - ((char *) (a))))
|
||||
@ -6980,7 +6982,7 @@ static uint16_t ipcsum(const void *buf, size_t len) {
|
||||
return csumfin(sum);
|
||||
}
|
||||
|
||||
static size_t ether_output(struct mip_if *ifp, size_t len) {
|
||||
static size_t ether_output(struct mg_tcpip_if *ifp, size_t len) {
|
||||
// size_t min = 64; // Pad short frames to 64 bytes (minimum Ethernet size)
|
||||
// if (len < min) memset(ifp->tx.ptr + len, 0, min - len), len = min;
|
||||
// mg_hexdump(ifp->tx.ptr, len);
|
||||
@ -6989,7 +6991,7 @@ static size_t ether_output(struct mip_if *ifp, size_t len) {
|
||||
return n;
|
||||
}
|
||||
|
||||
static void arp_ask(struct mip_if *ifp, uint32_t ip) {
|
||||
static void arp_ask(struct mg_tcpip_if *ifp, uint32_t ip) {
|
||||
struct eth *eth = (struct eth *) ifp->tx.ptr;
|
||||
struct arp *arp = (struct arp *) (eth + 1);
|
||||
memset(eth->dst, 255, sizeof(eth->dst));
|
||||
@ -7003,7 +7005,7 @@ static void arp_ask(struct mip_if *ifp, uint32_t ip) {
|
||||
ether_output(ifp, PDIFF(eth, arp + 1));
|
||||
}
|
||||
|
||||
static void onstatechange(struct mip_if *ifp) {
|
||||
static void onstatechange(struct mg_tcpip_if *ifp) {
|
||||
if (ifp->state == MIP_STATE_READY) {
|
||||
MG_INFO(("READY, IP: %M", mg_print_ip4, &ifp->ip));
|
||||
MG_INFO((" GW: %M", mg_print_ip4, &ifp->gw));
|
||||
@ -7011,6 +7013,7 @@ static void onstatechange(struct mip_if *ifp) {
|
||||
MG_INFO(
|
||||
(" Lease: %lld sec", (ifp->lease_expire - ifp->now) / 1000));
|
||||
}
|
||||
arp_ask(ifp, ifp->gw);
|
||||
} else if (ifp->state == MIP_STATE_UP) {
|
||||
MG_ERROR(("Link up"));
|
||||
} else if (ifp->state == MIP_STATE_DOWN) {
|
||||
@ -7018,8 +7021,9 @@ static void onstatechange(struct mip_if *ifp) {
|
||||
}
|
||||
}
|
||||
|
||||
static struct ip *tx_ip(struct mip_if *ifp, uint8_t *mac_dst, uint8_t proto,
|
||||
uint32_t ip_src, uint32_t ip_dst, size_t plen) {
|
||||
static struct ip *tx_ip(struct mg_tcpip_if *ifp, uint8_t *mac_dst,
|
||||
uint8_t proto, uint32_t ip_src, uint32_t ip_dst,
|
||||
size_t plen) {
|
||||
struct eth *eth = (struct eth *) ifp->tx.ptr;
|
||||
struct ip *ip = (struct ip *) (eth + 1);
|
||||
memcpy(eth->dst, mac_dst, sizeof(eth->dst));
|
||||
@ -7037,7 +7041,7 @@ static struct ip *tx_ip(struct mip_if *ifp, uint8_t *mac_dst, uint8_t proto,
|
||||
return ip;
|
||||
}
|
||||
|
||||
static void tx_udp(struct mip_if *ifp, uint8_t *mac_dst, uint32_t ip_src,
|
||||
static void tx_udp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src,
|
||||
uint16_t sport, uint32_t ip_dst, uint16_t dport,
|
||||
const void *buf, size_t len) {
|
||||
struct ip *ip =
|
||||
@ -7059,7 +7063,7 @@ static void tx_udp(struct mip_if *ifp, uint8_t *mac_dst, uint32_t ip_src,
|
||||
ether_output(ifp, sizeof(struct eth) + sizeof(*ip) + sizeof(*udp) + len);
|
||||
}
|
||||
|
||||
static void tx_dhcp(struct mip_if *ifp, uint8_t *mac_dst, uint32_t ip_src,
|
||||
static void tx_dhcp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src,
|
||||
uint32_t ip_dst, uint8_t *opts, size_t optslen) {
|
||||
struct dhcp dhcp = {1, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, {0}, 0, {0}};
|
||||
dhcp.magic = mg_htonl(0x63825363);
|
||||
@ -7070,7 +7074,7 @@ static void tx_dhcp(struct mip_if *ifp, uint8_t *mac_dst, uint32_t ip_src,
|
||||
sizeof(dhcp));
|
||||
}
|
||||
|
||||
static void tx_dhcp_request(struct mip_if *ifp, uint8_t *mac_dst,
|
||||
static void tx_dhcp_request(struct mg_tcpip_if *ifp, uint8_t *mac_dst,
|
||||
uint32_t ip_src, uint32_t ip_dst) {
|
||||
uint8_t opts[] = {
|
||||
53, 1, 3, // Type: DHCP request
|
||||
@ -7085,7 +7089,7 @@ static void tx_dhcp_request(struct mip_if *ifp, uint8_t *mac_dst,
|
||||
tx_dhcp(ifp, mac_dst, ip_src, ip_dst, opts, sizeof(opts));
|
||||
}
|
||||
|
||||
static void tx_dhcp_discover(struct mip_if *ifp) {
|
||||
static void tx_dhcp_discover(struct mg_tcpip_if *ifp) {
|
||||
uint8_t mac[6] = {255, 255, 255, 255, 255, 255};
|
||||
uint8_t opts[] = {
|
||||
53, 1, 1, // Type: DHCP discover
|
||||
@ -7108,11 +7112,11 @@ static struct mg_connection *getpeer(struct mg_mgr *mgr, struct pkt *pkt,
|
||||
return c;
|
||||
}
|
||||
|
||||
static void rx_arp(struct mip_if *ifp, struct pkt *pkt) {
|
||||
static void rx_arp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
if (pkt->arp->op == mg_htons(1) && pkt->arp->tpa == ifp->ip) {
|
||||
// ARP request. Make a response, then send
|
||||
MG_DEBUG(("ARP op %d %M: %M?", mg_ntohs(pkt->arp->op), mg_print_ip4,
|
||||
&pkt->arp->spa, mg_print_ip4, &pkt->arp->tpa));
|
||||
// MG_DEBUG(("ARP op %d %M: %M", mg_ntohs(pkt->arp->op), mg_print_ip4,
|
||||
// &pkt->arp->spa, mg_print_ip4, &pkt->arp->tpa));
|
||||
struct eth *eth = (struct eth *) ifp->tx.ptr;
|
||||
struct arp *arp = (struct arp *) (eth + 1);
|
||||
memcpy(eth->dst, pkt->eth->src, sizeof(eth->dst));
|
||||
@ -7124,11 +7128,13 @@ static void rx_arp(struct mip_if *ifp, struct pkt *pkt) {
|
||||
memcpy(arp->sha, ifp->mac, sizeof(pkt->arp->sha));
|
||||
arp->tpa = pkt->arp->spa;
|
||||
arp->spa = ifp->ip;
|
||||
MG_DEBUG(("ARP response: we're %M", mg_print_ip4, &ifp->ip));
|
||||
MG_DEBUG(("ARP: tell %M we're %M", mg_print_ip4, &arp->tpa, mg_print_ip4,
|
||||
&ifp->ip));
|
||||
ether_output(ifp, PDIFF(eth, arp + 1));
|
||||
} else if (pkt->arp->op == mg_htons(2)) {
|
||||
if (memcmp(pkt->arp->tha, ifp->mac, sizeof(pkt->arp->tha)) != 0) return;
|
||||
if (pkt->arp->spa == ifp->gw) {
|
||||
// Got response for the GW ARP request. Set ifp->gwmac
|
||||
memcpy(ifp->gwmac, pkt->arp->sha, sizeof(ifp->gwmac));
|
||||
} else {
|
||||
struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
|
||||
@ -7143,7 +7149,7 @@ static void rx_arp(struct mip_if *ifp, struct pkt *pkt) {
|
||||
}
|
||||
}
|
||||
|
||||
static void rx_icmp(struct mip_if *ifp, struct pkt *pkt) {
|
||||
static void rx_icmp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
// MG_DEBUG(("ICMP %d", (int) len));
|
||||
if (pkt->icmp->type == 8 && pkt->ip != NULL && pkt->ip->dst == ifp->ip) {
|
||||
size_t hlen = sizeof(struct eth) + sizeof(struct ip) + sizeof(struct icmp);
|
||||
@ -7159,7 +7165,7 @@ static void rx_icmp(struct mip_if *ifp, struct pkt *pkt) {
|
||||
}
|
||||
}
|
||||
|
||||
static void rx_dhcp_client(struct mip_if *ifp, struct pkt *pkt) {
|
||||
static void rx_dhcp_client(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
uint32_t ip = 0, gw = 0, mask = 0;
|
||||
uint8_t *p = pkt->dhcp->options,
|
||||
*end = (uint8_t *) &pkt->raw.ptr[pkt->raw.len];
|
||||
@ -7187,7 +7193,7 @@ static void rx_dhcp_client(struct mip_if *ifp, struct pkt *pkt) {
|
||||
}
|
||||
|
||||
// Simple DHCP server that assigns a next IP address: ifp->ip + 1
|
||||
static void rx_dhcp_server(struct mip_if *ifp, struct pkt *pkt) {
|
||||
static void rx_dhcp_server(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
uint8_t op = 0, *p = pkt->dhcp->options,
|
||||
*end = (uint8_t *) &pkt->raw.ptr[pkt->raw.len];
|
||||
if (end < (uint8_t *) (pkt->dhcp + 1)) return;
|
||||
@ -7223,7 +7229,7 @@ static void rx_dhcp_server(struct mip_if *ifp, struct pkt *pkt) {
|
||||
}
|
||||
}
|
||||
|
||||
static void rx_udp(struct mip_if *ifp, struct pkt *pkt) {
|
||||
static void rx_udp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
struct mg_connection *c = getpeer(ifp->mgr, pkt, true);
|
||||
if (c == NULL) {
|
||||
// No UDP listener on this port. Should send ICMP, but keep silent.
|
||||
@ -7243,7 +7249,7 @@ static void rx_udp(struct mip_if *ifp, struct pkt *pkt) {
|
||||
}
|
||||
}
|
||||
|
||||
static size_t tx_tcp(struct mip_if *ifp, uint8_t *dst_mac, uint32_t dst_ip,
|
||||
static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *dst_mac, uint32_t dst_ip,
|
||||
uint8_t flags, uint16_t sport, uint16_t dport,
|
||||
uint32_t seq, uint32_t ack, const void *buf, size_t len) {
|
||||
struct ip *ip =
|
||||
@ -7269,8 +7275,9 @@ static size_t tx_tcp(struct mip_if *ifp, uint8_t *dst_mac, uint32_t dst_ip,
|
||||
return ether_output(ifp, PDIFF(ifp->tx.ptr, tcp + 1) + len);
|
||||
}
|
||||
|
||||
static size_t tx_tcp_pkt(struct mip_if *ifp, struct pkt *pkt, uint8_t flags,
|
||||
uint32_t seq, const void *buf, size_t len) {
|
||||
static size_t tx_tcp_pkt(struct mg_tcpip_if *ifp, struct pkt *pkt,
|
||||
uint8_t flags, uint32_t seq, const void *buf,
|
||||
size_t len) {
|
||||
uint32_t delta = (pkt->tcp->flags & (TH_SYN | TH_FIN)) ? 1 : 0;
|
||||
return tx_tcp(ifp, pkt->eth->src, pkt->ip->src, flags, pkt->tcp->dport,
|
||||
pkt->tcp->sport, seq, mg_htonl(mg_ntohl(pkt->tcp->seq) + delta),
|
||||
@ -7278,7 +7285,7 @@ static size_t tx_tcp_pkt(struct mip_if *ifp, struct pkt *pkt, uint8_t flags,
|
||||
}
|
||||
|
||||
static void settmout(struct mg_connection *c, uint8_t type) {
|
||||
struct mip_if *ifp = (struct mip_if *) c->mgr->priv;
|
||||
struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
|
||||
struct connstate *s = (struct connstate *) (c + 1);
|
||||
unsigned n = type == MIP_TTYPE_ACK ? MIP_TCP_ACK_MS : MIP_TCP_KEEPALIVE_MS;
|
||||
s->timer = ifp->now + n;
|
||||
@ -7310,7 +7317,7 @@ static struct mg_connection *accept_conn(struct mg_connection *lsn,
|
||||
}
|
||||
|
||||
long mg_io_send(struct mg_connection *c, const void *buf, size_t len) {
|
||||
struct mip_if *ifp = (struct mip_if *) c->mgr->priv;
|
||||
struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
|
||||
struct connstate *s = (struct connstate *) (c + 1);
|
||||
size_t max_headers_len = 14 + 24 /* max IP */ + 60 /* max TCP */;
|
||||
if (len + max_headers_len > ifp->tx.len) len = ifp->tx.len - max_headers_len;
|
||||
@ -7371,7 +7378,7 @@ static void read_conn(struct mg_connection *c, struct pkt *pkt) {
|
||||
#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,
|
||||
tx_tcp((struct mg_tcpip_if *) c->mgr->priv, c->rem.ip, TH_ACK, c->loc.port,
|
||||
c->rem.port, mg_htonl(s->seq), mg_htonl(s->ack), "", 0);
|
||||
#else
|
||||
// if not already running, setup a timer to send an ACK later
|
||||
@ -7402,7 +7409,7 @@ static void read_conn(struct mg_connection *c, struct pkt *pkt) {
|
||||
}
|
||||
}
|
||||
|
||||
static void rx_tcp(struct mip_if *ifp, struct pkt *pkt) {
|
||||
static void rx_tcp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
|
||||
struct connstate *s = c == NULL ? NULL : (struct connstate *) (c + 1);
|
||||
#if 0
|
||||
@ -7450,7 +7457,7 @@ static void rx_tcp(struct mip_if *ifp, struct pkt *pkt) {
|
||||
}
|
||||
}
|
||||
|
||||
static void rx_ip(struct mip_if *ifp, struct pkt *pkt) {
|
||||
static void rx_ip(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
if (pkt->ip->proto == 1) {
|
||||
pkt->icmp = (struct icmp *) (pkt->ip + 1);
|
||||
if (pkt->pay.len < sizeof(*pkt->icmp)) return;
|
||||
@ -7488,7 +7495,7 @@ static void rx_ip(struct mip_if *ifp, struct pkt *pkt) {
|
||||
}
|
||||
}
|
||||
|
||||
static void rx_ip6(struct mip_if *ifp, struct pkt *pkt) {
|
||||
static void rx_ip6(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
// MG_DEBUG(("IP %d", (int) len));
|
||||
if (pkt->ip6->proto == 1 || pkt->ip6->proto == 58) {
|
||||
pkt->icmp = (struct icmp *) (pkt->ip6 + 1);
|
||||
@ -7504,7 +7511,7 @@ static void rx_ip6(struct mip_if *ifp, struct pkt *pkt) {
|
||||
}
|
||||
}
|
||||
|
||||
static void mip_rx(struct mip_if *ifp, void *buf, size_t len) {
|
||||
static void mg_tcpip_rx(struct mg_tcpip_if *ifp, void *buf, size_t len) {
|
||||
const uint8_t broadcast[] = {255, 255, 255, 255, 255, 255};
|
||||
struct pkt pkt;
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
@ -7541,7 +7548,7 @@ static void mip_rx(struct mip_if *ifp, void *buf, size_t len) {
|
||||
}
|
||||
}
|
||||
|
||||
static void mip_poll(struct mip_if *ifp, uint64_t uptime_ms) {
|
||||
static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t uptime_ms) {
|
||||
if (ifp == NULL || ifp->driver == NULL) return;
|
||||
bool expired_1000ms = mg_timer_expired(&ifp->timer_1000ms, 1000, uptime_ms);
|
||||
ifp->now = uptime_ms;
|
||||
@ -7566,7 +7573,7 @@ static void mip_poll(struct mip_if *ifp, uint64_t uptime_ms) {
|
||||
// Read data from the network
|
||||
size_t len = ifp->driver->rx((void *) ifp->rx.ptr, ifp->rx.len, ifp);
|
||||
if (len) {
|
||||
mip_rx(ifp, (void *) ifp->rx.ptr, len);
|
||||
mg_tcpip_rx(ifp, (void *) ifp->rx.ptr, len);
|
||||
}
|
||||
|
||||
// Process timeouts
|
||||
@ -7596,7 +7603,7 @@ static void mip_poll(struct mip_if *ifp, uint64_t uptime_ms) {
|
||||
// This function executes in interrupt context, thus it should copy data
|
||||
// somewhere fast. Note that newlib's malloc is not thread safe, thus use
|
||||
// our lock-free queue with preallocated buffer to copy data and return asap
|
||||
void mip_qwrite(void *buf, size_t len, struct mip_if *ifp) {
|
||||
void mg_tcpip_qwrite(void *buf, size_t len, struct mg_tcpip_if *ifp) {
|
||||
if (q_write(&ifp->queue, buf, len)) {
|
||||
ifp->nrecv++;
|
||||
} else {
|
||||
@ -7604,16 +7611,16 @@ void mip_qwrite(void *buf, size_t len, struct mip_if *ifp) {
|
||||
}
|
||||
}
|
||||
|
||||
size_t mip_qread(void *buf, struct mip_if *ifp) {
|
||||
size_t mg_tcpip_qread(void *buf, struct mg_tcpip_if *ifp) {
|
||||
return q_read(&ifp->queue, buf);
|
||||
}
|
||||
|
||||
size_t mip_driver_rx(void *buf, size_t len, struct mip_if *ifp) {
|
||||
return mip_qread((void *) ifp->rx.ptr, ifp);
|
||||
size_t mg_tcpip_driver_rx(void *buf, size_t len, struct mg_tcpip_if *ifp) {
|
||||
return mg_tcpip_qread((void *) ifp->rx.ptr, ifp);
|
||||
(void) len, (void) buf;
|
||||
}
|
||||
|
||||
void mip_init(struct mg_mgr *mgr, struct mip_if *ifp) {
|
||||
void mg_tcpip_init(struct mg_mgr *mgr, struct mg_tcpip_if *ifp) {
|
||||
// If MAC address is not set, make a random one
|
||||
if (ifp->mac[0] == 0 && ifp->mac[1] == 0 && ifp->mac[2] == 0 &&
|
||||
ifp->mac[3] == 0 && ifp->mac[4] == 0 && ifp->mac[5] == 0) {
|
||||
@ -7644,7 +7651,7 @@ void mip_init(struct mg_mgr *mgr, struct mip_if *ifp) {
|
||||
}
|
||||
}
|
||||
|
||||
void mip_free(struct mip_if *ifp) {
|
||||
void mg_tcpip_free(struct mg_tcpip_if *ifp) {
|
||||
free((char *) ifp->rx.ptr);
|
||||
free((char *) ifp->tx.ptr);
|
||||
}
|
||||
@ -7658,13 +7665,13 @@ int mg_mkpipe(struct mg_mgr *m, mg_event_handler_t fn, void *d, bool udp) {
|
||||
static void send_syn(struct mg_connection *c) {
|
||||
struct connstate *s = (struct connstate *) (c + 1);
|
||||
uint32_t isn = mg_htonl((uint32_t) mg_ntohs(c->loc.port));
|
||||
struct mip_if *ifp = (struct mip_if *) c->mgr->priv;
|
||||
struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
|
||||
tx_tcp(ifp, s->mac, c->rem.ip, TH_SYN, c->loc.port, c->rem.port, isn, 0, NULL,
|
||||
0);
|
||||
}
|
||||
|
||||
void mg_connect_resolved(struct mg_connection *c) {
|
||||
struct mip_if *ifp = (struct mip_if *) c->mgr->priv;
|
||||
struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
|
||||
c->is_resolving = 0;
|
||||
if (ifp->eport < MIP_EPHEMERAL_PORT) ifp->eport = MIP_EPHEMERAL_PORT;
|
||||
c->loc.ip = ifp->ip;
|
||||
@ -7706,8 +7713,9 @@ static void write_conn(struct mg_connection *c) {
|
||||
static void close_conn(struct mg_connection *c) {
|
||||
struct connstate *s = (struct connstate *) (c + 1);
|
||||
mg_iobuf_free(&s->raw); // For TLS connections, release raw data
|
||||
if (c->is_udp == false && c->is_listening == false) { // For TCP conns,
|
||||
struct mip_if *ifp = (struct mip_if *) c->mgr->priv; // send TCP FIN
|
||||
if (c->is_udp == false && c->is_listening == false) { // For TCP conns,
|
||||
struct mg_tcpip_if *ifp =
|
||||
(struct mg_tcpip_if *) c->mgr->priv; // send TCP FIN
|
||||
tx_tcp(ifp, s->mac, c->rem.ip, TH_FIN | TH_ACK, c->loc.port, c->rem.port,
|
||||
mg_htonl(s->seq), mg_htonl(s->ack), NULL, 0);
|
||||
}
|
||||
@ -7722,7 +7730,7 @@ static bool can_write(struct mg_connection *c) {
|
||||
void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
|
||||
struct mg_connection *c, *tmp;
|
||||
uint64_t now = mg_millis();
|
||||
mip_poll((struct mip_if *) mgr->priv, now);
|
||||
mg_tcpip_poll((struct mg_tcpip_if *) mgr->priv, now);
|
||||
mg_timer_poll(&mgr->timers, now);
|
||||
for (c = mgr->conns; c != NULL; c = tmp) {
|
||||
tmp = c->next;
|
||||
@ -7739,7 +7747,7 @@ void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
|
||||
}
|
||||
|
||||
bool mg_send(struct mg_connection *c, const void *buf, size_t len) {
|
||||
struct mip_if *ifp = (struct mip_if *) c->mgr->priv;
|
||||
struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
|
||||
bool res = false;
|
||||
if (ifp->ip == 0 || ifp->state != MIP_STATE_READY) {
|
||||
mg_error(c, "net down");
|
||||
@ -7752,4 +7760,4 @@ bool mg_send(struct mg_connection *c, const void *buf, size_t len) {
|
||||
}
|
||||
return res;
|
||||
}
|
||||
#endif // MG_ENABLE_MIP
|
||||
#endif // MG_ENABLE_TCPIP
|
||||
|
72
mongoose.h
72
mongoose.h
@ -593,8 +593,8 @@ struct timeval {
|
||||
#define MG_ENABLE_LOG 1
|
||||
#endif
|
||||
|
||||
#ifndef MG_ENABLE_MIP
|
||||
#define MG_ENABLE_MIP 0 // Mongoose built-in network stack
|
||||
#ifndef MG_ENABLE_TCPIP
|
||||
#define MG_ENABLE_TCPIP 0 // Mongoose built-in network stack
|
||||
#endif
|
||||
|
||||
#ifndef MG_ENABLE_LWIP
|
||||
@ -610,7 +610,7 @@ struct timeval {
|
||||
#endif
|
||||
|
||||
#ifndef MG_ENABLE_SOCKET
|
||||
#define MG_ENABLE_SOCKET !MG_ENABLE_MIP
|
||||
#define MG_ENABLE_SOCKET !MG_ENABLE_TCPIP
|
||||
#endif
|
||||
|
||||
#ifndef MG_ENABLE_POLL
|
||||
@ -1453,18 +1453,18 @@ void mg_rpc_list(struct mg_rpc_req *r);
|
||||
|
||||
|
||||
|
||||
struct mip_if; // MIP network interface
|
||||
struct mg_tcpip_if; // MIP network interface
|
||||
|
||||
struct mip_driver {
|
||||
bool (*init)(struct mip_if *); // Initialise driver
|
||||
size_t (*tx)(const void *, size_t, struct mip_if *); // Transmit frame
|
||||
size_t (*rx)(void *buf, size_t len, struct mip_if *); // Receive frame (poll)
|
||||
bool (*up)(struct mip_if *); // Up/down status
|
||||
struct mg_tcpip_driver {
|
||||
bool (*init)(struct mg_tcpip_if *); // Init driver
|
||||
size_t (*tx)(const void *, size_t, struct mg_tcpip_if *); // Transmit frame
|
||||
size_t (*rx)(void *buf, size_t len, struct mg_tcpip_if *); // Receive frame
|
||||
bool (*up)(struct mg_tcpip_if *); // Up/down status
|
||||
};
|
||||
|
||||
// Receive queue - single producer, single consumer queue. Interrupt-based
|
||||
// drivers copy received frames to the queue in interrupt context. mip_poll()
|
||||
// function runs in event loop context, reads from the queue
|
||||
// drivers copy received frames to the queue in interrupt context.
|
||||
// mg_tcpip_poll() function runs in event loop context, reads from the queue
|
||||
struct queue {
|
||||
uint8_t *buf;
|
||||
size_t len;
|
||||
@ -1472,17 +1472,17 @@ struct queue {
|
||||
};
|
||||
|
||||
// Network interface
|
||||
struct mip_if {
|
||||
uint8_t mac[6]; // MAC address. Must be set to a valid MAC
|
||||
uint32_t ip, mask, gw; // IP address, mask, default gateway
|
||||
struct mg_str rx; // Output (TX) buffer
|
||||
struct mg_str tx; // Input (RX) buffer
|
||||
bool enable_dhcp_client; // Enable DCHP client
|
||||
bool enable_dhcp_server; // Enable DCHP server
|
||||
struct mip_driver *driver; // Low level driver
|
||||
void *driver_data; // Driver-specific data
|
||||
struct mg_mgr *mgr; // Mongoose event manager
|
||||
struct queue queue; // Set queue.len for interrupt based drivers
|
||||
struct mg_tcpip_if {
|
||||
uint8_t mac[6]; // MAC address. Must be set to a valid MAC
|
||||
uint32_t ip, mask, gw; // IP address, mask, default gateway
|
||||
struct mg_str rx; // Output (TX) buffer
|
||||
struct mg_str tx; // Input (RX) buffer
|
||||
bool enable_dhcp_client; // Enable DCHP client
|
||||
bool enable_dhcp_server; // Enable DCHP server
|
||||
struct mg_tcpip_driver *driver; // Low level driver
|
||||
void *driver_data; // Driver-specific data
|
||||
struct mg_mgr *mgr; // Mongoose event manager
|
||||
struct queue queue; // Set queue.len for interrupt based drivers
|
||||
|
||||
// Internal state, user can use it but should not change it
|
||||
uint8_t gwmac[6]; // Router's MAC
|
||||
@ -1500,27 +1500,27 @@ struct mip_if {
|
||||
#define MIP_STATE_READY 2 // Interface is up and has IP
|
||||
};
|
||||
|
||||
void mip_init(struct mg_mgr *, struct mip_if *);
|
||||
void mip_free(struct mip_if *);
|
||||
void mip_qwrite(void *buf, size_t len, struct mip_if *ifp);
|
||||
size_t mip_qread(void *buf, struct mip_if *ifp);
|
||||
void mg_tcpip_init(struct mg_mgr *, struct mg_tcpip_if *);
|
||||
void mg_tcpip_free(struct mg_tcpip_if *);
|
||||
void mg_tcpip_qwrite(void *buf, size_t len, struct mg_tcpip_if *ifp);
|
||||
size_t mg_tcpip_qread(void *buf, struct mg_tcpip_if *ifp);
|
||||
// conveniency rx function for IRQ-driven drivers
|
||||
size_t mip_driver_rx(void *buf, size_t len, struct mip_if *ifp);
|
||||
size_t mg_tcpip_driver_rx(void *buf, size_t len, struct mg_tcpip_if *ifp);
|
||||
|
||||
extern struct mip_driver mip_driver_stm32;
|
||||
extern struct mip_driver mip_driver_w5500;
|
||||
extern struct mip_driver mip_driver_tm4c;
|
||||
extern struct mip_driver mip_driver_stm32h;
|
||||
extern struct mg_tcpip_driver mg_tcpip_driver_stm32;
|
||||
extern struct mg_tcpip_driver mg_tcpip_driver_w5500;
|
||||
extern struct mg_tcpip_driver mg_tcpip_driver_tm4c;
|
||||
extern struct mg_tcpip_driver mg_tcpip_driver_stm32h;
|
||||
|
||||
// Drivers that require SPI, can use this SPI abstraction
|
||||
struct mip_spi {
|
||||
struct mg_tcpip_spi {
|
||||
void *spi; // Opaque SPI bus descriptor
|
||||
void (*begin)(void *); // SPI begin: slave select low
|
||||
void (*end)(void *); // SPI end: slave select high
|
||||
uint8_t (*txn)(void *, uint8_t); // SPI transaction: write 1 byte, read reply
|
||||
};
|
||||
|
||||
#if MG_ENABLE_MIP
|
||||
#if MG_ENABLE_TCPIP
|
||||
#if !defined(MG_ENABLE_DRIVER_STM32H) && !defined(MG_ENABLE_DRIVER_TM4C)
|
||||
#define MG_ENABLE_DRIVER_STM32 1
|
||||
#else
|
||||
@ -1529,7 +1529,7 @@ struct mip_spi {
|
||||
#endif
|
||||
|
||||
|
||||
struct mip_driver_stm32_data {
|
||||
struct mg_tcpip_driver_stm32_data {
|
||||
// MDC clock divider. MDC clock is derived from HCLK, must not exceed 2.5MHz
|
||||
// HCLK range DIVIDER mdc_cr VALUE
|
||||
// -------------------------------------
|
||||
@ -1545,7 +1545,7 @@ struct mip_driver_stm32_data {
|
||||
};
|
||||
|
||||
|
||||
struct mip_driver_stm32h_data {
|
||||
struct mg_tcpip_driver_stm32h_data {
|
||||
// MDC clock divider. MDC clock is derived from HCLK, must not exceed 2.5MHz
|
||||
// HCLK range DIVIDER mdc_cr VALUE
|
||||
// -------------------------------------
|
||||
@ -1561,7 +1561,7 @@ struct mip_driver_stm32h_data {
|
||||
};
|
||||
|
||||
|
||||
struct mip_driver_tm4c_data {
|
||||
struct mg_tcpip_driver_tm4c_data {
|
||||
// MDC clock divider. MDC clock is derived from SYSCLK, must not exceed 2.5MHz
|
||||
// SYSCLK range DIVIDER mdc_cr VALUE
|
||||
// -------------------------------------
|
||||
|
@ -4,8 +4,8 @@
|
||||
#define MG_ENABLE_LOG 1
|
||||
#endif
|
||||
|
||||
#ifndef MG_ENABLE_MIP
|
||||
#define MG_ENABLE_MIP 0 // Mongoose built-in network stack
|
||||
#ifndef MG_ENABLE_TCPIP
|
||||
#define MG_ENABLE_TCPIP 0 // Mongoose built-in network stack
|
||||
#endif
|
||||
|
||||
#ifndef MG_ENABLE_LWIP
|
||||
@ -21,7 +21,7 @@
|
||||
#endif
|
||||
|
||||
#ifndef MG_ENABLE_SOCKET
|
||||
#define MG_ENABLE_SOCKET !MG_ENABLE_MIP
|
||||
#define MG_ENABLE_SOCKET !MG_ENABLE_TCPIP
|
||||
#endif
|
||||
|
||||
#ifndef MG_ENABLE_POLL
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "mip.h"
|
||||
|
||||
#if MG_ENABLE_MIP && MG_ENABLE_DRIVER_STM32
|
||||
#if MG_ENABLE_TCPIP && MG_ENABLE_DRIVER_STM32
|
||||
struct stm32_eth {
|
||||
volatile uint32_t MACCR, MACFFR, MACHTHR, MACHTLR, MACMIIAR, MACMIIDR, MACFCR,
|
||||
MACVLANTR, RESERVED0[2], MACRWUFFR, MACPMTCSR, RESERVED1, MACDBGR, MACSR,
|
||||
@ -27,10 +27,10 @@ static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS]; // RX descriptors
|
||||
static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]; // TX descriptors
|
||||
static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // RX ethernet buffers
|
||||
static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // TX ethernet buffers
|
||||
static uint8_t s_txno; // Current TX descriptor
|
||||
static uint8_t s_rxno; // Current RX descriptor
|
||||
static uint8_t s_txno; // Current TX descriptor
|
||||
static uint8_t s_rxno; // Current RX descriptor
|
||||
|
||||
static struct mip_if *s_ifp; // MIP interface
|
||||
static struct mg_tcpip_if *s_ifp; // MIP interface
|
||||
enum { PHY_ADDR = 0, PHY_BCR = 0, PHY_BSR = 1, PHY_CSCR = 31 };
|
||||
|
||||
static uint32_t eth_read_phy(uint8_t addr, uint8_t reg) {
|
||||
@ -103,9 +103,9 @@ static int guess_mdc_cr(void) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool mip_driver_stm32_init(struct mip_if *ifp) {
|
||||
struct mip_driver_stm32_data *d =
|
||||
(struct mip_driver_stm32_data *) ifp->driver_data;
|
||||
static bool mg_tcpip_driver_stm32_init(struct mg_tcpip_if *ifp) {
|
||||
struct mg_tcpip_driver_stm32_data *d =
|
||||
(struct mg_tcpip_driver_stm32_data *) ifp->driver_data;
|
||||
s_ifp = ifp;
|
||||
|
||||
// Init RX descriptors
|
||||
@ -154,8 +154,8 @@ static bool mip_driver_stm32_init(struct mip_if *ifp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static size_t mip_driver_stm32_tx(const void *buf, size_t len,
|
||||
struct mip_if *ifp) {
|
||||
static size_t mg_tcpip_driver_stm32_tx(const void *buf, size_t len,
|
||||
struct mg_tcpip_if *ifp) {
|
||||
if (len > sizeof(s_txbuf[s_txno])) {
|
||||
MG_ERROR(("Frame too big, %ld", (long) len));
|
||||
len = 0; // Frame is too big
|
||||
@ -176,7 +176,7 @@ static size_t mip_driver_stm32_tx(const void *buf, size_t len,
|
||||
return len;
|
||||
}
|
||||
|
||||
static bool mip_driver_stm32_up(struct mip_if *ifp) {
|
||||
static bool mg_tcpip_driver_stm32_up(struct mg_tcpip_if *ifp) {
|
||||
uint32_t bsr = eth_read_phy(PHY_ADDR, PHY_BSR);
|
||||
bool up = bsr & BIT(2) ? 1 : 0;
|
||||
if ((ifp->state == MIP_STATE_DOWN) && up) { // link state just went up
|
||||
@ -202,7 +202,7 @@ void ETH_IRQHandler(void) {
|
||||
uint32_t len = ((s_rxdesc[s_rxno][0] >> 16) & (BIT(14) - 1));
|
||||
// printf("%lx %lu %lx %.8lx\n", s_rxno, len, s_rxdesc[s_rxno][0],
|
||||
// ETH->DMASR);
|
||||
mip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
|
||||
mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
|
||||
}
|
||||
s_rxdesc[s_rxno][0] = BIT(31);
|
||||
if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
|
||||
@ -212,7 +212,7 @@ void ETH_IRQHandler(void) {
|
||||
ETH->DMARPDR = 0; // and resume RX
|
||||
}
|
||||
|
||||
struct mip_driver mip_driver_stm32 = {mip_driver_stm32_init,
|
||||
mip_driver_stm32_tx, mip_driver_rx,
|
||||
mip_driver_stm32_up};
|
||||
struct mg_tcpip_driver mg_tcpip_driver_stm32 = {
|
||||
mg_tcpip_driver_stm32_init, mg_tcpip_driver_stm32_tx, mg_tcpip_driver_rx,
|
||||
mg_tcpip_driver_stm32_up};
|
||||
#endif
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
struct mip_driver_stm32_data {
|
||||
struct mg_tcpip_driver_stm32_data {
|
||||
// MDC clock divider. MDC clock is derived from HCLK, must not exceed 2.5MHz
|
||||
// HCLK range DIVIDER mdc_cr VALUE
|
||||
// -------------------------------------
|
@ -1,6 +1,7 @@
|
||||
#include "mip.h"
|
||||
|
||||
#if MG_ENABLE_MIP && defined(MG_ENABLE_DRIVER_STM32H) && MG_ENABLE_DRIVER_STM32H
|
||||
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_STM32H) && \
|
||||
MG_ENABLE_DRIVER_STM32H
|
||||
struct stm32h_eth {
|
||||
volatile uint32_t MACCR, MACECR, MACPFR, MACWTR, MACHT0R, MACHT1R,
|
||||
RESERVED1[14], MACVTR, RESERVED2, MACVHTR, RESERVED3, MACVIR, MACIVIR,
|
||||
@ -45,7 +46,7 @@ static volatile uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS]; // RX descriptors
|
||||
static volatile uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]; // TX descriptors
|
||||
static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // RX ethernet buffers
|
||||
static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // TX ethernet buffers
|
||||
static struct mip_if *s_ifp; // MIP interface
|
||||
static struct mg_tcpip_if *s_ifp; // MIP interface
|
||||
enum {
|
||||
PHY_ADDR = 0,
|
||||
PHY_BCR = 0,
|
||||
@ -145,9 +146,9 @@ static int guess_mdc_cr(void) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool mip_driver_stm32h_init(struct mip_if *ifp) {
|
||||
struct mip_driver_stm32h_data *d =
|
||||
(struct mip_driver_stm32h_data *) ifp->driver_data;
|
||||
static bool mg_tcpip_driver_stm32h_init(struct mg_tcpip_if *ifp) {
|
||||
struct mg_tcpip_driver_stm32h_data *d =
|
||||
(struct mg_tcpip_driver_stm32h_data *) ifp->driver_data;
|
||||
s_ifp = ifp;
|
||||
|
||||
// Init RX descriptors
|
||||
@ -207,8 +208,8 @@ static bool mip_driver_stm32h_init(struct mip_if *ifp) {
|
||||
}
|
||||
|
||||
static uint32_t s_txno;
|
||||
static size_t mip_driver_stm32h_tx(const void *buf, size_t len,
|
||||
struct mip_if *ifp) {
|
||||
static size_t mg_tcpip_driver_stm32h_tx(const void *buf, size_t len,
|
||||
struct mg_tcpip_if *ifp) {
|
||||
if (len > sizeof(s_txbuf[s_txno])) {
|
||||
MG_ERROR(("Frame too big, %ld", (long) len));
|
||||
len = 0; // Frame is too big
|
||||
@ -230,7 +231,7 @@ static size_t mip_driver_stm32h_tx(const void *buf, size_t len,
|
||||
(void) ifp;
|
||||
}
|
||||
|
||||
static bool mip_driver_stm32h_up(struct mip_if *ifp) {
|
||||
static bool mg_tcpip_driver_stm32h_up(struct mg_tcpip_if *ifp) {
|
||||
uint32_t bsr = eth_read_phy(PHY_ADDR, PHY_BSR);
|
||||
bool up = bsr & BIT(2) ? 1 : 0;
|
||||
if ((ifp->state == MIP_STATE_DOWN) && up) { // link state just went up
|
||||
@ -258,7 +259,7 @@ void ETH_IRQHandler(void) {
|
||||
uint32_t len = s_rxdesc[s_rxno][3] & (BIT(15) - 1);
|
||||
// MG_DEBUG(("%lx %lu %lx %08lx", s_rxno, len, s_rxdesc[s_rxno][3],
|
||||
// ETH->DMACSR));
|
||||
mip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
|
||||
mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
|
||||
}
|
||||
s_rxdesc[s_rxno][3] = BIT(31) | BIT(30) | BIT(24); // OWN, IOC, BUF1V
|
||||
if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
|
||||
@ -269,7 +270,7 @@ void ETH_IRQHandler(void) {
|
||||
(uint32_t) (uintptr_t) &s_rxdesc[ETH_DESC_CNT - 1]; // and resume RX
|
||||
}
|
||||
|
||||
struct mip_driver mip_driver_stm32h = {mip_driver_stm32h_init,
|
||||
mip_driver_stm32h_tx, mip_driver_rx,
|
||||
mip_driver_stm32h_up};
|
||||
struct mg_tcpip_driver mg_tcpip_driver_stm32h = {
|
||||
mg_tcpip_driver_stm32h_init, mg_tcpip_driver_stm32h_tx, mg_tcpip_driver_rx,
|
||||
mg_tcpip_driver_stm32h_up};
|
||||
#endif
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
struct mip_driver_stm32h_data {
|
||||
struct mg_tcpip_driver_stm32h_data {
|
||||
// MDC clock divider. MDC clock is derived from HCLK, must not exceed 2.5MHz
|
||||
// HCLK range DIVIDER mdc_cr VALUE
|
||||
// -------------------------------------
|
@ -1,6 +1,6 @@
|
||||
#include "mip.h"
|
||||
|
||||
#if MG_ENABLE_MIP && defined(MG_ENABLE_DRIVER_TM4C) && MG_ENABLE_DRIVER_TM4C
|
||||
#if MG_ENABLE_TCPIP && defined(MG_ENABLE_DRIVER_TM4C) && MG_ENABLE_DRIVER_TM4C
|
||||
struct tm4c_emac {
|
||||
volatile uint32_t EMACCFG, EMACFRAMEFLTR, EMACHASHTBLH, EMACHASHTBLL,
|
||||
EMACMIIADDR, EMACMIIDATA, EMACFLOWCTL, EMACVLANTG, RESERVED0, EMACSTATUS,
|
||||
@ -34,7 +34,7 @@ static uint32_t s_rxdesc[ETH_DESC_CNT][ETH_DS]; // RX descriptors
|
||||
static uint32_t s_txdesc[ETH_DESC_CNT][ETH_DS]; // TX descriptors
|
||||
static uint8_t s_rxbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // RX ethernet buffers
|
||||
static uint8_t s_txbuf[ETH_DESC_CNT][ETH_PKT_SIZE]; // TX ethernet buffers
|
||||
static struct mip_if *s_ifp; // MIP interface
|
||||
static struct mg_tcpip_if *s_ifp; // MIP interface
|
||||
enum {
|
||||
EPHY_ADDR = 0,
|
||||
EPHYBMCR = 0,
|
||||
@ -128,9 +128,9 @@ static int guess_mdc_cr(void) {
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool mip_driver_tm4c_init(struct mip_if *ifp) {
|
||||
struct mip_driver_tm4c_data *d =
|
||||
(struct mip_driver_tm4c_data *) ifp->driver_data;
|
||||
static bool mg_tcpip_driver_tm4c_init(struct mg_tcpip_if *ifp) {
|
||||
struct mg_tcpip_driver_tm4c_data *d =
|
||||
(struct mg_tcpip_driver_tm4c_data *) ifp->driver_data;
|
||||
s_ifp = ifp;
|
||||
|
||||
// Init RX descriptors
|
||||
@ -184,8 +184,8 @@ static bool mip_driver_tm4c_init(struct mip_if *ifp) {
|
||||
}
|
||||
|
||||
static uint32_t s_txno;
|
||||
static size_t mip_driver_tm4c_tx(const void *buf, size_t len,
|
||||
struct mip_if *ifp) {
|
||||
static size_t mg_tcpip_driver_tm4c_tx(const void *buf, size_t len,
|
||||
struct mg_tcpip_if *ifp) {
|
||||
if (len > sizeof(s_txbuf[s_txno])) {
|
||||
MG_ERROR(("Frame too big, %ld", (long) len));
|
||||
len = 0; // fail
|
||||
@ -208,7 +208,7 @@ static size_t mip_driver_tm4c_tx(const void *buf, size_t len,
|
||||
(void) ifp;
|
||||
}
|
||||
|
||||
static bool mip_driver_tm4c_up(struct mip_if *ifp) {
|
||||
static bool mg_tcpip_driver_tm4c_up(struct mg_tcpip_if *ifp) {
|
||||
uint32_t bmsr = emac_read_phy(EPHY_ADDR, EPHYBMSR);
|
||||
bool up = (bmsr & BIT(2)) ? 1 : 0;
|
||||
if ((ifp->state == MIP_STATE_DOWN) && up) { // link state just went up
|
||||
@ -235,7 +235,7 @@ void EMAC0_IRQHandler(void) {
|
||||
uint32_t len = ((s_rxdesc[s_rxno][0] >> 16) & (BIT(14) - 1));
|
||||
// printf("%lx %lu %lx %.8lx\n", s_rxno, len, s_rxdesc[s_rxno][0],
|
||||
// EMAC->EMACDMARIS);
|
||||
mip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
|
||||
mg_tcpip_qwrite(s_rxbuf[s_rxno], len > 4 ? len - 4 : len, s_ifp);
|
||||
}
|
||||
s_rxdesc[s_rxno][0] = BIT(31);
|
||||
if (++s_rxno >= ETH_DESC_CNT) s_rxno = 0;
|
||||
@ -245,6 +245,7 @@ void EMAC0_IRQHandler(void) {
|
||||
EMAC->EMACRXPOLLD = 0; // and resume RX
|
||||
}
|
||||
|
||||
struct mip_driver mip_driver_tm4c = {mip_driver_tm4c_init, mip_driver_tm4c_tx,
|
||||
mip_driver_rx, mip_driver_tm4c_up};
|
||||
struct mg_tcpip_driver mg_tcpip_driver_tm4c = {
|
||||
mg_tcpip_driver_tm4c_init, mg_tcpip_driver_tm4c_tx, mg_tcpip_driver_rx,
|
||||
mg_tcpip_driver_tm4c_up};
|
||||
#endif
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
struct mip_driver_tm4c_data {
|
||||
struct mg_tcpip_driver_tm4c_data {
|
||||
// MDC clock divider. MDC clock is derived from SYSCLK, must not exceed 2.5MHz
|
||||
// SYSCLK range DIVIDER mdc_cr VALUE
|
||||
// -------------------------------------
|
@ -1,10 +1,10 @@
|
||||
#include "mip.h"
|
||||
|
||||
#if MG_ENABLE_MIP
|
||||
#if MG_ENABLE_TCPIP
|
||||
|
||||
enum { W5500_CR = 0, W5500_S0 = 1, W5500_TX0 = 2, W5500_RX0 = 3 };
|
||||
|
||||
static void w5500_txn(struct mip_spi *s, uint8_t block, uint16_t addr, bool wr,
|
||||
static void w5500_txn(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, bool wr,
|
||||
void *buf, size_t len) {
|
||||
uint8_t *p = (uint8_t *) buf;
|
||||
uint8_t cmd[] = {(uint8_t) (addr >> 8), (uint8_t) (addr & 255),
|
||||
@ -19,16 +19,16 @@ static void w5500_txn(struct mip_spi *s, uint8_t block, uint16_t addr, bool wr,
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
static void w5500_wn(struct mip_spi *s, uint8_t block, uint16_t addr, void *buf, size_t len) { w5500_txn(s, block, addr, true, buf, len); }
|
||||
static void w5500_w1(struct mip_spi *s, uint8_t block, uint16_t addr, uint8_t val) { w5500_wn(s, block, addr, &val, 1); }
|
||||
static void w5500_w2(struct mip_spi *s, uint8_t block, uint16_t addr, uint16_t val) { uint8_t buf[2] = {(uint8_t) (val >> 8), (uint8_t) (val & 255)}; w5500_wn(s, block, addr, buf, sizeof(buf)); }
|
||||
static void w5500_rn(struct mip_spi *s, uint8_t block, uint16_t addr, void *buf, size_t len) { w5500_txn(s, block, addr, false, buf, len); }
|
||||
static uint8_t w5500_r1(struct mip_spi *s, uint8_t block, uint16_t addr) { uint8_t r = 0; w5500_rn(s, block, addr, &r, 1); return r; }
|
||||
static uint16_t w5500_r2(struct mip_spi *s, uint8_t block, uint16_t addr) { uint8_t buf[2] = {0, 0}; w5500_rn(s, block, addr, buf, sizeof(buf)); return (uint16_t) ((buf[0] << 8) | buf[1]); }
|
||||
static void w5500_wn(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, void *buf, size_t len) { w5500_txn(s, block, addr, true, buf, len); }
|
||||
static void w5500_w1(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, uint8_t val) { w5500_wn(s, block, addr, &val, 1); }
|
||||
static void w5500_w2(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, uint16_t val) { uint8_t buf[2] = {(uint8_t) (val >> 8), (uint8_t) (val & 255)}; w5500_wn(s, block, addr, buf, sizeof(buf)); }
|
||||
static void w5500_rn(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr, void *buf, size_t len) { w5500_txn(s, block, addr, false, buf, len); }
|
||||
static uint8_t w5500_r1(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr) { uint8_t r = 0; w5500_rn(s, block, addr, &r, 1); return r; }
|
||||
static uint16_t w5500_r2(struct mg_tcpip_spi *s, uint8_t block, uint16_t addr) { uint8_t buf[2] = {0, 0}; w5500_rn(s, block, addr, buf, sizeof(buf)); return (uint16_t) ((buf[0] << 8) | buf[1]); }
|
||||
// clang-format on
|
||||
|
||||
static size_t w5500_rx(void *buf, size_t buflen, struct mip_if *ifp) {
|
||||
struct mip_spi *s = (struct mip_spi *) ifp->driver_data;
|
||||
static size_t w5500_rx(void *buf, size_t buflen, struct mg_tcpip_if *ifp) {
|
||||
struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
|
||||
uint16_t r = 0, n = 0, len = (uint16_t) buflen, n2; // Read recv len
|
||||
while ((n2 = w5500_r2(s, W5500_S0, 0x26)) > n) n = n2; // Until it is stable
|
||||
// printf("RSR: %d\n", (int) n);
|
||||
@ -46,8 +46,8 @@ static size_t w5500_rx(void *buf, size_t buflen, struct mip_if *ifp) {
|
||||
return r;
|
||||
}
|
||||
|
||||
static size_t w5500_tx(const void *buf, size_t buflen, struct mip_if *ifp) {
|
||||
struct mip_spi *s = (struct mip_spi *) ifp->driver_data;
|
||||
static size_t w5500_tx(const void *buf, size_t buflen, struct mg_tcpip_if *ifp) {
|
||||
struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
|
||||
uint16_t n = 0, len = (uint16_t) buflen;
|
||||
while (n < len) n = w5500_r2(s, W5500_S0, 0x20); // Wait for space
|
||||
uint16_t ptr = w5500_r2(s, W5500_S0, 0x24); // Get write pointer
|
||||
@ -65,8 +65,8 @@ static size_t w5500_tx(const void *buf, size_t buflen, struct mip_if *ifp) {
|
||||
return len;
|
||||
}
|
||||
|
||||
static bool w5500_init(struct mip_if *ifp) {
|
||||
struct mip_spi *s = (struct mip_spi *) ifp->driver_data;
|
||||
static bool w5500_init(struct mg_tcpip_if *ifp) {
|
||||
struct mg_tcpip_spi *s = (struct mg_tcpip_spi *) ifp->driver_data;
|
||||
s->end(s->spi);
|
||||
w5500_w1(s, W5500_CR, 0, 0x80); // Reset chip: CR -> 0x80
|
||||
w5500_w1(s, W5500_CR, 0x2e, 0); // CR PHYCFGR -> reset
|
||||
@ -79,11 +79,11 @@ static bool w5500_init(struct mip_if *ifp) {
|
||||
return w5500_r1(s, W5500_S0, 3) == 0x42; // Sock0 SR == MACRAW
|
||||
}
|
||||
|
||||
static bool w5500_up(struct mip_if *ifp) {
|
||||
struct mip_spi *spi = (struct mip_spi *) ifp->driver_data;
|
||||
static bool w5500_up(struct mg_tcpip_if *ifp) {
|
||||
struct mg_tcpip_spi *spi = (struct mg_tcpip_spi *) ifp->driver_data;
|
||||
uint8_t phycfgr = w5500_r1(spi, W5500_CR, 0x2e);
|
||||
return phycfgr & 1; // Bit 0 of PHYCFGR is LNK (0 - down, 1 - up)
|
||||
}
|
||||
|
||||
struct mip_driver mip_driver_w5500 = {w5500_init, w5500_tx, w5500_rx, w5500_up};
|
||||
struct mg_tcpip_driver mg_tcpip_driver_w5500 = {w5500_init, w5500_tx, w5500_rx, w5500_up};
|
||||
#endif
|
@ -1,6 +1,6 @@
|
||||
#include "mip.h"
|
||||
#include "tcpip.h"
|
||||
|
||||
#if MG_ENABLE_MIP
|
||||
#if MG_ENABLE_TCPIP
|
||||
|
||||
#define MIP_EPHEMERAL_PORT 49152
|
||||
#define PDIFF(a, b) ((size_t) (((char *) (b)) - ((char *) (a))))
|
||||
@ -193,7 +193,7 @@ static uint16_t ipcsum(const void *buf, size_t len) {
|
||||
return csumfin(sum);
|
||||
}
|
||||
|
||||
static size_t ether_output(struct mip_if *ifp, size_t len) {
|
||||
static size_t ether_output(struct mg_tcpip_if *ifp, size_t len) {
|
||||
// size_t min = 64; // Pad short frames to 64 bytes (minimum Ethernet size)
|
||||
// if (len < min) memset(ifp->tx.ptr + len, 0, min - len), len = min;
|
||||
// mg_hexdump(ifp->tx.ptr, len);
|
||||
@ -202,7 +202,7 @@ static size_t ether_output(struct mip_if *ifp, size_t len) {
|
||||
return n;
|
||||
}
|
||||
|
||||
static void arp_ask(struct mip_if *ifp, uint32_t ip) {
|
||||
static void arp_ask(struct mg_tcpip_if *ifp, uint32_t ip) {
|
||||
struct eth *eth = (struct eth *) ifp->tx.ptr;
|
||||
struct arp *arp = (struct arp *) (eth + 1);
|
||||
memset(eth->dst, 255, sizeof(eth->dst));
|
||||
@ -216,7 +216,7 @@ static void arp_ask(struct mip_if *ifp, uint32_t ip) {
|
||||
ether_output(ifp, PDIFF(eth, arp + 1));
|
||||
}
|
||||
|
||||
static void onstatechange(struct mip_if *ifp) {
|
||||
static void onstatechange(struct mg_tcpip_if *ifp) {
|
||||
if (ifp->state == MIP_STATE_READY) {
|
||||
MG_INFO(("READY, IP: %M", mg_print_ip4, &ifp->ip));
|
||||
MG_INFO((" GW: %M", mg_print_ip4, &ifp->gw));
|
||||
@ -232,8 +232,9 @@ static void onstatechange(struct mip_if *ifp) {
|
||||
}
|
||||
}
|
||||
|
||||
static struct ip *tx_ip(struct mip_if *ifp, uint8_t *mac_dst, uint8_t proto,
|
||||
uint32_t ip_src, uint32_t ip_dst, size_t plen) {
|
||||
static struct ip *tx_ip(struct mg_tcpip_if *ifp, uint8_t *mac_dst,
|
||||
uint8_t proto, uint32_t ip_src, uint32_t ip_dst,
|
||||
size_t plen) {
|
||||
struct eth *eth = (struct eth *) ifp->tx.ptr;
|
||||
struct ip *ip = (struct ip *) (eth + 1);
|
||||
memcpy(eth->dst, mac_dst, sizeof(eth->dst));
|
||||
@ -251,7 +252,7 @@ static struct ip *tx_ip(struct mip_if *ifp, uint8_t *mac_dst, uint8_t proto,
|
||||
return ip;
|
||||
}
|
||||
|
||||
static void tx_udp(struct mip_if *ifp, uint8_t *mac_dst, uint32_t ip_src,
|
||||
static void tx_udp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src,
|
||||
uint16_t sport, uint32_t ip_dst, uint16_t dport,
|
||||
const void *buf, size_t len) {
|
||||
struct ip *ip =
|
||||
@ -273,7 +274,7 @@ static void tx_udp(struct mip_if *ifp, uint8_t *mac_dst, uint32_t ip_src,
|
||||
ether_output(ifp, sizeof(struct eth) + sizeof(*ip) + sizeof(*udp) + len);
|
||||
}
|
||||
|
||||
static void tx_dhcp(struct mip_if *ifp, uint8_t *mac_dst, uint32_t ip_src,
|
||||
static void tx_dhcp(struct mg_tcpip_if *ifp, uint8_t *mac_dst, uint32_t ip_src,
|
||||
uint32_t ip_dst, uint8_t *opts, size_t optslen) {
|
||||
struct dhcp dhcp = {1, 1, 6, 0, 0, 0, 0, 0, 0, 0, 0, {0}, 0, {0}};
|
||||
dhcp.magic = mg_htonl(0x63825363);
|
||||
@ -284,7 +285,7 @@ static void tx_dhcp(struct mip_if *ifp, uint8_t *mac_dst, uint32_t ip_src,
|
||||
sizeof(dhcp));
|
||||
}
|
||||
|
||||
static void tx_dhcp_request(struct mip_if *ifp, uint8_t *mac_dst,
|
||||
static void tx_dhcp_request(struct mg_tcpip_if *ifp, uint8_t *mac_dst,
|
||||
uint32_t ip_src, uint32_t ip_dst) {
|
||||
uint8_t opts[] = {
|
||||
53, 1, 3, // Type: DHCP request
|
||||
@ -299,7 +300,7 @@ static void tx_dhcp_request(struct mip_if *ifp, uint8_t *mac_dst,
|
||||
tx_dhcp(ifp, mac_dst, ip_src, ip_dst, opts, sizeof(opts));
|
||||
}
|
||||
|
||||
static void tx_dhcp_discover(struct mip_if *ifp) {
|
||||
static void tx_dhcp_discover(struct mg_tcpip_if *ifp) {
|
||||
uint8_t mac[6] = {255, 255, 255, 255, 255, 255};
|
||||
uint8_t opts[] = {
|
||||
53, 1, 1, // Type: DHCP discover
|
||||
@ -322,7 +323,7 @@ static struct mg_connection *getpeer(struct mg_mgr *mgr, struct pkt *pkt,
|
||||
return c;
|
||||
}
|
||||
|
||||
static void rx_arp(struct mip_if *ifp, struct pkt *pkt) {
|
||||
static void rx_arp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
if (pkt->arp->op == mg_htons(1) && pkt->arp->tpa == ifp->ip) {
|
||||
// ARP request. Make a response, then send
|
||||
// MG_DEBUG(("ARP op %d %M: %M", mg_ntohs(pkt->arp->op), mg_print_ip4,
|
||||
@ -359,7 +360,7 @@ static void rx_arp(struct mip_if *ifp, struct pkt *pkt) {
|
||||
}
|
||||
}
|
||||
|
||||
static void rx_icmp(struct mip_if *ifp, struct pkt *pkt) {
|
||||
static void rx_icmp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
// MG_DEBUG(("ICMP %d", (int) len));
|
||||
if (pkt->icmp->type == 8 && pkt->ip != NULL && pkt->ip->dst == ifp->ip) {
|
||||
size_t hlen = sizeof(struct eth) + sizeof(struct ip) + sizeof(struct icmp);
|
||||
@ -375,7 +376,7 @@ static void rx_icmp(struct mip_if *ifp, struct pkt *pkt) {
|
||||
}
|
||||
}
|
||||
|
||||
static void rx_dhcp_client(struct mip_if *ifp, struct pkt *pkt) {
|
||||
static void rx_dhcp_client(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
uint32_t ip = 0, gw = 0, mask = 0;
|
||||
uint8_t *p = pkt->dhcp->options,
|
||||
*end = (uint8_t *) &pkt->raw.ptr[pkt->raw.len];
|
||||
@ -403,7 +404,7 @@ static void rx_dhcp_client(struct mip_if *ifp, struct pkt *pkt) {
|
||||
}
|
||||
|
||||
// Simple DHCP server that assigns a next IP address: ifp->ip + 1
|
||||
static void rx_dhcp_server(struct mip_if *ifp, struct pkt *pkt) {
|
||||
static void rx_dhcp_server(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
uint8_t op = 0, *p = pkt->dhcp->options,
|
||||
*end = (uint8_t *) &pkt->raw.ptr[pkt->raw.len];
|
||||
if (end < (uint8_t *) (pkt->dhcp + 1)) return;
|
||||
@ -439,7 +440,7 @@ static void rx_dhcp_server(struct mip_if *ifp, struct pkt *pkt) {
|
||||
}
|
||||
}
|
||||
|
||||
static void rx_udp(struct mip_if *ifp, struct pkt *pkt) {
|
||||
static void rx_udp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
struct mg_connection *c = getpeer(ifp->mgr, pkt, true);
|
||||
if (c == NULL) {
|
||||
// No UDP listener on this port. Should send ICMP, but keep silent.
|
||||
@ -459,7 +460,7 @@ static void rx_udp(struct mip_if *ifp, struct pkt *pkt) {
|
||||
}
|
||||
}
|
||||
|
||||
static size_t tx_tcp(struct mip_if *ifp, uint8_t *dst_mac, uint32_t dst_ip,
|
||||
static size_t tx_tcp(struct mg_tcpip_if *ifp, uint8_t *dst_mac, uint32_t dst_ip,
|
||||
uint8_t flags, uint16_t sport, uint16_t dport,
|
||||
uint32_t seq, uint32_t ack, const void *buf, size_t len) {
|
||||
struct ip *ip =
|
||||
@ -485,8 +486,9 @@ static size_t tx_tcp(struct mip_if *ifp, uint8_t *dst_mac, uint32_t dst_ip,
|
||||
return ether_output(ifp, PDIFF(ifp->tx.ptr, tcp + 1) + len);
|
||||
}
|
||||
|
||||
static size_t tx_tcp_pkt(struct mip_if *ifp, struct pkt *pkt, uint8_t flags,
|
||||
uint32_t seq, const void *buf, size_t len) {
|
||||
static size_t tx_tcp_pkt(struct mg_tcpip_if *ifp, struct pkt *pkt,
|
||||
uint8_t flags, uint32_t seq, const void *buf,
|
||||
size_t len) {
|
||||
uint32_t delta = (pkt->tcp->flags & (TH_SYN | TH_FIN)) ? 1 : 0;
|
||||
return tx_tcp(ifp, pkt->eth->src, pkt->ip->src, flags, pkt->tcp->dport,
|
||||
pkt->tcp->sport, seq, mg_htonl(mg_ntohl(pkt->tcp->seq) + delta),
|
||||
@ -494,7 +496,7 @@ static size_t tx_tcp_pkt(struct mip_if *ifp, struct pkt *pkt, uint8_t flags,
|
||||
}
|
||||
|
||||
static void settmout(struct mg_connection *c, uint8_t type) {
|
||||
struct mip_if *ifp = (struct mip_if *) c->mgr->priv;
|
||||
struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
|
||||
struct connstate *s = (struct connstate *) (c + 1);
|
||||
unsigned n = type == MIP_TTYPE_ACK ? MIP_TCP_ACK_MS : MIP_TCP_KEEPALIVE_MS;
|
||||
s->timer = ifp->now + n;
|
||||
@ -526,7 +528,7 @@ static struct mg_connection *accept_conn(struct mg_connection *lsn,
|
||||
}
|
||||
|
||||
long mg_io_send(struct mg_connection *c, const void *buf, size_t len) {
|
||||
struct mip_if *ifp = (struct mip_if *) c->mgr->priv;
|
||||
struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
|
||||
struct connstate *s = (struct connstate *) (c + 1);
|
||||
size_t max_headers_len = 14 + 24 /* max IP */ + 60 /* max TCP */;
|
||||
if (len + max_headers_len > ifp->tx.len) len = ifp->tx.len - max_headers_len;
|
||||
@ -587,7 +589,7 @@ static void read_conn(struct mg_connection *c, struct pkt *pkt) {
|
||||
#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,
|
||||
tx_tcp((struct mg_tcpip_if *) c->mgr->priv, c->rem.ip, TH_ACK, c->loc.port,
|
||||
c->rem.port, mg_htonl(s->seq), mg_htonl(s->ack), "", 0);
|
||||
#else
|
||||
// if not already running, setup a timer to send an ACK later
|
||||
@ -618,7 +620,7 @@ static void read_conn(struct mg_connection *c, struct pkt *pkt) {
|
||||
}
|
||||
}
|
||||
|
||||
static void rx_tcp(struct mip_if *ifp, struct pkt *pkt) {
|
||||
static void rx_tcp(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
struct mg_connection *c = getpeer(ifp->mgr, pkt, false);
|
||||
struct connstate *s = c == NULL ? NULL : (struct connstate *) (c + 1);
|
||||
#if 0
|
||||
@ -666,7 +668,7 @@ static void rx_tcp(struct mip_if *ifp, struct pkt *pkt) {
|
||||
}
|
||||
}
|
||||
|
||||
static void rx_ip(struct mip_if *ifp, struct pkt *pkt) {
|
||||
static void rx_ip(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
if (pkt->ip->proto == 1) {
|
||||
pkt->icmp = (struct icmp *) (pkt->ip + 1);
|
||||
if (pkt->pay.len < sizeof(*pkt->icmp)) return;
|
||||
@ -704,7 +706,7 @@ static void rx_ip(struct mip_if *ifp, struct pkt *pkt) {
|
||||
}
|
||||
}
|
||||
|
||||
static void rx_ip6(struct mip_if *ifp, struct pkt *pkt) {
|
||||
static void rx_ip6(struct mg_tcpip_if *ifp, struct pkt *pkt) {
|
||||
// MG_DEBUG(("IP %d", (int) len));
|
||||
if (pkt->ip6->proto == 1 || pkt->ip6->proto == 58) {
|
||||
pkt->icmp = (struct icmp *) (pkt->ip6 + 1);
|
||||
@ -720,7 +722,7 @@ static void rx_ip6(struct mip_if *ifp, struct pkt *pkt) {
|
||||
}
|
||||
}
|
||||
|
||||
static void mip_rx(struct mip_if *ifp, void *buf, size_t len) {
|
||||
static void mg_tcpip_rx(struct mg_tcpip_if *ifp, void *buf, size_t len) {
|
||||
const uint8_t broadcast[] = {255, 255, 255, 255, 255, 255};
|
||||
struct pkt pkt;
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
@ -757,7 +759,7 @@ static void mip_rx(struct mip_if *ifp, void *buf, size_t len) {
|
||||
}
|
||||
}
|
||||
|
||||
static void mip_poll(struct mip_if *ifp, uint64_t uptime_ms) {
|
||||
static void mg_tcpip_poll(struct mg_tcpip_if *ifp, uint64_t uptime_ms) {
|
||||
if (ifp == NULL || ifp->driver == NULL) return;
|
||||
bool expired_1000ms = mg_timer_expired(&ifp->timer_1000ms, 1000, uptime_ms);
|
||||
ifp->now = uptime_ms;
|
||||
@ -782,7 +784,7 @@ static void mip_poll(struct mip_if *ifp, uint64_t uptime_ms) {
|
||||
// Read data from the network
|
||||
size_t len = ifp->driver->rx((void *) ifp->rx.ptr, ifp->rx.len, ifp);
|
||||
if (len) {
|
||||
mip_rx(ifp, (void *) ifp->rx.ptr, len);
|
||||
mg_tcpip_rx(ifp, (void *) ifp->rx.ptr, len);
|
||||
}
|
||||
|
||||
// Process timeouts
|
||||
@ -812,7 +814,7 @@ static void mip_poll(struct mip_if *ifp, uint64_t uptime_ms) {
|
||||
// This function executes in interrupt context, thus it should copy data
|
||||
// somewhere fast. Note that newlib's malloc is not thread safe, thus use
|
||||
// our lock-free queue with preallocated buffer to copy data and return asap
|
||||
void mip_qwrite(void *buf, size_t len, struct mip_if *ifp) {
|
||||
void mg_tcpip_qwrite(void *buf, size_t len, struct mg_tcpip_if *ifp) {
|
||||
if (q_write(&ifp->queue, buf, len)) {
|
||||
ifp->nrecv++;
|
||||
} else {
|
||||
@ -820,16 +822,16 @@ void mip_qwrite(void *buf, size_t len, struct mip_if *ifp) {
|
||||
}
|
||||
}
|
||||
|
||||
size_t mip_qread(void *buf, struct mip_if *ifp) {
|
||||
size_t mg_tcpip_qread(void *buf, struct mg_tcpip_if *ifp) {
|
||||
return q_read(&ifp->queue, buf);
|
||||
}
|
||||
|
||||
size_t mip_driver_rx(void *buf, size_t len, struct mip_if *ifp) {
|
||||
return mip_qread((void *) ifp->rx.ptr, ifp);
|
||||
size_t mg_tcpip_driver_rx(void *buf, size_t len, struct mg_tcpip_if *ifp) {
|
||||
return mg_tcpip_qread((void *) ifp->rx.ptr, ifp);
|
||||
(void) len, (void) buf;
|
||||
}
|
||||
|
||||
void mip_init(struct mg_mgr *mgr, struct mip_if *ifp) {
|
||||
void mg_tcpip_init(struct mg_mgr *mgr, struct mg_tcpip_if *ifp) {
|
||||
// If MAC address is not set, make a random one
|
||||
if (ifp->mac[0] == 0 && ifp->mac[1] == 0 && ifp->mac[2] == 0 &&
|
||||
ifp->mac[3] == 0 && ifp->mac[4] == 0 && ifp->mac[5] == 0) {
|
||||
@ -860,7 +862,7 @@ void mip_init(struct mg_mgr *mgr, struct mip_if *ifp) {
|
||||
}
|
||||
}
|
||||
|
||||
void mip_free(struct mip_if *ifp) {
|
||||
void mg_tcpip_free(struct mg_tcpip_if *ifp) {
|
||||
free((char *) ifp->rx.ptr);
|
||||
free((char *) ifp->tx.ptr);
|
||||
}
|
||||
@ -874,13 +876,13 @@ int mg_mkpipe(struct mg_mgr *m, mg_event_handler_t fn, void *d, bool udp) {
|
||||
static void send_syn(struct mg_connection *c) {
|
||||
struct connstate *s = (struct connstate *) (c + 1);
|
||||
uint32_t isn = mg_htonl((uint32_t) mg_ntohs(c->loc.port));
|
||||
struct mip_if *ifp = (struct mip_if *) c->mgr->priv;
|
||||
struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
|
||||
tx_tcp(ifp, s->mac, c->rem.ip, TH_SYN, c->loc.port, c->rem.port, isn, 0, NULL,
|
||||
0);
|
||||
}
|
||||
|
||||
void mg_connect_resolved(struct mg_connection *c) {
|
||||
struct mip_if *ifp = (struct mip_if *) c->mgr->priv;
|
||||
struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
|
||||
c->is_resolving = 0;
|
||||
if (ifp->eport < MIP_EPHEMERAL_PORT) ifp->eport = MIP_EPHEMERAL_PORT;
|
||||
c->loc.ip = ifp->ip;
|
||||
@ -922,8 +924,9 @@ static void write_conn(struct mg_connection *c) {
|
||||
static void close_conn(struct mg_connection *c) {
|
||||
struct connstate *s = (struct connstate *) (c + 1);
|
||||
mg_iobuf_free(&s->raw); // For TLS connections, release raw data
|
||||
if (c->is_udp == false && c->is_listening == false) { // For TCP conns,
|
||||
struct mip_if *ifp = (struct mip_if *) c->mgr->priv; // send TCP FIN
|
||||
if (c->is_udp == false && c->is_listening == false) { // For TCP conns,
|
||||
struct mg_tcpip_if *ifp =
|
||||
(struct mg_tcpip_if *) c->mgr->priv; // send TCP FIN
|
||||
tx_tcp(ifp, s->mac, c->rem.ip, TH_FIN | TH_ACK, c->loc.port, c->rem.port,
|
||||
mg_htonl(s->seq), mg_htonl(s->ack), NULL, 0);
|
||||
}
|
||||
@ -938,7 +941,7 @@ static bool can_write(struct mg_connection *c) {
|
||||
void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
|
||||
struct mg_connection *c, *tmp;
|
||||
uint64_t now = mg_millis();
|
||||
mip_poll((struct mip_if *) mgr->priv, now);
|
||||
mg_tcpip_poll((struct mg_tcpip_if *) mgr->priv, now);
|
||||
mg_timer_poll(&mgr->timers, now);
|
||||
for (c = mgr->conns; c != NULL; c = tmp) {
|
||||
tmp = c->next;
|
||||
@ -955,7 +958,7 @@ void mg_mgr_poll(struct mg_mgr *mgr, int ms) {
|
||||
}
|
||||
|
||||
bool mg_send(struct mg_connection *c, const void *buf, size_t len) {
|
||||
struct mip_if *ifp = (struct mip_if *) c->mgr->priv;
|
||||
struct mg_tcpip_if *ifp = (struct mg_tcpip_if *) c->mgr->priv;
|
||||
bool res = false;
|
||||
if (ifp->ip == 0 || ifp->state != MIP_STATE_READY) {
|
||||
mg_error(c, "net down");
|
||||
@ -968,4 +971,4 @@ bool mg_send(struct mg_connection *c, const void *buf, size_t len) {
|
||||
}
|
||||
return res;
|
||||
}
|
||||
#endif // MG_ENABLE_MIP
|
||||
#endif // MG_ENABLE_TCPIP
|
79
src/tcpip/tcpip.h
Normal file
79
src/tcpip/tcpip.h
Normal file
@ -0,0 +1,79 @@
|
||||
#pragma once
|
||||
|
||||
#include "arch.h"
|
||||
#include "net.h"
|
||||
|
||||
struct mg_tcpip_if; // MIP network interface
|
||||
|
||||
struct mg_tcpip_driver {
|
||||
bool (*init)(struct mg_tcpip_if *); // Init driver
|
||||
size_t (*tx)(const void *, size_t, struct mg_tcpip_if *); // Transmit frame
|
||||
size_t (*rx)(void *buf, size_t len, struct mg_tcpip_if *); // Receive frame
|
||||
bool (*up)(struct mg_tcpip_if *); // Up/down status
|
||||
};
|
||||
|
||||
// Receive queue - single producer, single consumer queue. Interrupt-based
|
||||
// drivers copy received frames to the queue in interrupt context.
|
||||
// mg_tcpip_poll() function runs in event loop context, reads from the queue
|
||||
struct queue {
|
||||
uint8_t *buf;
|
||||
size_t len;
|
||||
volatile size_t tail, head;
|
||||
};
|
||||
|
||||
// Network interface
|
||||
struct mg_tcpip_if {
|
||||
uint8_t mac[6]; // MAC address. Must be set to a valid MAC
|
||||
uint32_t ip, mask, gw; // IP address, mask, default gateway
|
||||
struct mg_str rx; // Output (TX) buffer
|
||||
struct mg_str tx; // Input (RX) buffer
|
||||
bool enable_dhcp_client; // Enable DCHP client
|
||||
bool enable_dhcp_server; // Enable DCHP server
|
||||
struct mg_tcpip_driver *driver; // Low level driver
|
||||
void *driver_data; // Driver-specific data
|
||||
struct mg_mgr *mgr; // Mongoose event manager
|
||||
struct queue queue; // Set queue.len for interrupt based drivers
|
||||
|
||||
// Internal state, user can use it but should not change it
|
||||
uint8_t gwmac[6]; // Router's MAC
|
||||
uint64_t now; // Current time
|
||||
uint64_t timer_1000ms; // 1000 ms timer: for DHCP and link state
|
||||
uint64_t lease_expire; // Lease expiration time
|
||||
uint16_t eport; // Next ephemeral port
|
||||
volatile uint32_t ndrop; // Number of received, but dropped frames
|
||||
volatile uint32_t nrecv; // Number of received frames
|
||||
volatile uint32_t nsent; // Number of transmitted frames
|
||||
volatile uint32_t nerr; // Number of driver errors
|
||||
uint8_t state; // Current state
|
||||
#define MIP_STATE_DOWN 0 // Interface is down
|
||||
#define MIP_STATE_UP 1 // Interface is up
|
||||
#define MIP_STATE_READY 2 // Interface is up and has IP
|
||||
};
|
||||
|
||||
void mg_tcpip_init(struct mg_mgr *, struct mg_tcpip_if *);
|
||||
void mg_tcpip_free(struct mg_tcpip_if *);
|
||||
void mg_tcpip_qwrite(void *buf, size_t len, struct mg_tcpip_if *ifp);
|
||||
size_t mg_tcpip_qread(void *buf, struct mg_tcpip_if *ifp);
|
||||
// conveniency rx function for IRQ-driven drivers
|
||||
size_t mg_tcpip_driver_rx(void *buf, size_t len, struct mg_tcpip_if *ifp);
|
||||
|
||||
extern struct mg_tcpip_driver mg_tcpip_driver_stm32;
|
||||
extern struct mg_tcpip_driver mg_tcpip_driver_w5500;
|
||||
extern struct mg_tcpip_driver mg_tcpip_driver_tm4c;
|
||||
extern struct mg_tcpip_driver mg_tcpip_driver_stm32h;
|
||||
|
||||
// Drivers that require SPI, can use this SPI abstraction
|
||||
struct mg_tcpip_spi {
|
||||
void *spi; // Opaque SPI bus descriptor
|
||||
void (*begin)(void *); // SPI begin: slave select low
|
||||
void (*end)(void *); // SPI end: slave select high
|
||||
uint8_t (*txn)(void *, uint8_t); // SPI transaction: write 1 byte, read reply
|
||||
};
|
||||
|
||||
#if MG_ENABLE_TCPIP
|
||||
#if !defined(MG_ENABLE_DRIVER_STM32H) && !defined(MG_ENABLE_DRIVER_TM4C)
|
||||
#define MG_ENABLE_DRIVER_STM32 1
|
||||
#else
|
||||
#define MG_ENABLE_DRIVER_STM32 0
|
||||
#endif
|
||||
#endif
|
@ -1,21 +1,21 @@
|
||||
static bool mock_init(struct mip_if *ifp) {
|
||||
static bool mock_init(struct mg_tcpip_if *ifp) {
|
||||
(void) ifp;
|
||||
return true;
|
||||
}
|
||||
|
||||
static size_t mock_tx(const void *buf, size_t len, struct mip_if *ifp) {
|
||||
static size_t mock_tx(const void *buf, size_t len, struct mg_tcpip_if *ifp) {
|
||||
(void) buf, (void) len, (void) ifp;
|
||||
return len;
|
||||
}
|
||||
|
||||
static size_t mock_rx(void *buf, size_t len, struct mip_if *ifp) {
|
||||
static size_t mock_rx(void *buf, size_t len, struct mg_tcpip_if *ifp) {
|
||||
(void) buf, (void) len, (void) ifp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool mock_up(struct mip_if *ifp) {
|
||||
static bool mock_up(struct mg_tcpip_if *ifp) {
|
||||
(void) ifp;
|
||||
return true;
|
||||
}
|
||||
|
||||
struct mip_driver mip_driver_mock = {mock_init, mock_tx, mock_rx, mock_up};
|
||||
struct mg_tcpip_driver mg_tcpip_driver_mock = {mock_init, mock_tx, mock_rx, mock_up};
|
||||
|
10
test/fuzz.c
10
test/fuzz.c
@ -1,7 +1,7 @@
|
||||
#define MG_ENABLE_SOCKET 0
|
||||
#define MG_ENABLE_LOG 0
|
||||
#define MG_ENABLE_LINES 1
|
||||
#define MG_ENABLE_MIP 1
|
||||
#define MG_ENABLE_TCPIP 1
|
||||
|
||||
#include "mongoose.c"
|
||||
|
||||
@ -58,13 +58,13 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
mg_json_get(mg_str_n((char *) data, size), "$[0]", &n);
|
||||
|
||||
if (size > 0) {
|
||||
struct mip_if mif = {.ip = 0x01020304,
|
||||
struct mg_tcpip_if mif = {.ip = 0x01020304,
|
||||
.mask = 255,
|
||||
.gw = 0x01010101,
|
||||
.driver = &mip_driver_mock};
|
||||
.driver = &mg_tcpip_driver_mock};
|
||||
struct mg_mgr mgr;
|
||||
mg_mgr_init(&mgr);
|
||||
mip_init(&mgr, &mif);
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
|
||||
// Make a copy of the random data, in order to modify it
|
||||
void *pkt = malloc(size);
|
||||
@ -78,7 +78,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||
if (i >= sizeof(eth_types) / sizeof(eth_types[0])) i = 0;
|
||||
}
|
||||
|
||||
mip_rx(&mif, pkt, size);
|
||||
mg_tcpip_rx(&mif, pkt, size);
|
||||
mg_mgr_free(&mgr);
|
||||
free(pkt);
|
||||
free((char *) mif.rx.ptr);
|
||||
|
@ -1,4 +1,4 @@
|
||||
#define MG_ENABLE_MIP 1
|
||||
#define MG_ENABLE_TCPIP 1
|
||||
#define MG_ENABLE_SOCKET 0
|
||||
#define MG_USING_DHCP 1
|
||||
#define MG_ENABLE_PACKED_FS 0
|
||||
@ -30,14 +30,14 @@ static int s_num_tests = 0;
|
||||
} while (0)
|
||||
|
||||
// MIP TUNTAP driver
|
||||
static size_t tap_rx(void *buf, size_t len, struct mip_if *ifp) {
|
||||
static size_t tap_rx(void *buf, size_t len, struct mg_tcpip_if *ifp) {
|
||||
ssize_t received = read(*(int *) ifp->driver_data, buf, len);
|
||||
usleep(1); // This is to avoid 100% CPU
|
||||
if (received < 0) return 0;
|
||||
return (size_t) received;
|
||||
}
|
||||
|
||||
static size_t tap_tx(const void *buf, size_t len, struct mip_if *ifp) {
|
||||
static size_t tap_tx(const void *buf, size_t len, struct mg_tcpip_if *ifp) {
|
||||
ssize_t res = write(*(int *) ifp->driver_data, buf, len);
|
||||
if (res < 0) {
|
||||
MG_ERROR(("tap_tx failed: %d", errno));
|
||||
@ -46,7 +46,7 @@ static size_t tap_tx(const void *buf, size_t len, struct mip_if *ifp) {
|
||||
return (size_t) res;
|
||||
}
|
||||
|
||||
static bool tap_up(struct mip_if *ifp) {
|
||||
static bool tap_up(struct mg_tcpip_if *ifp) {
|
||||
return ifp->driver_data ? true : false;
|
||||
}
|
||||
|
||||
@ -161,14 +161,14 @@ static void test_http_fetch(void) {
|
||||
mg_mgr_init(&mgr); // Initialise event manager
|
||||
|
||||
// MIP driver
|
||||
struct mip_driver driver;
|
||||
struct mg_tcpip_driver driver;
|
||||
memset(&driver, 0, sizeof(driver));
|
||||
|
||||
driver.tx = tap_tx;
|
||||
driver.up = tap_up;
|
||||
driver.rx = tap_rx;
|
||||
|
||||
struct mip_if mif;
|
||||
struct mg_tcpip_if mif;
|
||||
memset(&mif, 0, sizeof(mif));
|
||||
|
||||
mif.driver = &driver;
|
||||
@ -184,7 +184,7 @@ static void test_http_fetch(void) {
|
||||
sscanf(mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &mif.mac[0], &mif.mac[1],
|
||||
&mif.mac[2], &mif.mac[3], &mif.mac[4], &mif.mac[5]);
|
||||
|
||||
mip_init(&mgr, &mif);
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
MG_INFO(("Init done, starting main loop"));
|
||||
|
||||
// Stack initialization, Network configuration (DHCP lease, ...)
|
||||
@ -236,7 +236,7 @@ static void test_http_fetch(void) {
|
||||
|
||||
// Clear
|
||||
mg_mgr_free(&mgr);
|
||||
mip_free(&mif); // Release after mg_mgr
|
||||
mg_tcpip_free(&mif); // Release after mg_mgr
|
||||
ASSERT(mgr.conns == NULL); // Deconstruction OK
|
||||
close(fd);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#define MG_ENABLE_SOCKET 0
|
||||
#define MG_ENABLE_LINES 1
|
||||
#define MG_ENABLE_MIP 1
|
||||
#define MG_ENABLE_TCPIP 1
|
||||
#define MG_ENABLE_PACKED_FS 0
|
||||
|
||||
#include <assert.h>
|
||||
@ -50,12 +50,12 @@ static void test_queue(void) {
|
||||
|
||||
static void test_statechange(void) {
|
||||
char tx[1540];
|
||||
struct mip_if iface;
|
||||
struct mg_tcpip_if iface;
|
||||
memset(&iface, 0, sizeof(iface));
|
||||
iface.ip = mg_htonl(0x01020304);
|
||||
iface.state = MIP_STATE_READY;
|
||||
iface.tx.ptr = tx, iface.tx.len = sizeof(tx);
|
||||
iface.driver = &mip_driver_mock;
|
||||
iface.driver = &mg_tcpip_driver_mock;
|
||||
onstatechange(&iface);
|
||||
}
|
||||
|
||||
@ -68,14 +68,14 @@ static void test_poll(void) {
|
||||
int count = 0, i;
|
||||
struct mg_mgr mgr;
|
||||
mg_mgr_init(&mgr);
|
||||
struct mip_if mif;
|
||||
struct mg_tcpip_if mif;
|
||||
memset(&mif, 0, sizeof(mif));
|
||||
mif.driver = &mip_driver_mock;
|
||||
mip_init(&mgr, &mif);
|
||||
mif.driver = &mg_tcpip_driver_mock;
|
||||
mg_tcpip_init(&mgr, &mif);
|
||||
mg_http_listen(&mgr, "http://127.0.0.1:12346", ph, &count);
|
||||
for (i = 0; i < 10; i++) mg_mgr_poll(&mgr, 0);
|
||||
ASSERT(count == 10);
|
||||
mip_free(&mif);
|
||||
mg_tcpip_free(&mif);
|
||||
mg_mgr_free(&mgr);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user