com2tty 0.2.0__tar.gz → 0.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {com2tty-0.2.0/src/com2tty.egg-info → com2tty-0.3.1}/PKG-INFO +160 -58
- {com2tty-0.2.0 → com2tty-0.3.1}/README.md +159 -57
- {com2tty-0.2.0 → com2tty-0.3.1}/pyproject.toml +4 -1
- com2tty-0.3.1/src/com2tty/__init__.py +1 -0
- com2tty-0.3.1/src/com2tty/bridge.py +21 -0
- com2tty-0.2.0/src/com2tty/cli.py → com2tty-0.3.1/src/com2tty/cli/__init__.py +113 -22
- {com2tty-0.2.0/src/com2tty → com2tty-0.3.1/src/com2tty/cli}/profiles.py +20 -3
- com2tty-0.3.1/src/com2tty/core/__init__.py +6 -0
- com2tty-0.3.1/src/com2tty/core/boards.py +77 -0
- com2tty-0.3.1/src/com2tty/core/constants.py +91 -0
- com2tty-0.3.1/src/com2tty/core/frames.py +143 -0
- com2tty-0.3.1/src/com2tty/core/protocol.py +129 -0
- com2tty-0.3.1/src/com2tty/pad_bridge.py +21 -0
- com2tty-0.3.1/src/com2tty/windows/__init__.py +6 -0
- com2tty-0.2.0/src/com2tty/boards.py → com2tty-0.3.1/src/com2tty/windows/board_reset.py +27 -80
- com2tty-0.3.1/src/com2tty/windows/bridge_app.py +404 -0
- com2tty-0.3.1/src/com2tty/windows/control_handler.py +482 -0
- {com2tty-0.2.0/src/com2tty → com2tty-0.3.1/src/com2tty/windows}/discovery.py +13 -4
- com2tty-0.3.1/src/com2tty/windows/doctor.py +210 -0
- com2tty-0.3.1/src/com2tty/windows/gamepad_app.py +226 -0
- com2tty-0.2.0/src/com2tty/xinput.py → com2tty-0.3.1/src/com2tty/windows/gamepad_host.py +24 -62
- com2tty-0.3.1/src/com2tty/windows/os_hacks/__init__.py +12 -0
- com2tty-0.2.0/src/com2tty/uf2.py → com2tty-0.3.1/src/com2tty/windows/os_hacks/autoplay.py +16 -81
- com2tty-0.2.0/src/com2tty/banner.py → com2tty-0.3.1/src/com2tty/windows/os_hacks/console.py +10 -0
- com2tty-0.3.1/src/com2tty/windows/os_hacks/device_watcher.py +205 -0
- com2tty-0.3.1/src/com2tty/windows/os_hacks/explorer.py +154 -0
- com2tty-0.2.0/src/com2tty/rfc2217_server.py → com2tty-0.3.1/src/com2tty/windows/rfc2217_redirector.py +29 -0
- com2tty-0.3.1/src/com2tty/windows/serial_host.py +313 -0
- com2tty-0.3.1/src/com2tty/windows/uf2_flash.py +84 -0
- com2tty-0.3.1/src/com2tty/windows/wsl_process.py +264 -0
- com2tty-0.3.1/src/com2tty/wsl/__init__.py +14 -0
- com2tty-0.3.1/src/com2tty/wsl/assets/picotool_wrapper.py.in +48 -0
- com2tty-0.2.0/src/com2tty/pad_bridge.py → com2tty-0.3.1/src/com2tty/wsl/evdev_sink.py +109 -205
- com2tty-0.3.1/src/com2tty/wsl/gamepad_app.py +99 -0
- com2tty-0.3.1/src/com2tty/wsl/integrations/__init__.py +9 -0
- com2tty-0.3.1/src/com2tty/wsl/integrations/picotool.py +133 -0
- com2tty-0.3.1/src/com2tty/wsl/integrations/shell_env.py +225 -0
- com2tty-0.3.1/src/com2tty/wsl/liveness.py +95 -0
- com2tty-0.3.1/src/com2tty/wsl/pty_manager.py +129 -0
- com2tty-0.3.1/src/com2tty/wsl/serial_app.py +284 -0
- com2tty-0.3.1/src/com2tty/wsl/servers/__init__.py +8 -0
- com2tty-0.3.1/src/com2tty/wsl/servers/base.py +144 -0
- com2tty-0.3.1/src/com2tty/wsl/servers/rfc2217_forwarder.py +85 -0
- com2tty-0.3.1/src/com2tty/wsl/servers/uf2_relay.py +117 -0
- {com2tty-0.2.0 → com2tty-0.3.1/src/com2tty.egg-info}/PKG-INFO +160 -58
- com2tty-0.3.1/src/com2tty.egg-info/SOURCES.txt +84 -0
- com2tty-0.3.1/tests/test_autoplay.py +267 -0
- com2tty-0.3.1/tests/test_board_reset.py +71 -0
- {com2tty-0.2.0 → com2tty-0.3.1}/tests/test_boards.py +19 -17
- com2tty-0.3.1/tests/test_bridge_app.py +821 -0
- {com2tty-0.2.0 → com2tty-0.3.1}/tests/test_cli.py +104 -8
- com2tty-0.3.1/tests/test_console.py +79 -0
- com2tty-0.3.1/tests/test_control_handler.py +1151 -0
- com2tty-0.3.1/tests/test_core_frames.py +109 -0
- com2tty-0.3.1/tests/test_core_protocol.py +140 -0
- com2tty-0.3.1/tests/test_devnotify.py +237 -0
- {com2tty-0.2.0 → com2tty-0.3.1}/tests/test_discovery.py +25 -2
- com2tty-0.3.1/tests/test_doctor.py +323 -0
- com2tty-0.3.1/tests/test_entry_shims.py +80 -0
- com2tty-0.2.0/tests/test_pad_bridge.py → com2tty-0.3.1/tests/test_evdev_sink.py +201 -91
- com2tty-0.3.1/tests/test_explorer.py +204 -0
- com2tty-0.3.1/tests/test_gamepad_app.py +356 -0
- com2tty-0.3.1/tests/test_liveness.py +158 -0
- com2tty-0.3.1/tests/test_picotool.py +333 -0
- {com2tty-0.2.0 → com2tty-0.3.1}/tests/test_profiles.py +36 -5
- com2tty-0.3.1/tests/test_pty_manager.py +119 -0
- com2tty-0.3.1/tests/test_rfc2217_forwarder.py +173 -0
- com2tty-0.2.0/tests/test_rfc2217_server.py → com2tty-0.3.1/tests/test_rfc2217_redirector.py +64 -3
- com2tty-0.3.1/tests/test_serial_app.py +535 -0
- com2tty-0.3.1/tests/test_serial_host.py +493 -0
- com2tty-0.3.1/tests/test_shell_env.py +489 -0
- com2tty-0.3.1/tests/test_uf2_flash.py +108 -0
- com2tty-0.3.1/tests/test_uf2_relay.py +366 -0
- com2tty-0.3.1/tests/test_wsl_gamepad_app.py +51 -0
- com2tty-0.3.1/tests/test_wsl_process.py +275 -0
- com2tty-0.3.1/tests/test_wsl_servers_base.py +103 -0
- {com2tty-0.2.0 → com2tty-0.3.1}/tests/test_xinput.py +33 -29
- com2tty-0.2.0/src/com2tty/__init__.py +0 -1
- com2tty-0.2.0/src/com2tty/bridge.py +0 -666
- com2tty-0.2.0/src/com2tty/host.py +0 -1166
- com2tty-0.2.0/src/com2tty.egg-info/SOURCES.txt +0 -33
- com2tty-0.2.0/tests/test_bridge_script.py +0 -1572
- com2tty-0.2.0/tests/test_host.py +0 -3021
- {com2tty-0.2.0 → com2tty-0.3.1}/LICENSE +0 -0
- {com2tty-0.2.0 → com2tty-0.3.1}/setup.cfg +0 -0
- {com2tty-0.2.0 → com2tty-0.3.1}/setup.py +0 -0
- {com2tty-0.2.0 → com2tty-0.3.1}/src/com2tty/__main__.py +0 -0
- {com2tty-0.2.0 → com2tty-0.3.1}/src/com2tty.egg-info/dependency_links.txt +0 -0
- {com2tty-0.2.0 → com2tty-0.3.1}/src/com2tty.egg-info/entry_points.txt +0 -0
- {com2tty-0.2.0 → com2tty-0.3.1}/src/com2tty.egg-info/requires.txt +0 -0
- {com2tty-0.2.0 → com2tty-0.3.1}/src/com2tty.egg-info/top_level.txt +0 -0
- {com2tty-0.2.0 → com2tty-0.3.1}/tests/test_main.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: com2tty
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: A Windows COM port to WSL ttyUSB forwarder
|
|
5
5
|
Author-email: yichengs <yichengs.tw+com2tty@gmail.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/Yi-Cheng-Wang/com2tty
|
|
@@ -116,7 +116,21 @@ The following options apply to both modes.
|
|
|
116
116
|
--version Print the com2tty version and exit.
|
|
117
117
|
-l, --list List the serial ports Windows can see (device name,
|
|
118
118
|
VID:PID, USB bus id, serial number, detected board,
|
|
119
|
-
description) and exit.
|
|
119
|
+
description) and exit. Supplying a COM port together
|
|
120
|
+
with --list is an argument error.
|
|
121
|
+
--json With --list: print the port list as a JSON array
|
|
122
|
+
instead of an aligned table, for scripts and IDE
|
|
123
|
+
integrations.
|
|
124
|
+
--doctor Run an environment self-check (WSL, python3, drive
|
|
125
|
+
automounting, fuser, TCP port availability, leftovers
|
|
126
|
+
from crashed sessions, /dev/uinput, the XInput DLL)
|
|
127
|
+
and exit. Exit status 1 when a required check fails.
|
|
128
|
+
--auto-respawn Rebuild the bridge automatically when the WSL helper
|
|
129
|
+
dies, for example after `wsl --shutdown` or a WSL
|
|
130
|
+
servicing update: com2tty waits until WSL answers
|
|
131
|
+
again and re-creates the same endpoint. In serial
|
|
132
|
+
mode this implies --wait. Applies to serial and
|
|
133
|
+
gamepad mode alike.
|
|
120
134
|
-d, --debug Enable verbose debug logging on standard error.
|
|
121
135
|
--distro NAME WSL distribution to use (default: the WSL default
|
|
122
136
|
distribution). Useful when the default distribution
|
|
@@ -138,6 +152,10 @@ port [port ...] Windows COM port(s) to bridge, for example COM3, or
|
|
|
138
152
|
--rfc2217-port PORT TCP port for the in-WSL RFC 2217 forwarder
|
|
139
153
|
(default: 4000). The UF2 relay uses PORT + 1; with
|
|
140
154
|
multiple ports, each additional port uses PORT + 2i.
|
|
155
|
+
--wait If the COM port is not present yet, wait for it to
|
|
156
|
+
appear instead of failing, then bridge it. Useful
|
|
157
|
+
when com2tty is started before the device is
|
|
158
|
+
plugged in.
|
|
141
159
|
--bytesize {5,6,7,8} Serial byte size (default: 8).
|
|
142
160
|
--parity {N,E,O,S,M} Parity: none, even, odd, space, or mark (default: N).
|
|
143
161
|
--stopbits {1,1.5,2} Stop bits (default: 1).
|
|
@@ -155,7 +173,12 @@ port [port ...] Windows COM port(s) to bridge, for example COM3, or
|
|
|
155
173
|
|
|
156
174
|
```text
|
|
157
175
|
--gamepad Select gamepad mode. No COM port is required.
|
|
158
|
-
--pad-index {0,1,2,3}
|
|
176
|
+
--pad-index {0,1,2,3} [...]
|
|
177
|
+
XInput controller slot(s) to forward (default: 0).
|
|
178
|
+
Several slots may be given (--pad-index 0 1) to
|
|
179
|
+
forward multiple controllers at once; each gets its
|
|
180
|
+
own WSL helper and endpoint (/tmp/com2pad0,
|
|
181
|
+
/tmp/com2pad1, ...).
|
|
159
182
|
--pad-name NAME Device name advertised inside WSL
|
|
160
183
|
(default: "Microsoft X-Box 360 pad").
|
|
161
184
|
--uinput Create a real /dev/input device through /dev/uinput
|
|
@@ -218,7 +241,15 @@ stale Windows handle and waits for the device to come back, first under its
|
|
|
218
241
|
original COM name and then by scanning for its USB serial number, because
|
|
219
242
|
Windows may assign a different COM number after a replug. Once the device
|
|
220
243
|
reappears the bridge resumes automatically; the WSL endpoint stays in place
|
|
221
|
-
the whole time.
|
|
244
|
+
the whole time. The waiting loops are event-driven: com2tty registers for
|
|
245
|
+
Windows device-change notifications (`WM_DEVICECHANGE`), so a replugged
|
|
246
|
+
device resumes the moment Windows enumerates it rather than on the next
|
|
247
|
+
polling tick (plain polling remains as the fallback).
|
|
248
|
+
|
|
249
|
+
The complementary case — WSL itself going away, for example through
|
|
250
|
+
`wsl --shutdown` or a WSL update — is covered by `--auto-respawn`: instead
|
|
251
|
+
of exiting when the WSL helper dies, com2tty waits until WSL answers again
|
|
252
|
+
and rebuilds the bridge with the same endpoint paths.
|
|
222
253
|
|
|
223
254
|
### Bridging multiple ports
|
|
224
255
|
|
|
@@ -266,12 +297,18 @@ com2tty @myboard --baud 9600
|
|
|
266
297
|
com2tty @pad
|
|
267
298
|
```
|
|
268
299
|
|
|
300
|
+
A literal argument that must begin with `@` is written with a doubled marker:
|
|
301
|
+
`@@value` is passed through as the literal `@value` and is never interpreted as
|
|
302
|
+
a profile reference.
|
|
303
|
+
|
|
269
304
|
### Automatic baud-rate detection
|
|
270
305
|
|
|
271
306
|
When the baud rate is left at its default value of `auto`, com2tty queries the
|
|
272
|
-
rate that Windows has configured for the port and uses it.
|
|
273
|
-
the
|
|
274
|
-
|
|
307
|
+
rate that Windows has configured for the port and uses it. The rate is read
|
|
308
|
+
directly from the Win32 `GetCommState` API, which works regardless of the
|
|
309
|
+
Windows display language; parsing the `mode.com` output is kept only as a
|
|
310
|
+
fallback. If detection fails, the bridge falls back to 9600 baud. To set the
|
|
311
|
+
rate explicitly, pass a numeric value to `--baud`.
|
|
275
312
|
|
|
276
313
|
```cmd
|
|
277
314
|
com2tty COM3 --baud auto
|
|
@@ -316,9 +353,11 @@ when zsh is in use or that file exists, and to
|
|
|
316
353
|
`~/.config/fish/conf.d/com2tty.fish` when fish is in use or its configuration
|
|
317
354
|
directory exists. Open a new WSL shell or run `source ~/.bashrc` (or
|
|
318
355
|
`source ~/.zshrc`; fish picks the snippet up automatically) after starting
|
|
319
|
-
com2tty for them to take effect. The variables are removed when com2tty exits
|
|
320
|
-
|
|
321
|
-
|
|
356
|
+
com2tty for them to take effect. The variables are removed when com2tty exits,
|
|
357
|
+
including when the console window is closed: the WSL helper is reaped together
|
|
358
|
+
with the host process rather than left running, and it is given the chance to
|
|
359
|
+
run its own cleanup before it is forced down. If a session is nonetheless killed
|
|
360
|
+
before it can clean up, the next run removes the stale block on startup.
|
|
322
361
|
|
|
323
362
|
Second, com2tty detects the connected board type from its USB vendor identifier
|
|
324
363
|
and performs the appropriate hardware reset on the Windows side. For ESP32-class
|
|
@@ -341,10 +380,13 @@ inside WSL. When PlatformIO calls `picotool` to flash a `.uf2` image, a wrapper
|
|
|
341
380
|
transfers the image back to the Windows host over a relay that listens on
|
|
342
381
|
`127.0.0.1:<rfc2217-port + 1>`. The host then triggers BOOTSEL mode, locates the
|
|
343
382
|
board's mass-storage drive, verifies the transferred image against an MD5
|
|
344
|
-
checksum, and writes the image to the drive.
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
383
|
+
checksum, and writes the image to the drive. Subcommands that carry no firmware
|
|
384
|
+
image, such as `picotool info`, `picotool reboot`, and `picotool help`, are
|
|
385
|
+
forwarded to the real binary unchanged, so non-flashing uses of `picotool`
|
|
386
|
+
continue to work while the interception is active. The original `picotool` is
|
|
387
|
+
restored when com2tty exits; if a session is killed before it can restore it, the
|
|
388
|
+
next run detects and reverses the leftover interception on startup, so PlatformIO
|
|
389
|
+
uploads are not left broken.
|
|
348
390
|
|
|
349
391
|
These mechanisms operate without any additional flags. The startup banner reports
|
|
350
392
|
the detected board type, the RFC 2217 port, the UF2 relay port, and the board's
|
|
@@ -359,7 +401,15 @@ these ports during an upload. Run com2tty only on hosts you trust, and choose a
|
|
|
359
401
|
non-default `--rfc2217-port` if another local service needs the default port. To
|
|
360
402
|
reclaim a port left open by a previous com2tty session, the helper only
|
|
361
403
|
terminates processes whose command line identifies them as a com2tty bridge; an
|
|
362
|
-
unrelated service occupying the port is never killed.
|
|
404
|
+
unrelated service occupying the port is never killed. A *running* com2tty
|
|
405
|
+
session is never disturbed: before it touches any shared state, a new session
|
|
406
|
+
checks whether its RFC 2217 and UF2 relay ports are already bound and, if so,
|
|
407
|
+
refuses to start rather than overwrite the first session's shell configuration
|
|
408
|
+
or steal its serial endpoint. As a further guard, the WSL helper refuses to
|
|
409
|
+
replace a tty symlink that already points at another live session's pseudo
|
|
410
|
+
terminal. Two sessions can run concurrently by giving the second one a different
|
|
411
|
+
`--rfc2217-port` and `--wsl-tty`; each session removes only its own block from
|
|
412
|
+
the shell startup files when it exits.
|
|
363
413
|
|
|
364
414
|
### Gamepad mode
|
|
365
415
|
|
|
@@ -385,7 +435,10 @@ privileges at run time.
|
|
|
385
435
|
#### Default tier: the /tmp event stream
|
|
386
436
|
|
|
387
437
|
The default tier writes the evdev event stream to a FIFO under `/tmp`, by default
|
|
388
|
-
`/tmp/com2pad0`, and requires no privileged setup.
|
|
438
|
+
`/tmp/com2pad0`, and requires no privileged setup. This FIFO and its
|
|
439
|
+
force-feedback companion (described below) are created with owner-only
|
|
440
|
+
permissions, so another local user on the WSL instance cannot read the input
|
|
441
|
+
stream or inject events into it.
|
|
389
442
|
|
|
390
443
|
```cmd
|
|
391
444
|
com2tty --gamepad
|
|
@@ -396,6 +449,24 @@ interprets them using the device profile below. This tier is suited to programs
|
|
|
396
449
|
that read the stream directly. Standard applications and game engines that
|
|
397
450
|
enumerate `/dev/input` devices do not read a FIFO and require the uinput tier.
|
|
398
451
|
|
|
452
|
+
Force feedback is available in this tier through a second FIFO created at
|
|
453
|
+
`<path>.ff` (by default `/tmp/com2pad0.ff`): the consumer writes 6-byte rumble
|
|
454
|
+
frames into it — the bytes `0xFB 0xFE` followed by the strong (left,
|
|
455
|
+
low-frequency) and weak (right, high-frequency) motor magnitudes as two
|
|
456
|
+
little-endian unsigned 16-bit values — and com2tty forwards them to the
|
|
457
|
+
physical controller's motors, exactly as the uinput tier does for kernel
|
|
458
|
+
`FF_RUMBLE` effects.
|
|
459
|
+
|
|
460
|
+
To forward several controllers at once, pass several slots:
|
|
461
|
+
|
|
462
|
+
```cmd
|
|
463
|
+
com2tty --gamepad --pad-index 0 1
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
Each slot gets its own WSL helper and its own endpoint (`/tmp/com2pad0`,
|
|
467
|
+
`/tmp/com2pad1`, ...); in the uinput tier each helper creates its own
|
|
468
|
+
`/dev/input` device, as if several physical controllers were attached.
|
|
469
|
+
|
|
399
470
|
#### Opt-in tier: a real device through /dev/uinput
|
|
400
471
|
|
|
401
472
|
The opt-in tier creates a real system-wide device under `/dev/input` so that SDL2
|
|
@@ -472,8 +543,9 @@ feedback. When a game or emulator inside WSL plays a rumble effect, the
|
|
|
472
543
|
effect's magnitudes travel back through the bridge to the Windows host, which
|
|
473
544
|
drives the physical controller's motors through `XInputSetState`. The strong
|
|
474
545
|
(left, low-frequency) and weak (right, high-frequency) motors map directly to
|
|
475
|
-
their XInput counterparts.
|
|
476
|
-
|
|
546
|
+
their XInput counterparts. In the `/tmp` stream tier the same reverse channel
|
|
547
|
+
is reached by writing rumble frames into the `<path>.ff` FIFO, as described
|
|
548
|
+
in [the default tier](#default-tier-the-tmp-event-stream).
|
|
477
549
|
|
|
478
550
|
The forwarded signal matches a real controller at the level of these event codes,
|
|
479
551
|
ranges, and resolutions, but it is not bit-for-bit identical to a controller
|
|
@@ -487,48 +559,68 @@ available. These differences are inherent to the approach.
|
|
|
487
559
|
|
|
488
560
|
The package is organised around a host process on Windows and a helper process
|
|
489
561
|
inside WSL connected by the standard input and output streams of the helper.
|
|
562
|
+
The code under `src/com2tty/` is split by where it runs: `cli/` is the
|
|
563
|
+
command-line layer, `core/` holds the dependency-free definitions both sides
|
|
564
|
+
share, `windows/` runs on the Windows interpreter, and `wsl/` runs on the
|
|
565
|
+
Linux interpreter inside WSL.
|
|
490
566
|
|
|
491
|
-
`cli
|
|
492
|
-
tokens) and dispatches to an entry function in `
|
|
567
|
+
`cli/` parses the command line (after `cli/profiles.py` expands any `@profile`
|
|
568
|
+
tokens) and dispatches to an entry function in `windows/`: `run_bridge` in
|
|
493
569
|
serial mode, `run_multi_bridge` when several ports are given, and
|
|
494
|
-
`run_gamepad_bridge` in gamepad mode. `discovery.py` implements
|
|
495
|
-
`
|
|
496
|
-
`__init__.py` holds the package
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
`
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
570
|
+
`run_gamepad_bridge` in gamepad mode. `windows/discovery.py` implements
|
|
571
|
+
`--list` and `windows/doctor.py` implements `--doctor`. `__main__.py` and the
|
|
572
|
+
console entry point both call `cli.main`, and `__init__.py` holds the package
|
|
573
|
+
version.
|
|
574
|
+
|
|
575
|
+
`core/` defines the contracts both interpreters rely on: `core/protocol.py`
|
|
576
|
+
holds the `[CONTROL]` message catalogue and the dispatcher the host routes
|
|
577
|
+
stderr lines through, `core/frames.py` the binary gamepad frame codecs,
|
|
578
|
+
`core/boards.py` the USB VID classification with the reset timing data, and
|
|
579
|
+
`core/constants.py` the shared paths, ports, and marker strings.
|
|
580
|
+
|
|
581
|
+
`windows/` is the Windows side. In serial mode `run_bridge` in
|
|
582
|
+
`windows/bridge_app.py` opens the COM port with `pyserial`, spawns the WSL
|
|
583
|
+
helper with `wsl python3 -u bridge.py` (through `windows/wsl_process.py`), and
|
|
584
|
+
runs three threads: one relays bytes from the COM port to the helper's
|
|
585
|
+
standard input, one relays bytes from the helper's standard output to the COM
|
|
586
|
+
port, and one reads the helper's standard error. The standard error stream
|
|
587
|
+
carries a line-oriented control protocol whose messages are prefixed with
|
|
588
|
+
`[CONTROL]`; the handlers in `windows/control_handler.py` drive dynamic
|
|
589
|
+
serial-setting changes, the RFC 2217 session lifecycle, and the UF2 upload
|
|
590
|
+
sequence (including the routine that writes a transferred UF2 image to the
|
|
591
|
+
correct Windows drive, via `windows/uf2_flash.py`). The hot-plug reconnect
|
|
592
|
+
logic lives in `windows/serial_host.py` and the board reset sequences in
|
|
593
|
+
`windows/board_reset.py`. The raw OS-level interventions -- AutoPlay
|
|
594
|
+
suppression, Explorer window closing, `WM_DEVICECHANGE` wake-ups, and console
|
|
595
|
+
VT mode -- are isolated under `windows/os_hacks/`.
|
|
596
|
+
|
|
597
|
+
`wsl/` is the WSL side, restricted to the Python standard library.
|
|
598
|
+
`wsl/serial_app.py` (launched through the `bridge.py` shim at the package
|
|
599
|
+
root) creates a pseudo terminal with `openpty` via `wsl/pty_manager.py`,
|
|
600
|
+
symlinks the requested path to the pseudo-terminal slave, falling back to
|
|
601
|
+
`/tmp` if the requested path is not writable, and runs a `select` loop that
|
|
602
|
+
relays data between the helper's standard input and output and the
|
|
603
|
+
pseudo-terminal master. It also starts the RFC 2217 forwarder and UF2 relay
|
|
604
|
+
threads (`wsl/servers/`), writes the PlatformIO environment variables into
|
|
605
|
+
`~/.bashrc` (`wsl/integrations/shell_env.py`), and installs the `picotool`
|
|
606
|
+
interceptor (`wsl/integrations/picotool.py`).
|
|
607
|
+
`windows/rfc2217_redirector.py` provides the redirector that implements the
|
|
608
|
+
RFC 2217 protocol for the forwarder.
|
|
609
|
+
|
|
610
|
+
The gamepad path reuses the same spawn-and-pipe transport.
|
|
611
|
+
`windows/gamepad_host.py` is the Windows side: it polls an XInput controller
|
|
612
|
+
slot through `ctypes` (preferring the `XInputGetStateEx` export so the Guide
|
|
613
|
+
button is visible) and packs each state snapshot into a fixed 16-byte frame,
|
|
614
|
+
sending a frame only when the state changes. `wsl/gamepad_app.py` (launched
|
|
615
|
+
through the `pad_bridge.py` shim) is the WSL side: it parses the frames,
|
|
616
|
+
translates them into evdev events, and writes them to one of the two sinks in
|
|
617
|
+
`wsl/evdev_sink.py`. The default sink writes to a `/tmp` FIFO, and the opt-in
|
|
618
|
+
sink creates a real device through `/dev/uinput` using raw `ioctl` calls. Both
|
|
619
|
+
sinks share the same event-encoding code, so the byte stream they produce is
|
|
620
|
+
identical. In the uinput sink the helper also services the kernel's
|
|
621
|
+
force-feedback upload handshake and streams played rumble effects back over
|
|
622
|
+
its stdout, where the host applies them to the physical controller with
|
|
623
|
+
`XInputSetState`.
|
|
532
624
|
|
|
533
625
|
For a detailed account of the control protocol, the board reset sequences, the
|
|
534
626
|
reconnection model, the binary frame formats, and the known hardware-unverified
|
|
@@ -588,6 +680,11 @@ step, is documented in [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
|
588
680
|
|
|
589
681
|
## Troubleshooting
|
|
590
682
|
|
|
683
|
+
Run `com2tty --doctor` first: it probes the whole environment (WSL, the
|
|
684
|
+
selected distribution's `python3`, drive automounting, `fuser`, the RFC 2217
|
|
685
|
+
and UF2 relay TCP ports, leftovers from crashed sessions, `/dev/uinput`
|
|
686
|
+
access, and the XInput DLL) and prints one actionable line per check.
|
|
687
|
+
|
|
591
688
|
At startup com2tty verifies the WSL environment and reports a specific error if
|
|
592
689
|
a prerequisite is missing. The checks and their remedies are:
|
|
593
690
|
|
|
@@ -609,6 +706,11 @@ package; on minimal distributions install it with `sudo apt install psmisc`, or
|
|
|
609
706
|
select a different port with `--rfc2217-port` (the UF2 relay always uses that
|
|
610
707
|
port plus one).
|
|
611
708
|
|
|
709
|
+
If com2tty instead refuses to start with a message that a port is already in
|
|
710
|
+
use, a second com2tty session is already bound to that port. Give the new session
|
|
711
|
+
a different `--rfc2217-port`, and a different `--wsl-tty`, to run the two
|
|
712
|
+
concurrently.
|
|
713
|
+
|
|
612
714
|
The serial-mode environment variables are written to `~/.bashrc`, to `~/.zshrc`
|
|
613
715
|
when zsh is detected or a `~/.zshrc` file exists, and to
|
|
614
716
|
`~/.config/fish/conf.d/com2tty.fish` when fish is detected. Users of other
|