OXYGENHUB
◆ main openmsx / doc / smxwifi.md
13.7 KiB · Markdown · last changed chore(): initial commit 1 month ago renderedsource blame history raw
1
# SM-X WiFi Emulation Information
2
3
This document describes the SM-X WiFi device emulated by openMSX
4
(`smxwifi`), its I/O interface and how to use it. The SM-X WiFi is built-in
5
on SM-X computers and on some OCM FPGA computers, not an external cartridge.
6
7
## Overview
8
9
The `smxwifi` device emulates the DucaSP SM-X WiFi (2020): an I/O-mapped
10
UART interface between the MSX and an ESP WiFi module, where the ESP side
11
runs the ESP32-UNAPI firmware. The UART link is either:
12
13
* **an emulated ESP32** (default), or
14
* **a real ESP32** on a host serial port, attached through the device's RS232 connector with `rs232-raw`
15
16
This should not be a concern for most users, where the emulated ESP32 will
17
be used. In some cases, user might want to not use the host network / bypass
18
host network limitations without changing firewall / binding / settings, 
19
those users can refer to the Using a real ESP32 section.
20
21
MSX software uses the adapter through the SM-X WiFi UNAPI BIOS / driver, which
22
implements the TCP-IP UNAPI specification over the UART protocol spoken by
23
the ESP32 firmware.
24
25
## UNAPI BIOS / driver
26
27
To add UNAPI capabilities to the MSX, download `ESPUNAPI_IO.rom`
28
from the [UNAPI_BIOS_CUSTOM_ESP_V2]https://github.com/ducasp/MSX-Development/tree/master/UNAPI_BIOS_CUSTOM_ESP_V2
29
30
It is free for use and required for this device. When using with a real ESP32 module,
31
keep F1 pressed during reset to connect to an AP, configure some features, etc.
32
While you can access this setup with an emulated ESP, no configuration is needed
33
and most of the configurations will not take any effect (as the host system will
34
govern those).
35
36
## Emulated ESP32
37
38
The emulated ESP32 implements the complete TCP-IP UNAPI firmware inside
39
openMSX: the TCP-IP UNAPI specification 1.1 (TCP and UDP connections, DNS
40
resolution, TLS/SSL over TCP active connections) using the network stack of
41
the host operating system. It DOES NOT emulate SSH UNAPI, that is available
42
only attaching a real ESP32.
43
44
### TLS/SSL support
45
46
TLS (spec 1.1, "Use TLS" flag in `TCPIP_TCP_OPEN`) is supported for TCP
47
**active** connections. The emulation uses the OpenSSL runtime library
48
**installed on the host operating system**, which is loaded dynamically at
49
startup.
50
51
* If OpenSSL is found, the "_Use TLS in TCP active connections_" capability
52
  bit is advertised and TLS connections can be opened. The OpenSSL version
53
  is printed to the openMSX console when the extension is inserted.
54
* If OpenSSL is not found, the capability bit is **not** advertised and a
55
  `TCPIP_TCP_OPEN` with the TLS flag returns `ERR_NOT_IMP`. A message is
56
  printed to the openMSX console when the extension is inserted.
57
58
TLS in **passive** connections is not implemented (the "_Use TLS in TCP
59
passive connections_" capability bit is never advertised, and requesting it
60
returns `ERR_NOT_IMP`, as the specification requires).
61
62
### Certificate verification
63
64
The "Verify the server certificate" flag of `TCPIP_TCP_OPEN` is honored: the
65
server certificate is validated against the root certificates of the host
66
operating system:
67
68
* **Windows:** the Windows system certificate store (`ROOT`) is used.
69
* **Linux:** the default OpenSSL system trust store is used
70
  (`/etc/ssl/cert.pem` and `/etc/ssl/certs` and friends).
71
* **macOS:** the `/etc/ssl/cert.pem` bundle is used (this file is provided by
72
  the system).
73
74
The server host name sent in the `TCPIP_TCP_OPEN` command is used for SNI
75
and, when verification is enabled, to validate the host name in the
76
certificate (matching the way the ESP32-UNAPI firmware reads the host name
77
from the command data). When no host name is supplied, the certificate chain
78
is still validated, but the host name is not checked.
79
80
A failed TLS handshake or certificate validation closes the connection; the
81
close reason (spec 4.5.4, reasons 9-19) is reported by `TCPIP_TCP_STATE` as
82
`ERR_NO_CONN` with the reason code.
83
84
### Installing OpenSSL
85
86
* **Linux:** OpenSSL is almost always pre-installed (package `openssl` /
87
  `libssl`). Nothing to do.
88
* **Windows:** install a Win64 OpenSSL build, e.g. the one distributed by
89
  [slproweb.com]https://slproweb.com/products/Win32OpenSSL.html or the
90
  "OpenSSL" builds by [FireDaemon]https://firedaemon.com (which are based
91
  on LibreSSL and use `libssl-4-x64.dll` / `libcrypto-4-x64.dll`). OpenSSL
92
  1.1.x, 3.x and LibreSSL 3.5.x/4.x are all supported. Make sure the OpenSSL
93
  DLLs (`libssl-*.dll` / `libcrypto-*.dll`) are in `PATH` or in the openMSX
94
  executable directory.
95
* **macOS:** install via Homebrew: `brew install openssl@3`.
96
97
### Network adapter preference
98
99
The IP address the emulated ESP32 reports to the MSX (`TCPIP_GET_IPINFO`) is
100
the one other machines use to reach the MSX, so it must be reachable on the
101
network. When the host has several adapters, the primary physical one is
102
chosen:
103
104
1. **Wired** (Ethernet) — preferred whenever it is up.
105
2. **Wireless** (Wi-Fi) — used when no wired adapter is up.
106
3. **Other physical** adapters (PPP, modems, ...).
107
4. **Virtual adapters** — only used when no physical adapter has a usable
108
   IPv4 address, so the emulation still works on machines that only have a
109
   virtual adapter (e.g. WSL-only setups).
110
111
The loopback adapter and adapters that are down are never used. Tunnels
112
(6to4, ISATAP, Teredo) and VPN software (Tailscale, ZeroTier, WireGuard, ...)
113
count as virtual.
114
115
When adapters tie in preference, the first one is used.
116
117
### Host ports and operating-system services
118
119
The emulation binds sockets on the **host** operating system to emulate the
120
network interface of the ESP32. Consequently, a port that is already in use
121
on the host cannot be used by the device:
122
123
* The emulation reports the host's own network configuration to the MSX (its
124
  primary IPv4 address, netmask, gateway and DNS servers, read fresh on each
125
  `TCPIP_GET_IPINFO` call; see *Network adapter preference* above), so other
126
  machines on the same network reach the MSX at that address, without any
127
  configuration on those machines. When the host has no usable IPv4
128
  configuration the fields report `0.0.0.0`, except the primary DNS which
129
  falls back to the well-known `8.8.8.8` (DNS lookups are performed on the
130
  host anyway, so the reported value is informational).
131
* Opening a connection (TCP or UDP) on a local port that is occupied by a
132
  host application returns `ERR_CONN_EXISTS` (or fails).
133
* In particular, well-known ports used by operating-system services are not
134
  available. On Windows, the Windows Time service (W32Time) is started by
135
  default and keeps UDP port 123 in use permanently, so the
136
  `TCPIP_SNTP_SET`/SNTP functionality cannot use its standard port. To use
137
  the SNTP port, the W32Time service must be stopped (see below).
138
* To free a port for the device, stop the host service that occupies it. On
139
  Windows, stop the Windows Time service temporarily with
140
  `net stop w32time`, or permanently by setting its startup type to
141
  "Manual"/"Disabled" in the Services manager (`services.msc`) or with
142
  `sc config w32time start= disabled`.
143
144
### Firewalls and inbound connections
145
146
The emulation binds sockets on the host operating system, so inbound traffic
147
to the emulated MSX has to pass the host's firewall. This applies to servers
148
running on the MSX (for example an FTP server on port 21) and to
149
"connect-back" connections, where a remote machine connects to the MSX's
150
advertised port (for example the data connection of an FTP client). Outbound
151
connections are normally not affected.
152
153
* **Linux (ufw):** ufw denies inbound connections by default. Allow the
154
  ports used by the MSX applications; for example, for an FTP server and
155
  the data connections of an FTP client:
156
157
      sudo ufw allow from 192.168.0.0/24 to any port 21 proto tcp         # FTP server (control)
158
      sudo ufw allow from 192.168.0.0/24 to any port 113 proto tcp        # FTP client (IDENT listener)
159
      sudo ufw allow from 192.168.0.0/24 to any port 1024:65535 proto tcp # FTP data connections
160
161
  (the FTP client opens its data connection on a random port in the range
162
  16384-32767; the FTP server opens its data ports starting at 1024).
163
164
  UDP traffic is subject to the same inbound deny, and replies to MSX UDP
165
  clients are affected as well: TFTP and SNTP on the MSX are clients, so
166
  their requests go out, but the replies (and subsequent data packets)
167
  arrive on the host as inbound UDP traffic and are dropped unless allowed.
168
  Allow the local ports those clients bind - SNTP uses UDP port 123, the
169
  TFTP client uses port 69 or a random port in the 16384-32767 range:
170
171
      sudo ufw allow from 192.168.0.0/24 to any port 123 proto udp        # SNTP client (local port)
172
      sudo ufw allow from 192.168.0.0/24 to any port 69 proto udp         # TFTP client (local port)
173
      sudo ufw allow from 192.168.0.0/24 to any port 16384:32767 proto udp # TFTP client (random local port)
174
175
  When in doubt, allow the local port(s) the application uses. Port 69 is
176
  privileged like port 21 (see below).
177
178
  For a quick test the firewall can be disabled temporarily with
179
  `sudo ufw disable` and re-enabled with `sudo ufw enable`. iptables- or
180
  nftables-based firewalls need equivalent rules.
181
182
* **Privileged ports:** on Linux and macOS, binding a port below 1024
183
  requires privileges. If an MSX application uses such a port (for
184
  example an FTP server on port 21), grant the capability once so regular
185
  users can bind these ports:
186
187
      sudo setcap 'cap_net_bind_service=+ep' /path/to/openmsx
188
189
  (the capability must be reapplied after every openMSX update, and the
190
  filesystem must support file capabilities). Alternatively,
191
  `authbind --deep openmsx` can be used. Windows has no privileged ports.
192
193
## Technical / Advanced Information
194
195
### Setting: simulated WiFi link
196
197
The `smxwifi-emulatedesp32-link-enabled` setting (default `true`) simulates
198
the WiFi link state of the emulated ESP32: with the setting disabled, the
199
emulated ESP32 reports its network link as closed (which is what
200
`TCPIP_NET_STATE` reports), like a real ESP32 whose WiFi radio is off. It
201
does not affect a real ESP32 attached through `rs232-raw`. This is useful
202
for developers that want to test cable / AP disconnected.
203
204
### I/O ports
205
206
The extension (`smxwifi.xml`) occupies 2 I/O ports at base `0x06`:
207
208
| Port     | Direction | Function                                             |
209
| -------- | --------- | ---------------------------------------------------- |
210
| base     | read      | UART RX FIFO byte (from the ESP module)              |
211
| base     | write     | UART command (baud-rate select, FIFO reset)          |
212
| base + 1 | read      | UART status                                          |
213
| base + 1 | write     | UART TX byte (to the ESP module)                     |
214
215
UART status bits:
216
217
| Bit | Meaning                                            |
218
| --- | -------------------------------------------------- |
219
| 0   | RX data available in the FIFO                      |
220
| 3   | Quick receive supported                            |
221
| 4   | Underrun (read of an empty FIFO), cleared by read  |
222
223
Quick receive is on by default, it works by safeguarding the read of an UART
224
RX FIFO byte, if FIFO is empty it will assert WAIT on the BUS (so z80 will
225
not continue processing) until a byte arrives OR a timeout elapses (about 30
226
ms); if no data arrives, `0xFF` is returned and the underrun bit is set.
227
UNAPI Driver make use of this feature to accelerate receiving data from
228
connections, in a way that it is guaranteed that extra bytes are coming, in
229
all other operations it is always checking if there is a byte available
230
before reading. The end result is faster receiving at the "expense" of
231
asserting WAIT for some time. The `smxwifi-emulatedesp32-quickrcv-enabled`
232
setting (default `true`) can be used to turn this feature off.
233
234
UART command values (write to the data port base):
235
236
| Value | Function                                   |
237
| ----- | ------------------------------------------ |
238
| 0-9   | Select baud rate (see table below)         |
239
| 20    | Reset the RX FIFO                          |
240
241
Baud rates (value = index):
242
243
| Value | Baud rate | Value | Baud rate |
244
| ----- | --------- | ----- | --------- |
245
| 0     | 859372    | 5     | 38400     |
246
| 1     | 346520    | 6     | 31250     |
247
| 2     | 231014    | 7     | 19200     |
248
| 3     | 115200    | 8     | 9600      |
249
| 4     | 57600     | 9     | 4800      |
250
251
The default after reset is baud rate 0 (859372). The UART parameters are
252
always 8 data bits, 1 stop bit, no parity. With the emulated ESP32 the baud
253
rate is not considered (there is no real serial communication).
254
255
## Using a real ESP32
256
257
### ESP Firmware
258
259
A real ESP32 module can be useful for developers or advanced users that do
260
not want to run into the host network limitations or want to have a separate
261
physical connection to the MSX. This module must run the ESP32-UNAPI firmware,
262
which is built from the [ESP32-UNAPI-Firmware]https://github.com/ducasp/ESP32-UNAPI-Firmware
263
repository and flashed to the ESP32. We recommend using an **ESP32-C6** or
264
**ESP32-S3** board with **at least 8 MB of flash; 16 MB is recommended**.
265
266
### Connector and pluggables
267
268
Once the extension is inserted, it exposes an RS232 connector named `smxwifi`.
269
If you plan to use a real ESP32 module instead of the emulated one, plug
270
`rs232-raw` into it to connect the UART to a real ESP32 on a host serial port:
271
272
```
273
ext smxwifi
274
plug smxwifi rs232-raw
275
set rs232-raw-port COM7
276
```
277
278
As long as the connector has no `rs232-raw` device plugged in, or its host
279
serial port is not open (no port selected, port in use, ...), the device
280
talks to the emulated ESP32, so the adapter keeps working with no real
281
hardware attached. Plugging a device other than `rs232-raw` also leaves the
282
emulated ESP32 in charge.
283
284
Note: changes can be done pretty easily on the GUI as well, using the connectors menu.
285
286
With `rs232-raw` the networking happens on the attached real device, so the
287
host networking considerations of the emulated ESP32 (firewall, ports, TLS)
288
do not apply.