Skip to content

Fix deadlocks, TCP stability, and ASCOM registration issues#69

Open
EricSchubert wants to merge 1 commit intoOpenAstroTech:masterfrom
EricSchubert:bugfix/deadlocks-tcp-ascom-stability
Open

Fix deadlocks, TCP stability, and ASCOM registration issues#69
EricSchubert wants to merge 1 commit intoOpenAstroTech:masterfrom
EricSchubert:bugfix/deadlocks-tcp-ascom-stability

Conversation

@EricSchubert
Copy link

Please see attached markdown files for all detailed changes and fixes in this PR.
BUILD_FIXES.md
CHANGES.md

Summary

This PR fixes 11 bugs identified while using the ASCOM driver with N.I.N.A. and OATControl
on a BTT SKR Pico v1.0 running firmware V1.13.9. The issues range from permanent UI/thread
deadlocks to silent communication failures and COM registration problems.

Full details for each fix (problem, change, and rationale) are documented in CHANGES.md
and BUILD_FIXES.md, which I'll attach as comments below.


Runtime Bug Fixes (OATCommunications, ASCOM.Driver)

Fix 1 — Slew() deadlock (OatmealTelescopeCommandHandlers.cs)
doneEvent.Set() was missing from the :MS# callback — await doneEvent.WaitAsync() hung
forever. Added doneEvent.Set() inside the :MS# callback.

Fix 2 — SetLocation() deadlock (OatmealTelescopeCommandHandlers.cs)
A premature await doneEvent.WaitAsync() appeared before any commands were sent, making all
location/time commands unreachable. Removed the spurious wait.

Fix 3 — RefreshMountState() deadlock (OatmealTelescopeCommandHandlers.cs)
doneEvent.Set() was inside if (status.Success) — a comm failure meant it was never called
and the method hung. Moved Set() outside the if block.

Fix 4 — TCP timeout reported as success (TcpCommunicationHandler.cs)
A catch block substituted "0#" as a fake response, which CommandResponse treated as
success. Replaced with string.Empty and an explicit succeeded flag.

Fix 5 — DoubleFullResponse only reads once over TCP (TcpCommunicationHandler.cs)
DoubleFullResponse was grouped with single-response types — only one read happened, leaving
the second #-terminated reply in the buffer and corrupting the next command's response.
Split into its own case block with two reads, matching SerialCommunicationHandler.

Fix 6 — TCP stream leak on write failure (TcpCommunicationHandler.cs)
An early return on write failure bypassed stream.Close(), leaking the socket handle.
Added stream.Close() before the early return.

Fix 7 — TCP reconnects on every command (TcpCommunicationHandler.cs)
stream.Close() after every command closed the underlying socket, so _client.Connected was
always false and every command triggered a full TCP handshake. Added a _stream field to
keep the connection open; reconnects only when _stream == null.

Fix 8 — SendMessage() silently returns empty when disconnected (SharedResources.cs)
When SharedSerial.Connected was false, SendMessage() returned string.Empty
indistinguishable from a legitimate empty response. Now throws ASCOM.NotConnectedException.

Fix 9 — PollUntilZero() hangs forever on mount stall (Driver.cs)
No timeout — a stalled mount or repeated "255" error returns from CommandString() caused
FindHome(), Park(), and synchronous slews to block the driver thread permanently. Added
maxAttempts = 120 (2-minute cap); throws TimeoutException on expiry.

Fix 10 — LocalServer32 registry path not quoted (LocalServer.cs)
Application.ExecutablePath was written without quotes. Paths with spaces caused
CO_E_SERVER_EXEC_FAILURE at COM activation. Wrapped in double quotes.

Fix 11 — SetupDialog() invisible when called from N.I.N.A. (Driver.cs)
COM-started processes are denied foreground privilege by Windows. SetupDialogForm opened but
was silently hidden behind other windows. Added SetForegroundWindow() on the main form
handle before ShowDialog() to regain foreground status.


Build / Project Fixes (OpenAstroTracker.csproj)

Build Fix 4 — Wrong NuGet HintPaths for ASCOM assemblies
HintPaths pointed to packages\ (inside the project dir) instead of ..\packages\ (the
actual NuGet restore location). ASCOM DLLs were not CopyLocal'd to bin/Debug/, causing
ReflectionTypeLoadException at COM activation on a clean build.

Build Fix 5 — Debug build targets wrong CPU architecture
Debug PropertyGroup had <PlatformTarget>AnyCPU</PlatformTarget>. On 64-bit Windows this
wrote the COM registration to the 64-bit registry hive; 32-bit ASCOM clients (N.I.N.A., SGP,
etc.) look in Wow6432Node and couldn't find the driver. Changed to x86 to match the
Release configuration and the official installer.

Note for maintainers: The Release configuration already uses x86 and is unaffected.
If your release pipeline generates Debug as an intermediate artifact, or if you prefer a
different mechanism for ensuring 32-bit registration in Debug builds, please review this
change. The core requirement is that LocalServer32 lands in Wow6432Node.


Test Environment

  • Hardware: BTT SKR Pico v1.0, firmware V1.13.9
  • ASCOM Platform 6.6, ASCOM driver v6.6.6.8
  • N.I.N.A. 3.x (ASCOM telescope client)
  • OATControl (WPF desktop app, WiFi + serial)
  • Windows 11

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant