Skip to content

Commit da47617

Browse files
committed
Fixes for STM32H5 demo. Fixes MQTT broker and improrves testing/docs.
1 parent 689f2a6 commit da47617

4 files changed

Lines changed: 352 additions & 7 deletions

File tree

.github/workflows/stm32h563-m33mu.yml

Lines changed: 206 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: STM32H563 m33mu (echo only)
1+
name: STM32H563 m33mu
22

33
on:
44
push:
@@ -109,3 +109,208 @@ jobs:
109109
if [ -f /tmp/m33mu.pid ]; then
110110
sudo kill "$(cat /tmp/m33mu.pid)" 2>/dev/null || true
111111
fi
112+
113+
stm32h563_m33mu_full:
114+
runs-on: ubuntu-latest
115+
timeout-minutes: 30
116+
container:
117+
image: ghcr.io/danielinux/m33mu-ci:1.5
118+
options: --privileged
119+
120+
steps:
121+
- uses: actions/checkout@v4
122+
123+
- name: Clone wolfSSL, wolfSSH, wolfMQTT
124+
run: |
125+
set -euo pipefail
126+
cd ..
127+
git clone --depth 1 https://github.com/wolfSSL/wolfssl.git
128+
git clone --depth 1 https://github.com/wolfSSL/wolfssh.git
129+
git clone --depth 1 https://github.com/wolfSSL/wolfMQTT.git wolfmqtt
130+
131+
- name: Install host tools
132+
run: |
133+
set -euo pipefail
134+
apt-get update
135+
apt-get install -y sudo dnsmasq iproute2 netcat-openbsd \
136+
curl mosquitto-clients openssh-client
137+
138+
- name: Build STM32H563 full firmware
139+
run: |
140+
set -euo pipefail
141+
make -C src/port/stm32h563 \
142+
ENABLE_HTTPS=1 ENABLE_MQTT_BROKER=1 ENABLE_SSH=1 \
143+
CC=arm-none-eabi-gcc OBJCOPY=arm-none-eabi-objcopy
144+
145+
- name: Run m33mu + DHCP + full test
146+
timeout-minutes: 15
147+
run: |
148+
set -euo pipefail
149+
150+
cleanup() {
151+
set +e
152+
if [ -f /tmp/m33mu.pid ]; then
153+
sudo kill "$(cat /tmp/m33mu.pid)" 2>/dev/null || true
154+
fi
155+
sudo pkill -x m33mu 2>/dev/null || true
156+
if [ -f /tmp/dnsmasq.pid ]; then
157+
sudo kill "$(cat /tmp/dnsmasq.pid)" 2>/dev/null || true
158+
fi
159+
sudo ip link del tap0 2>/dev/null || true
160+
}
161+
trap cleanup EXIT
162+
163+
sudo ip tuntap add dev tap0 mode tap
164+
sudo ip addr add 192.168.12.1/24 dev tap0
165+
sudo ip link set tap0 up
166+
167+
cat > /tmp/dnsmasq.conf <<'EOF'
168+
interface=tap0
169+
bind-interfaces
170+
dhcp-range=192.168.12.50,192.168.12.100,255.255.255.0,12h
171+
dhcp-leasefile=/tmp/dnsmasq.leases
172+
log-dhcp
173+
EOF
174+
sudo dnsmasq --conf-file=/tmp/dnsmasq.conf --pid-file=/tmp/dnsmasq.pid
175+
176+
sudo m33mu src/port/stm32h563/app.bin \
177+
--cpu stm32h563 --tap:tap0 --uart-stdout --timeout 240 \
178+
2>&1 | tee /tmp/m33mu.log &
179+
sleep 1
180+
m33mu_pid="$(pgrep -n -x m33mu || true)"
181+
if [ -n "${m33mu_pid}" ]; then
182+
echo "${m33mu_pid}" > /tmp/m33mu.pid
183+
fi
184+
185+
# Wait for DHCP lease
186+
ip=""
187+
for _ in $(seq 1 60); do
188+
if [ -s /tmp/dnsmasq.leases ]; then
189+
ip="$(tail -n1 /tmp/dnsmasq.leases | cut -d' ' -f3)"
190+
fi
191+
if [ -n "${ip}" ]; then
192+
break
193+
fi
194+
sleep 1
195+
done
196+
if [ -z "${ip}" ]; then
197+
echo "No DHCP lease acquired."
198+
tail -n 200 /tmp/m33mu.log || true
199+
exit 1
200+
fi
201+
echo "Leased IP: ${ip}"
202+
203+
# Helper: check m33mu is still running
204+
check_alive() {
205+
if ! pgrep -x m33mu >/dev/null 2>&1; then
206+
echo "FAIL: m33mu exited unexpectedly."
207+
tail -n 200 /tmp/m33mu.log || true
208+
exit 1
209+
fi
210+
}
211+
212+
# Test 1: TCP Echo (port 7)
213+
echo "=== Test 1: TCP Echo ==="
214+
ok=0
215+
for _ in $(seq 1 20); do
216+
check_alive
217+
if printf "ping" | nc -w 2 "${ip}" 7 | grep -q "ping"; then
218+
ok=1; break
219+
fi
220+
sleep 0.5
221+
done
222+
if [ "${ok}" -ne 1 ]; then
223+
echo "FAIL: Echo test."
224+
tail -n 200 /tmp/m33mu.log || true
225+
exit 1
226+
fi
227+
echo "PASS: Echo test."
228+
229+
# Test 2: HTTPS Web Server (port 443)
230+
echo "=== Test 2: HTTPS Server ==="
231+
ok=0
232+
for _ in $(seq 1 10); do
233+
check_alive
234+
resp="$(curl -k -s --max-time 10 "https://${ip}/" 2>/dev/null || true)"
235+
if echo "${resp}" | grep -q "wolfIP Status"; then
236+
ok=1; break
237+
fi
238+
sleep 2
239+
done
240+
if [ "${ok}" -ne 1 ]; then
241+
echo "FAIL: HTTPS test."
242+
tail -n 200 /tmp/m33mu.log || true
243+
exit 1
244+
fi
245+
echo "PASS: HTTPS test."
246+
247+
# Test 3: TLS Echo (port 8443)
248+
echo "=== Test 3: TLS Echo ==="
249+
sleep 5 # allow recovery from HTTPS TLS session
250+
ok=0
251+
for _ in $(seq 1 5); do
252+
check_alive
253+
resp="$(echo "TLS-ping" | timeout 10 openssl s_client \
254+
-connect "${ip}:8443" -quiet 2>/dev/null || true)"
255+
if echo "${resp}" | grep -q "TLS-ping"; then
256+
ok=1; break
257+
fi
258+
sleep 3
259+
done
260+
if [ "${ok}" -ne 1 ]; then
261+
echo "FAIL: TLS echo test."
262+
tail -n 200 /tmp/m33mu.log || true
263+
exit 1
264+
fi
265+
echo "PASS: TLS echo test."
266+
267+
# Test 4: MQTT Broker (port 8883)
268+
echo "=== Test 4: MQTT Broker ==="
269+
sleep 5 # allow recovery from TLS echo session
270+
# Extract cert from certs.h for mosquitto
271+
sed -n '/server_cert_pem\[\]/,/^";$/p' src/port/certs.h \
272+
| sed 's/^"//; s/"$//; s/\\n$//' \
273+
| grep -v '^static\|^;' > /tmp/wolfip_cert.pem
274+
ok=0
275+
for _ in $(seq 1 5); do
276+
check_alive
277+
out="$(mosquitto_pub -h "${ip}" -p 8883 \
278+
--cafile /tmp/wolfip_cert.pem --insecure \
279+
-t "ci/test" -m "hello" -d 2>&1 || true)"
280+
if echo "${out}" | grep -q "CONNACK"; then
281+
ok=1; break
282+
fi
283+
sleep 5
284+
done
285+
if [ "${ok}" -ne 1 ]; then
286+
echo "FAIL: MQTT broker test."
287+
tail -n 200 /tmp/m33mu.log || true
288+
exit 1
289+
fi
290+
echo "PASS: MQTT broker test."
291+
292+
# Test 5: SSH Server (port 22)
293+
echo "=== Test 5: SSH Server ==="
294+
sleep 5 # allow recovery from MQTT TLS session
295+
ok=0
296+
for _ in $(seq 1 5); do
297+
check_alive
298+
# Test SSH banner (connection-level check, no auth)
299+
resp="$(timeout 10 bash -c "echo '' | nc -w 5 ${ip} 22" 2>/dev/null || true)"
300+
if echo "${resp}" | grep -qi "ssh"; then
301+
ok=1; break
302+
fi
303+
sleep 3
304+
done
305+
if [ "${ok}" -ne 1 ]; then
306+
echo "FAIL: SSH banner test."
307+
tail -n 200 /tmp/m33mu.log || true
308+
exit 1
309+
fi
310+
echo "PASS: SSH banner test."
311+
312+
echo ""
313+
echo "=== All tests passed ==="
314+
if [ -f /tmp/m33mu.pid ]; then
315+
sudo kill "$(cat /tmp/m33mu.pid)" 2>/dev/null || true
316+
fi

src/port/stm32h563/README.md

Lines changed: 120 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ This directory contains a bare-metal port of wolfIP for the STM32H563 microcontr
88
```bash
99
cd src/port/stm32h563
1010
CC=arm-none-eabi-gcc OBJCOPY=arm-none-eabi-objcopy \
11-
make ENABLE_HTTPS=1 ENABLE_SSH=1 ENABLE_MQTT=1
11+
make ENABLE_HTTPS=1 ENABLE_SSH=1 ENABLE_MQTT_BROKER=1
1212
```
1313

1414
2. **Flash to board:**
1515
```bash
1616
openocd -f interface/stlink-dap.cfg -f target/stm32h5x.cfg \
17-
-c "program app.bin 0x08000000 verify reset exit"
17+
-c "program app.elf verify reset exit"
1818
```
1919

2020
3. **Monitor UART output** (115200 baud on /dev/ttyACM0):
@@ -33,6 +33,11 @@ This directory contains a bare-metal port of wolfIP for the STM32H563 microcontr
3333

3434
# SSH (password: wolfip)
3535
ssh admin@<device-ip>
36+
37+
# MQTT Broker (TLS on port 8883)
38+
mosquitto_pub -h <device-ip> -p 8883 \
39+
--cafile /tmp/wolfip_cert.pem --insecure \
40+
-t "test/hello" -m "Hello MQTT!" -d
3641
```
3742

3843
## Hardware Requirements
@@ -349,18 +354,19 @@ make ENABLE_SSH=1 WOLFSSH_ROOT=/path/to/wolfssh
349354
350355
### Full Featured Build
351356
352-
Build with all features (TLS echo, HTTPS web server, and SSH shell).
357+
Build with all features (TLS echo, HTTPS web server, SSH shell, and MQTT broker).
353358
TLS is automatically enabled when any feature that requires it is set:
354359
355360
```bash
356-
make ENABLE_HTTPS=1 ENABLE_SSH=1
361+
make ENABLE_HTTPS=1 ENABLE_SSH=1 ENABLE_MQTT_BROKER=1
357362
```
358363
359364
This provides:
360365
- TCP echo server on port 7
361366
- TLS echo server on port 8443
362367
- HTTPS web server on port 443
363368
- SSH shell on port 22
369+
- MQTT broker on port 8883 (TLS)
364370
365371
### TLS Example Output
366372
@@ -784,6 +790,116 @@ This provides:
784790
| `../wolfmqtt_io.c` | wolfMQTT I/O glue layer for wolfIP sockets |
785791
| `user_settings.h` | wolfMQTT compile-time configuration |
786792

793+
## MQTT Broker
794+
795+
When built with `ENABLE_MQTT_BROKER=1`, the device runs a TLS-secured MQTT broker on port 8883.
796+
797+
### Building MQTT Broker Mode
798+
799+
```bash
800+
# Clone wolfMQTT alongside wolfip (broker support required)
801+
cd /path/to/parent
802+
git clone https://github.com/wolfSSL/wolfMQTT.git wolfmqtt
803+
804+
# Build with broker (and optionally HTTPS + SSH)
805+
cd wolfip/src/port/stm32h563
806+
make ENABLE_MQTT_BROKER=1 ENABLE_HTTPS=1 ENABLE_SSH=1
807+
```
808+
809+
### Expected Serial Output (MQTT Broker)
810+
811+
```
812+
Initializing MQTT broker...
813+
MQTT Broker: Initializing
814+
Entering main loop. Ready for connections!
815+
MQTT Broker: TLS initialized (TLS 1.3, ECC P-256)
816+
broker: plain port == TLS port (8883), TLS-only mode
817+
broker: listening on port 8883 (TLS)
818+
MQTT Broker: Running on port 8883 (TLS)
819+
```
820+
821+
When a client connects, the broker logs the full lifecycle:
822+
```
823+
broker: accept sock=261 (TLS)
824+
broker: TLS handshake done sock=261 TLSv1.3
825+
broker: CONNECT recv sock=261 len=14
826+
broker: CONNECT proto=4 clean=1 will=0 client_id=(null)
827+
broker: CONNACK send sock=261 code=0
828+
broker: disconnect sock=261
829+
```
830+
831+
### Extracting the Server Certificate
832+
833+
The broker uses a self-signed ECC P-256 certificate embedded in `../certs.h`. To test with TLS clients, extract it to a PEM file:
834+
835+
```bash
836+
# Manual: copy the PEM block from src/port/certs.h to a file
837+
cat > /tmp/wolfip_cert.pem << 'EOF'
838+
-----BEGIN CERTIFICATE-----
839+
MIIByTCCAW+gAwIBAgIUW3k96+M3BtW7CJRDEO/u5BaaGjgwCgYIKoZIzj0EAwIw
840+
...
841+
-----END CERTIFICATE-----
842+
EOF
843+
```
844+
845+
### Testing the MQTT Broker
846+
847+
Install mosquitto client tools: `sudo apt install mosquitto-clients`
848+
849+
#### Test 1: Publish (verify broker accepts connections)
850+
851+
```bash
852+
mosquitto_pub -h <device-ip> -p 8883 \
853+
--cafile /tmp/wolfip_cert.pem --insecure \
854+
-t "test/hello" -m "Hello wolfIP!" -d
855+
```
856+
857+
Expected output:
858+
```
859+
Client null sending CONNECT
860+
Client null received CONNACK (0)
861+
Client null sending PUBLISH (d0, q0, r0, m1, 'test/hello', ... (13 bytes))
862+
Client null sending DISCONNECT
863+
```
864+
865+
The `CONNACK (0)` confirms the broker accepted the connection.
866+
867+
#### Test 2: Subscribe and Publish (round-trip)
868+
869+
```bash
870+
# Terminal 1: Start subscriber (allow time for TLS handshake)
871+
mosquitto_sub -h <device-ip> -p 8883 \
872+
--cafile /tmp/wolfip_cert.pem --insecure \
873+
-t "test/#" -v
874+
875+
# Terminal 2: Publish (wait ~10s after subscriber connects)
876+
mosquitto_pub -h <device-ip> -p 8883 \
877+
--cafile /tmp/wolfip_cert.pem --insecure \
878+
-t "test/hello" -m "Round-trip works!"
879+
```
880+
881+
**Important:** The embedded Cortex-M33 needs several seconds per TLS handshake. Allow 8-10 seconds between connecting the subscriber and publisher to avoid overwhelming the device with concurrent TLS negotiations.
882+
883+
### MQTT Broker Configuration
884+
885+
| Setting | Default | File |
886+
|---------|---------|------|
887+
| Port (TLS) | 8883 | `mqtt_broker.c` |
888+
| Max Clients | 4 | `user_settings.h` (`BROKER_MAX_CLIENTS`) |
889+
| Max Subscriptions | 16 | `user_settings.h` (`BROKER_MAX_SUBS`) |
890+
| RX/TX Buffer | 1024 bytes | `user_settings.h` |
891+
| Max Payload | 1024 bytes | `user_settings.h` |
892+
| Log Level | INFO (2) | `user_settings.h` (`BROKER_LOG_LEVEL_DEFAULT`) |
893+
| TLS Version | TLS 1.3 | `mqtt_broker.c` |
894+
895+
### MQTT Broker Files
896+
897+
| File | Description |
898+
|------|-------------|
899+
| `mqtt_broker.c/h` | Broker state machine wrapper for wolfIP |
900+
| `../certs.h` | Embedded ECC P-256 cert/key (shared with TLS/HTTPS) |
901+
| `user_settings.h` | wolfMQTT broker compile-time config |
902+
787903
## Files
788904

789905
| File | Description |

0 commit comments

Comments
 (0)