Merge pull request #2032 from cesanta/move

Move mip/ -> src/tcpip/, rename mip_ -> mg_tcpip_
This commit is contained in:
Sergio R. Caprile 2023-02-08 09:49:06 -03:00 committed by GitHub
commit 9da80d7b7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
64 changed files with 515 additions and 516 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,
};

View File

@ -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;

View File

@ -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"));

View File

@ -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)

View File

@ -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..."));

View File

@ -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)

View File

@ -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..."));

View File

@ -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

View 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

View File

@ -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..."));

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 ..."));

View File

@ -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

View File

@ -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..."));

View File

@ -0,0 +1 @@
../../../mongoose.c

View File

@ -0,0 +1 @@
../../../mongoose.h

View File

@ -0,0 +1 @@
../../device-dashboard/net.c

View File

@ -0,0 +1 @@
../../device-dashboard/packed_fs.c

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 ..."));

View File

@ -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

View 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 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

View File

@ -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) {

View File

@ -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 \

View 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 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

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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
// -------------------------------------

View File

@ -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

View File

@ -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

View File

@ -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
// -------------------------------------

View File

@ -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

View File

@ -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
// -------------------------------------

View File

@ -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

View File

@ -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
// -------------------------------------

View File

@ -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

View File

@ -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
View 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

View File

@ -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};

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
}