diff --git a/.github/workflows/stm32h5-tls-m33mu.yml b/.github/workflows/stm32h5-tls-m33mu.yml new file mode 100644 index 0000000..35044e2 --- /dev/null +++ b/.github/workflows/stm32h5-tls-m33mu.yml @@ -0,0 +1,101 @@ +name: STM32H5 TLS Demo (m33mu + VDE) + +on: + push: + branches: [ 'master', 'main', 'release/**' ] + pull_request: + branches: [ '*' ] + +jobs: + stm32h5_tls_test: + runs-on: ubuntu-latest + container: + image: ghcr.io/danielinux/m33mu-ci:1.3 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + submodules: false + + - name: Clone wolfSSL + working-directory: /tmp + run: | + git clone --depth 1 https://github.com/wolfSSL/wolfssl.git + echo "wolfSSL cloned to /tmp/wolfssl" + + - name: Build TLS Server + Client Binaries + working-directory: src/port/stm32h563 + run: | + CC=arm-none-eabi-gcc OBJCOPY=arm-none-eabi-objcopy \ + make test-m33mu WOLFSSL_ROOT=/tmp/wolfssl + ls -lh app-server.bin + echo "Server binary size: $(stat -c%s app-server.bin) bytes" + ls -lh app-client.bin + echo "Client binary size: $(stat -c%s app-client.bin) bytes" + + - name: Start VDE Switch + run: | + vde_switch -s /tmp/vde_switch.ctl -d + sleep 2 + echo "VDE switch started" + + - name: Run TLS Server (m33mu) + working-directory: src/port/stm32h563 + run: | + m33mu --vde /tmp/vde_switch.ctl --expect-bkpt 0x7f --timeout 60 app-server.bin > server.log 2>&1 & + SERVER_PID=$! + echo "Server started with PID $SERVER_PID" + echo $SERVER_PID > /tmp/server.pid + sleep 5 + echo "Server log (first 50 lines):" + head -50 server.log || true + + - name: Run TLS Client (m33mu) + working-directory: src/port/stm32h563 + run: | + m33mu --vde /tmp/vde_switch.ctl --expect-bkpt 0x7f --timeout 60 app-client.bin > client.log 2>&1 + CLIENT_EXIT=$? + echo "Client exit code: $CLIENT_EXIT" + echo "Client log:" + cat client.log + if [ $CLIENT_EXIT -ne 0 ]; then + echo "ERROR: Client test failed!" + exit $CLIENT_EXIT + fi + + - name: Check Server Result + working-directory: src/port/stm32h563 + run: | + SERVER_PID=$(cat /tmp/server.pid) + # Wait a bit for server to finish + sleep 2 + # Check if server is still running + if kill -0 $SERVER_PID 2>/dev/null; then + echo "Server still running, waiting for completion..." + wait $SERVER_PID || true + fi + SERVER_EXIT=$? + echo "Server exit code: $SERVER_EXIT" + echo "Server log:" + cat server.log + if [ $SERVER_EXIT -ne 0 ] && [ $SERVER_EXIT -ne 143 ]; then + echo "ERROR: Server test failed!" + exit 1 + fi + + - name: Cleanup + if: always() + run: | + killall vde_switch 2>/dev/null || true + killall m33mu 2>/dev/null || true + rm -rf /tmp/vde_switch.ctl + + - name: Upload Logs + if: always() + uses: actions/upload-artifact@v4 + with: + name: m33mu-logs + path: | + src/port/stm32h563/server.log + src/port/stm32h563/client.log diff --git a/src/port/stm32h563/M33MU_TESTING_M2M_TLS.md b/src/port/stm32h563/M33MU_TESTING_M2M_TLS.md new file mode 100644 index 0000000..e572ae9 --- /dev/null +++ b/src/port/stm32h563/M33MU_TESTING_M2M_TLS.md @@ -0,0 +1,420 @@ +# m33mu TLS Testing with VDE Networking + +This document describes how to test the STM32H563 TLS client/server demo using the m33mu emulator with VDE (Virtual Distributed Ethernet) networking. + +## Overview + +The test setup consists of: +- **VDE Switch**: Virtual Ethernet switch that connects the emulator instances +- **TLS Server**: Runs on `192.168.100.10:8443`, echoes received data back +- **TLS Client**: Runs on `192.168.100.20`, connects to server and sends test message +- **Success Detection**: Both binaries trigger breakpoint `0x7f` on successful completion + +This same test runs automatically in CI via GitHub Actions. + +## Prerequisites + +### Software Requirements + +- **m33mu**: ARM Cortex-M33 emulator (`man m33mu` for documentation) +- **vde_switch**: Virtual Distributed Ethernet switch +- **arm-none-eabi-gcc**: ARM GCC toolchain for building +- **wolfSSL**: TLS library (clone alongside wolfip) + +### Installation (Ubuntu/Debian) + +```bash +# Install VDE +sudo apt install vde2 + +# Install ARM GCC toolchain +sudo apt install gcc-arm-none-eabi + +# Clone wolfSSL (if not already done) +cd /path/to/parent +git clone https://github.com/wolfSSL/wolfssl.git +# wolfip should be at /path/to/parent/wolfip +``` + +For m33mu installation, refer to the m33mu documentation. + +## Quick Start: Automated Script + +The easiest way to run the test locally is using the provided script: + +```bash +cd src/port/stm32h563 +./test-m33mu-local.sh +``` + +The script will: +1. Check prerequisites +2. Build both server and client binaries +3. Start VDE switch +4. Launch server in background +5. Launch client (connects to server) +6. Display logs and results +7. Clean up automatically + +Expected output on success: +``` +========================================== + Test Results +========================================== + +Client exit code: 0 +Server exit code: 0 + +✓ TEST PASSED + +Both server and client successfully completed TLS handshake +and data exchange. The test executed correctly! +``` + +## Manual Step-by-Step Testing + +For more control or debugging, you can run each component manually. + +### Step 1: Build Binaries + +```bash +cd src/port/stm32h563 + +# Build TLS server +make clean +CC=arm-none-eabi-gcc OBJCOPY=arm-none-eabi-objcopy \ + make test-server WOLFSSL_ROOT=/path/to/wolfssl + +# Build TLS client +make clean +CC=arm-none-eabi-gcc OBJCOPY=arm-none-eabi-objcopy \ + make test-client WOLFSSL_ROOT=/path/to/wolfssl +``` + +This creates: +- `app-server.bin`: TLS server binary (echoes data on port 8443) +- `app-client.bin`: TLS client binary (connects and sends test message) + +### Step 2: Start VDE Switch (Terminal 1) + +The VDE switch provides a virtual Ethernet network for the emulators. + +```bash +mkdir -p /tmp/vde +vde_switch -s /tmp/vde/switch.ctl -d +``` + +Options: +- `-s /tmp/vde/switch.ctl`: Socket path for VDE switch +- `-d`: Run as daemon + +Leave this running throughout the test. + +### Step 3: Start TLS Server (Terminal 2) + +```bash +cd src/port/stm32h563 + +m33mu --vde /tmp/vde/switch.ctl \ + --vde-mac 52:54:00:12:34:56 \ + --expect-bkpt 0x7f \ + --timeout 60000 \ + app-server.bin +``` + +Parameters: +- `--vde /tmp/vde/switch.ctl`: Connect to VDE switch +- `--vde-mac 52:54:00:12:34:56`: MAC address for server +- `--expect-bkpt 0x7f`: Exit successfully (code 0) when this breakpoint is hit +- `--timeout 60000`: Fail after 60 seconds if breakpoint not hit +- `app-server.bin`: Server binary to execute + +The server will: +1. Initialize wolfIP stack +2. Configure static IP: 192.168.100.10 +3. Start TLS server on port 8443 +4. Wait for client connection +5. Echo received data back +6. Trigger breakpoint 0x7f on successful echo +7. Exit with code 0 + +### Step 4: Wait for Server Initialization + +Wait **5 seconds** for the server to fully initialize before starting the client. + +```bash +sleep 5 +``` + +### Step 5: Start TLS Client (Terminal 3) + +```bash +cd src/port/stm32h563 + +m33mu --vde /tmp/vde/switch.ctl \ + --vde-mac 52:54:00:12:34:57 \ + --expect-bkpt 0x7f \ + --timeout 60000 \ + app-client.bin +``` + +Parameters: +- `--vde /tmp/vde/switch.ctl`: Connect to same VDE switch as server +- `--vde-mac 52:54:00:12:34:57`: Different MAC address for client +- `--expect-bkpt 0x7f`: Exit successfully when breakpoint hit +- `--timeout 60000`: 60 second timeout +- `app-client.bin`: Client binary to execute + +The client will: +1. Initialize wolfIP stack +2. Configure static IP: 192.168.100.20 +3. Connect to 192.168.100.10:8443 +4. Perform TLS 1.3 handshake +5. Send test message: "Hello TLS Server!\n" +6. Receive echoed response +7. Trigger breakpoint 0x7f on success +8. Exit with code 0 + +### Step 6: Check Exit Codes + +```bash +echo $? +``` + +- **Exit code 0**: Success (breakpoint 0x7f was hit) +- **Exit code != 0**: Failure (timeout, connection error, or breakpoint 0x7e hit) + +### Step 7: Cleanup + +```bash +# Kill VDE switch +killall vde_switch + +# Kill any remaining m33mu processes +killall m33mu + +# Remove VDE directory +rm -rf /tmp/vde +``` + +## Network Configuration + +| Component | MAC Address | IP Address | Port | +|-----------|-------------|------------|------| +| TLS Server | 52:54:00:12:34:56 | 192.168.100.10 | 8443 | +| TLS Client | 52:54:00:12:34:57 | 192.168.100.20 | - | + +Network: 192.168.100.0/24 + +## Breakpoint Codes + +The test uses ARM Cortex-M breakpoint instructions for success/failure detection: + +| Breakpoint | Hex | Meaning | +|------------|-----|---------| +| `bkpt #0x7f` | 0xBE7F | Test passed - m33mu exits with code 0 | +| `bkpt #0x7e` | 0xBE7E | Test failed - m33mu exits with non-zero code | + +When m33mu encounters the expected breakpoint (via `--expect-bkpt`), it exits gracefully with code 0. + +## Expected Output + +### Server Log (Success) + +``` +=== wolfIP STM32H563 Echo Server === +Initializing wolfIP stack... +M33MU_TEST: Setting static IP configuration: + IP: 192.168.100.10 + Mask: 255.255.255.0 + GW: 192.168.100.1 +Initializing TLS server on port 8443... +TLS: Server ready on port 8443 +Entering main loop. Ready for connections! +TLS: Client connected, starting handshake +TLS: Handshake complete +M33MU_TEST: TLS server echoed data successfully +M33MU_TEST: TLS server test PASSED +``` + +### Client Log (Success) + +``` +=== wolfIP STM32H563 Echo Server === +Initializing wolfIP stack... +M33MU_TEST: Setting static IP configuration: + IP: 192.168.100.20 + Mask: 255.255.255.0 + GW: 192.168.100.1 +Initializing TLS client... +TLS Client: Initialized +Entering main loop. Ready for connections! + +--- M33MU TLS Client Test: Connecting to TLS server --- +Target: 192.168.100.10:8443 +TLS Client: Connection initiated +TLS Client: Connected! +TLS Client: Sending test message... +TLS Client: Message sent +TLS Client received 19 bytes: +Hello TLS Server! + +M33MU_TEST: TLS client test PASSED +``` + +## Troubleshooting + +### VDE Switch Not Starting + +**Symptom:** `vde_switch` command not found + +**Solution:** +```bash +sudo apt install vde2 +``` + +### m33mu Not Found + +**Symptom:** `m33mu: command not found` + +**Solution:** Install m33mu emulator and add to PATH + +### Server/Client Timeout (60 seconds) + +**Symptoms:** +- No "TLS: Handshake complete" message +- m33mu exits after 60 seconds +- No breakpoint hit + +**Possible Causes:** +1. **Client started too early**: Increase wait time between server and client start + ```bash + sleep 10 # Instead of 5 + ``` + +2. **Wrong IP addresses**: Verify server and client use correct IPs + - Check UART output for "Setting static IP configuration" + +3. **VDE not connected**: Ensure both use same VDE socket path + +4. **Binary built without M33MU_TEST**: Rebuild with test targets + ```bash + make test-server + make test-client + ``` + +### Connection Refused + +**Symptom:** Client gets "Connection failed" immediately + +**Cause:** Server not fully initialized + +**Solution:** Increase delay between server and client start + +### Breakpoint 0x7e Hit (Failure) + +**Symptom:** Exit code != 0, log shows "test FAILED" + +**Cause:** Explicit failure detected in code (connection error, send failed) + +**Solution:** Check logs for specific error message before breakpoint + +### Build Fails - wolfSSL Not Found + +**Symptom:** +``` +wolfssl/options.h: No such file or directory +``` + +**Solution:** +```bash +# Clone wolfSSL +cd /path/to/parent +git clone https://github.com/wolfSSL/wolfssl.git + +# Or set WOLFSSL_ROOT +export WOLFSSL_ROOT=/path/to/wolfssl +make test-server WOLFSSL_ROOT=/path/to/wolfssl +``` + +## GitHub Actions CI + +The same test runs automatically on every push/PR via GitHub Actions. + +**Workflow:** `.github/workflows/stm32h5-tls-m33mu.yml` + +The CI: +1. Uses pre-built container: `ghcr.io/danielinux/m33mu-ci:1.3` +2. Clones wolfSSL +3. Builds both binaries +4. Starts VDE switch +5. Runs server in background +6. Runs client +7. Checks both exit codes +8. Uploads logs as artifacts + +View workflow runs at: https://github.com/YOUR_ORG/wolfip/actions + +## Advanced: Running Without TAP Interface + +The VDE setup runs entirely in userspace and does **not** require: +- Root/sudo privileges (for packet capture) +- TAP interface configuration +- Network capabilities + +This makes it ideal for: +- Sandboxed CI environments +- Containerized testing +- Non-privileged users + +The emulators communicate through the VDE switch socket, which is a simple UNIX domain socket. + +## Development: Modifying Tests + +### Changing IP Addresses + +Edit `src/port/stm32h563/main.c`: + +```c +#ifdef M33MU_TEST + #ifdef BUILD_TLS_SERVER_ONLY + #define TEST_SERVER_IP "192.168.100.10" // Change here + #endif + #ifdef BUILD_TLS_CLIENT_ONLY + #define TEST_SERVER_IP "192.168.100.10" // Must match server + #define TEST_CLIENT_IP "192.168.100.20" // Change here + #endif + #define TEST_NETMASK "255.255.255.0" + #define TEST_GATEWAY "192.168.100.1" +#endif +``` + +### Changing Test Message + +Edit the client section in `main.c`: + +```c +#ifdef M33MU_TEST + const char *test_msg = "Hello TLS Server!\n"; // Change message here +``` + +### Adjusting Timeouts + +For slower systems, increase timeout: + +```bash +m33mu --timeout 120000 ... # 2 minutes instead of 60 seconds +``` + +Or increase initialization wait: + +```bash +sleep 10 # 10 seconds instead of 5 +``` + +## References + +- **m33mu Documentation**: `man m33mu` +- **VDE Documentation**: https://github.com/virtualsquare/vde-2 +- **wolfSSL**: https://www.wolfssl.com/documentation/ +- **wolfIP README**: See main project README.md diff --git a/src/port/stm32h563/Makefile b/src/port/stm32h563/Makefile index 0ab8105..146afb6 100644 --- a/src/port/stm32h563/Makefile +++ b/src/port/stm32h563/Makefile @@ -1,5 +1,5 @@ -CC ?= arm-none-eabi-gcc -OBJCOPY ?= arm-none-eabi-objcopy +CC:=arm-none-eabi-gcc +OBJCOPY:=arm-none-eabi-objcopy ROOT := ../../.. @@ -20,6 +20,12 @@ ENABLE_SSH ?= 0 # MQTT support: set ENABLE_MQTT=1 to include wolfMQTT client (requires TLS) ENABLE_MQTT ?= 0 +# Build mode for m33mu testing: SERVER, CLIENT, or empty for combined +BUILD_MODE ?= + +# m33mu test mode: set M33MU_TEST=1 to enable test mode with breakpoint on success +M33MU_TEST ?= 0 + # Library paths - default to sibling directories (clone alongside pattern) WOLFSSL_ROOT ?= $(ROOT)/../wolfssl WOLFSSH_ROOT ?= $(ROOT)/../wolfssh @@ -46,6 +52,22 @@ endif LDFLAGS := -nostdlib -T $(LDSCRIPT) -Wl,-gc-sections +# Add build mode defines +ifeq ($(BUILD_MODE),SERVER) + CFLAGS += -DBUILD_TLS_SERVER_ONLY +endif + +ifeq ($(BUILD_MODE),CLIENT) + CFLAGS += -DBUILD_TLS_CLIENT_ONLY +endif + +# Add m33mu test mode define +ifeq ($(M33MU_TEST),1) + CFLAGS += -DM33MU_TEST=1 + # Disable DHCP for deterministic IPs in tests + CFLAGS += -DWOLFIP_ENABLE_DHCP=0 +endif + # Base source files SRCS := startup.c ivt.c syscalls.c main.c stm32h5_eth.c $(ROOT)/src/wolfip.c @@ -232,8 +254,34 @@ app.bin: app.elf $(WOLFSSL_ROOT)/%.o: $(WOLFSSL_ROOT)/%.c $(CC) $(CFLAGS_WOLFSSL) -DWOLFSSL_USER_SETTINGS $(if $(filter 1,$(ENABLE_SSH)),-DENABLE_SSH) -I$(WOLFSSL_ROOT) -c $< -o $@ +# ----------------------------------------------------------------------------- +# m33mu Test Targets +# ----------------------------------------------------------------------------- + +# Build TLS server/client for m33mu testing (same recipe) +test-server test-client: + $(MAKE) app-$(subst test-,,$@).bin ENABLE_TLS=1 M33MU_TEST=1 BUILD_MODE=$(if $(findstring server,$@),SERVER,CLIENT) + +# Build both TLS server and client for m33mu testing +test-m33mu: + $(MAKE) clean + $(MAKE) app-server.bin ENABLE_TLS=1 M33MU_TEST=1 BUILD_MODE=SERVER + $(MAKE) app-client.bin ENABLE_TLS=1 M33MU_TEST=1 BUILD_MODE=CLIENT + +app-server.elf: $(OBJS) $(LDSCRIPT) + $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -Wl,--start-group -lc -lm -lgcc -lnosys -Wl,--end-group -o $@ + +app-server.bin: app-server.elf + $(OBJCOPY) -O binary $< $@ + +app-client.elf: $(OBJS) $(LDSCRIPT) + $(CC) $(CFLAGS) $(OBJS) $(LDFLAGS) -Wl,--start-group -lc -lm -lgcc -lnosys -Wl,--end-group -o $@ + +app-client.bin: app-client.elf + $(OBJCOPY) -O binary $< $@ + clean: - rm -f *.o app.elf app.bin + rm -f *.o app.elf app.bin app-server.elf app-server.bin app-client.elf app-client.bin rm -f $(ROOT)/src/*.o rm -f $(ROOT)/src/port/*.o ifeq ($(ENABLE_TLS),1) @@ -267,7 +315,7 @@ size: app.elf @echo "Flash usage: $$(arm-none-eabi-size app.elf | awk 'NR==2{printf "%.1f%% (%d / %d bytes)", ($$1+$$2)*100/2097152, $$1+$$2, 2097152}')" @echo "RAM usage (static): $$(arm-none-eabi-size app.elf | awk 'NR==2{printf "%.1f%% (%d / %d bytes)", ($$2+$$3)*100/655360, $$2+$$3, 655360}')" -.PHONY: all clean verify size +.PHONY: all clean verify size test-server test-client test-m33mu # ----------------------------------------------------------------------------- # Help diff --git a/src/port/stm32h563/main.c b/src/port/stm32h563/main.c index e9fe260..b60f37d 100644 --- a/src/port/stm32h563/main.c +++ b/src/port/stm32h563/main.c @@ -45,7 +45,20 @@ #include "mqtt_client.h" #endif -#ifdef ENABLE_TLS +#ifdef M33MU_TEST +/* Test mode configuration for m33mu emulator */ + #ifdef BUILD_TLS_SERVER_ONLY + #define TEST_SERVER_IP "192.168.100.10" + #endif + #ifdef BUILD_TLS_CLIENT_ONLY + #define TEST_SERVER_IP "192.168.100.10" + #define TEST_CLIENT_IP "192.168.100.20" + #endif + #define TEST_NETMASK "255.255.255.0" + #define TEST_GATEWAY "192.168.100.1" +#endif + +#if defined(ENABLE_TLS) && !defined(BUILD_TLS_SERVER_ONLY) /* Google IP for TLS client test (run: dig +short google.com) */ #define GOOGLE_IP "142.250.189.174" @@ -209,9 +222,11 @@ static int https_status_handler(struct httpd *httpd, struct http_client *hc, #define LED2_PIN 4u static struct wolfIP *IPStack; +#ifndef BUILD_TLS_CLIENT_ONLY static int listen_fd = -1; static int client_fd = -1; static uint8_t rx_buf[RX_BUF_SIZE]; +#endif uint32_t wolfIP_getrandom(void) { @@ -432,7 +447,7 @@ static void eth_gpio_init(void) gpio_eth_pin(GPIOG_BASE, 13); /* TXD0 */ } -#ifdef ENABLE_TLS +#if defined(ENABLE_TLS) && !defined(BUILD_TLS_SERVER_ONLY) /* Callback for TLS client responses */ static void tls_response_cb(const char *data, int len, void *ctx) { @@ -449,9 +464,17 @@ static void tls_response_cb(const char *data, int len, void *ctx) } uart_puts("\n"); tls_client_test_done = 1; + +#ifdef M33MU_TEST + /* In test mode, receiving response means success */ + uart_puts("M33MU_TEST: TLS client test PASSED\n"); + /* Trigger breakpoint for m33mu to detect success */ + __asm volatile("bkpt #0x7f"); +#endif } #endif +#ifndef BUILD_TLS_CLIENT_ONLY static void echo_cb(int fd, uint16_t event, void *arg) { struct wolfIP *s = (struct wolfIP *)arg; @@ -480,11 +503,14 @@ static void echo_cb(int fd, uint16_t event, void *arg) client_fd = -1; } } +#endif int main(void) { struct wolfIP_ll_dev *ll; +#ifndef BUILD_TLS_CLIENT_ONLY struct wolfIP_sockaddr_in addr; +#endif uint64_t tick = 0; int ret; @@ -603,10 +629,22 @@ int main(void) } #else { +#ifdef M33MU_TEST + /* Use test-specific IPs for m33mu emulator */ + #ifdef BUILD_TLS_CLIENT_ONLY + ip4 ip = atoip4(TEST_CLIENT_IP); + #else + ip4 ip = atoip4(TEST_SERVER_IP); + #endif + ip4 nm = atoip4(TEST_NETMASK); + ip4 gw = atoip4(TEST_GATEWAY); + uart_puts("M33MU_TEST: Setting static IP configuration:\n"); +#else ip4 ip = atoip4(WOLFIP_IP); ip4 nm = atoip4(WOLFIP_NETMASK); ip4 gw = atoip4(WOLFIP_GW); uart_puts("Setting IP configuration:\n"); +#endif uart_puts(" IP: "); uart_putip4(ip); uart_puts("\n Mask: "); @@ -618,6 +656,7 @@ int main(void) } #endif +#ifndef BUILD_TLS_CLIENT_ONLY uart_puts("Creating TCP socket on port 7...\n"); listen_fd = wolfIP_sock_socket(IPStack, AF_INET, IPSTACK_SOCK_STREAM, 0); wolfIP_register_callback(IPStack, listen_fd, echo_cb, IPStack); @@ -628,20 +667,25 @@ int main(void) addr.sin_addr.s_addr = 0; (void)wolfIP_sock_bind(IPStack, listen_fd, (struct wolfIP_sockaddr *)&addr, sizeof(addr)); (void)wolfIP_sock_listen(IPStack, listen_fd, 1); +#endif #ifdef ENABLE_TLS + #ifndef BUILD_TLS_CLIENT_ONLY uart_puts("Initializing TLS server on port 8443...\n"); if (tls_server_init(IPStack, TLS_PORT, uart_puts) < 0) { uart_puts("ERROR: TLS server init failed\n"); } + #endif + #ifndef BUILD_TLS_SERVER_ONLY uart_puts("Initializing TLS client...\n"); if (tls_client_init(IPStack, uart_puts) < 0) { uart_puts("ERROR: TLS client init failed\n"); } + #endif #endif -#ifdef ENABLE_HTTPS +#if defined(ENABLE_HTTPS) && !defined(BUILD_TLS_SERVER_ONLY) && !defined(BUILD_TLS_CLIENT_ONLY) uart_puts("Initializing HTTPS server on port 443...\n"); /* Create SSL context for HTTPS */ @@ -665,14 +709,14 @@ int main(void) } #endif -#ifdef ENABLE_SSH +#if defined(ENABLE_SSH) && !defined(BUILD_TLS_SERVER_ONLY) && !defined(BUILD_TLS_CLIENT_ONLY) uart_puts("Initializing SSH server on port 22...\n"); if (ssh_server_init(IPStack, SSH_PORT, uart_puts) < 0) { uart_puts("ERROR: SSH server init failed\n"); } #endif -#ifdef ENABLE_MQTT +#if defined(ENABLE_MQTT) && !defined(BUILD_TLS_SERVER_ONLY) && !defined(BUILD_TLS_CLIENT_ONLY) uart_puts("Initializing MQTT client...\n"); { mqtt_client_config_t mqtt_config = { @@ -751,8 +795,23 @@ int main(void) #endif #ifdef ENABLE_TLS - /* TLS client test: connect to Google after network settles */ + #ifndef BUILD_TLS_SERVER_ONLY + /* TLS client test: connect after network settles */ if (!tls_client_test_started && tick > 5000) { +#ifdef M33MU_TEST + uart_puts("\n--- M33MU TLS Client Test: Connecting to TLS server ---\n"); + uart_puts("Target: "); + uart_puts(TEST_SERVER_IP); + uart_puts(":8443\n"); + + if (tls_client_connect(TEST_SERVER_IP, TLS_PORT, tls_response_cb, NULL) == 0) { + uart_puts("TLS Client: Connection initiated\n"); + } else { + uart_puts("TLS Client: Failed to start connection\n"); + uart_puts("M33MU_TEST: TLS client test FAILED\n"); + __asm volatile("bkpt #0x7e"); /* Failure breakpoint */ + } +#else uart_puts("\n--- TLS Client Test: Connecting to Google ---\n"); uart_puts("Target: "); uart_puts(GOOGLE_IP); @@ -765,16 +824,28 @@ int main(void) } else { uart_puts("TLS Client: Failed to start connection\n"); } +#endif tls_client_test_started = 1; } /* Poll TLS client state machine */ tls_client_poll(); - /* Send HTTP request once TLS handshake completes */ + /* Send test data once TLS handshake completes */ if (tls_client_is_connected() && !tls_client_test_done) { static int request_sent = 0; if (!request_sent) { +#ifdef M33MU_TEST + const char *test_msg = "Hello TLS Server!\n"; + uart_puts("TLS Client: Sending test message...\n"); + if (tls_client_send(test_msg, (int)strlen(test_msg)) > 0) { + uart_puts("TLS Client: Message sent\n"); + } else { + uart_puts("TLS Client: Send failed\n"); + uart_puts("M33MU_TEST: TLS client test FAILED\n"); + __asm volatile("bkpt #0x7e"); /* Failure breakpoint */ + } +#else const char *http_req = "GET / HTTP/1.1\r\n" "Host: google.com\r\n" "Connection: close\r\n\r\n"; @@ -784,9 +855,11 @@ int main(void) } else { uart_puts("TLS Client: Send failed\n"); } +#endif request_sent = 1; } } + #endif #endif /* Toggle LED every ~256K iterations as heartbeat */ diff --git a/src/port/stm32h563/test-m33mu-local.sh b/src/port/stm32h563/test-m33mu-local.sh new file mode 100755 index 0000000..489ef17 --- /dev/null +++ b/src/port/stm32h563/test-m33mu-local.sh @@ -0,0 +1,203 @@ +#!/bin/bash +# Local testing script for m33mu TLS client/server demo with VDE networking +# +# This script demonstrates how to run the same test locally that runs in CI. +# It starts a VDE switch, launches the TLS server, waits for it to initialize, +# then launches the TLS client. Both communicate over a virtual network. +# +# Prerequisites: +# - m33mu emulator installed and in PATH +# - vde_switch installed (VDE virtual distributed ethernet) +# - wolfSSL cloned alongside wolfip (or WOLFSSL_ROOT set) +# - ARM GCC toolchain (arm-none-eabi-gcc) + +set -e + +# Configuration +VDE_SOCKET="/tmp/vde-switch.ctl" +TIMEOUT=60 # 60 seconds +WOLFSSL_ROOT="${WOLFSSL_ROOT:-$(pwd)/../../../wolfssl}" + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +echo "==========================================" +echo " m33mu TLS Test - Local Execution" +echo "==========================================" +echo "" + +# Check prerequisites +echo "Checking prerequisites..." + +if ! command -v m33mu &> /dev/null; then + echo -e "${RED}ERROR: m33mu not found in PATH${NC}" + echo "Install m33mu emulator first" + exit 1 +fi + +if ! command -v vde_switch &> /dev/null; then + echo -e "${RED}ERROR: vde_switch not found in PATH${NC}" + echo "Install VDE: sudo apt install vde2 (Ubuntu/Debian)" + exit 1 +fi + +if ! command -v arm-none-eabi-gcc &> /dev/null; then + echo -e "${RED}ERROR: arm-none-eabi-gcc not found in PATH${NC}" + echo "Install ARM GCC toolchain: sudo apt install gcc-arm-none-eabi" + exit 1 +fi + +if [ ! -d "$WOLFSSL_ROOT" ]; then + echo -e "${RED}ERROR: wolfSSL not found at $WOLFSSL_ROOT${NC}" + echo "Clone wolfSSL: git clone https://github.com/wolfSSL/wolfssl.git" + echo "Or set WOLFSSL_ROOT environment variable" + exit 1 +fi + +echo -e "${GREEN}✓ All prerequisites found${NC}" +echo "" + +# Build binaries +echo "Building TLS server binary..." +if ! CC=arm-none-eabi-gcc OBJCOPY=arm-none-eabi-objcopy \ + make test-server WOLFSSL_ROOT="$WOLFSSL_ROOT"; then + echo -e "${RED}ERROR: Server build failed${NC}" + exit 1 +fi +echo -e "${GREEN}✓ Server binary built: $(ls -lh app-server.bin | awk '{print $5}')${NC}" + +echo "Building TLS client binary..." +if ! CC=arm-none-eabi-gcc OBJCOPY=arm-none-eabi-objcopy \ + make test-client WOLFSSL_ROOT="$WOLFSSL_ROOT"; then + echo -e "${RED}ERROR: Client build failed${NC}" + exit 1 +fi +echo -e "${GREEN}✓ Client binary built: $(ls -lh app-client.bin | awk '{print $5}')${NC}" +echo "" + +# Cleanup function +cleanup() { + echo "" + echo "Cleaning up..." + killall vde_switch 2>/dev/null || true + killall m33mu 2>/dev/null || true + rm -rf "$VDE_SOCKET" + echo -e "${GREEN}✓ Cleanup complete${NC}" +} + +# Set trap to cleanup on exit +trap cleanup EXIT INT TERM + +# Start VDE switch +echo "Starting VDE switch..." +echo vde_switch -s "$VDE_SOCKET" -d +vde_switch -s "$VDE_SOCKET" -d +VDE_RET=$? +sleep 2 + +if ! [ $VDE_RET -eq 0 ]; then + echo -e "${RED}ERROR: VDE switch failed to start${NC}" + exit 1 +fi +echo -e "${GREEN}✓ VDE switch started ${NC}" +echo "" + +# Start server +echo "Starting TLS server (m33mu)..." +echo " MAC: $SERVER_MAC" +echo " IP: 192.168.100.10:8443" +echo " Expecting breakpoint: 0x7f (success)" +echo " Timeout: ${TIMEOUT}ms" + +m33mu --vde "$VDE_SOCKET" \ + --expect-bkpt 0x7f \ + --timeout $TIMEOUT \ + app-server.bin > server.log 2>&1 & +SERVER_PID=$! + +echo -e "${GREEN}✓ Server started (PID: $SERVER_PID)${NC}" +echo "" + +# Wait for server to initialize +echo "Waiting 5 seconds for server initialization..." +sleep 5 + +echo "Server log (initialization):" +echo "----------------------------" +head -30 server.log +echo "----------------------------" +echo "" + +# Start client +echo "Starting TLS client (m33mu)..." +echo " IP: 192.168.100.20" +echo " Target: 192.168.100.10:8443" +echo " Expecting breakpoint: 0x7f (success)" +echo " Timeout: ${TIMEOUT}ms" + +m33mu --vde "$VDE_SOCKET" \ + --expect-bkpt 0x7f \ + --timeout $TIMEOUT \ + app-client.bin > client.log 2>&1 +CLIENT_EXIT=$? + +echo "" +echo "Client log:" +echo "----------------------------" +cat client.log +echo "----------------------------" +echo "" + +# Wait for server +echo "Waiting for server to complete..." +sleep 2 + +if kill -0 $SERVER_PID 2>/dev/null; then + wait $SERVER_PID 2>/dev/null || true +fi +SERVER_EXIT=$? + +echo "" +echo "Server log:" +echo "----------------------------" +cat server.log +echo "----------------------------" +echo "" + +# Check results +echo "==========================================" +echo " Test Results" +echo "==========================================" +echo "" + +echo "Client exit code: $CLIENT_EXIT" +echo "Server exit code: $SERVER_EXIT" +echo "" + +if [ $CLIENT_EXIT -eq 0 ] && { [ $SERVER_EXIT -eq 0 ] || [ $SERVER_EXIT -eq 143 ]; }; then + echo -e "${GREEN}✓ TEST PASSED${NC}" + echo "" + echo "Both server and client successfully completed TLS handshake" + echo "and data exchange. The test executed correctly!" + exit 0 +else + echo -e "${RED}✗ TEST FAILED${NC}" + echo "" + echo "Expected:" + echo " - Client exit code: 0 (breakpoint 0x7f hit)" + echo " - Server exit code: 0 or 143" + echo "" + echo "Actual:" + echo " - Client exit code: $CLIENT_EXIT" + echo " - Server exit code: $SERVER_EXIT" + echo "" + echo "Check the logs above for error messages." + echo "Common issues:" + echo " - Network not initialized: Check for 'Setting static IP' in logs" + echo " - Handshake timeout: Emulator might be too slow, increase timeout" + echo " - Connection refused: Server not listening yet, increase wait time" + exit 1 +fi diff --git a/src/port/stm32h563/tls_client.c b/src/port/stm32h563/tls_client.c index 8fe2576..c2ae482 100644 --- a/src/port/stm32h563/tls_client.c +++ b/src/port/stm32h563/tls_client.c @@ -209,7 +209,9 @@ int tls_client_poll(void) } /* Set SNI (Server Name Indication) - required by most servers */ +#ifndef M33MU_TEST wolfSSL_UseSNI(client.ssl, WOLFSSL_SNI_HOST_NAME, "google.com", 10); +#endif /* Associate SSL with socket */ ret = wolfSSL_SetIO_wolfIP(client.ssl, client.fd); diff --git a/src/port/stm32h563/tls_server.c b/src/port/stm32h563/tls_server.c index ee00904..3f62b1f 100644 --- a/src/port/stm32h563/tls_server.c +++ b/src/port/stm32h563/tls_server.c @@ -359,7 +359,14 @@ static void tls_client_cb(int fd, uint16_t event, void *arg) if (ret > 0) { /* Echo data back */ ret = wolfSSL_write(client->ssl, server.rx_buf, ret); - if (ret <= 0) { + if (ret > 0) { +#ifdef M33MU_TEST + debug_print("M33MU_TEST: TLS server echoed data successfully\n"); + debug_print("M33MU_TEST: TLS server test PASSED\n"); + /* Trigger breakpoint for m33mu to detect success */ + __asm volatile("bkpt #0x7f"); +#endif + } else { err = wolfSSL_get_error(client->ssl, ret); if (err != WOLFSSL_ERROR_WANT_WRITE) { debug_print("TLS: Write error\n");