Skip to content

fix(vxi11): resolve Core port via TCP/111 portmapper GETPORT (#20)#55

Merged
ShortArrow merged 2 commits into
mainfrom
fix/vxi11-portmapper
Jun 29, 2026
Merged

fix(vxi11): resolve Core port via TCP/111 portmapper GETPORT (#20)#55
ShortArrow merged 2 commits into
mainfrom
fix/vxi11-portmapper

Conversation

@ShortArrow

@ShortArrow ShortArrow commented Jun 29, 2026

Copy link
Copy Markdown
Owner

Problem

Physical VXI-11 instruments publish their portmapper and assign the VXI-11 Device Core to a dynamic port. The client backend connected straight to a fixed port (1024), which is closed on such instruments, so visa query against a ::inst0::INSTR resource timed out.

Change

OpenAsync now performs a real PMAPPROC_GETPORT over UDP/111 to resolve the Core port, then connects there. When no portmapper answers within a short probe window — e.g. ivi-cli's own gateway, which co-locates portmapper + Core on a single bind port and does not answer GETPORT on 111 — it falls back to the fixed port, preserving the existing gateway pairing (backward compatible).

Transport note: a real Kikusui PWR801L was used to validate. Its portmapper accepts TCP on 111 but answers GETPORT only over UDP/111 — so the resolver uses unicast UDP (matching the broadcast scanner). The shared GETPORT request/reply codec is extracted into Vxi11Portmapper and reused by Vxi11BroadcastScanner (removing duplicated RPC code).

Field note: on the PWR801L the portmapper reports Core port 20001, but that port is not reachable on the unit under test (TCP 5025/4880 for SOCKET/HiSLIP are), so VXI-11 *IDN? cannot complete against this particular device — a device-side limitation, independent of the client. The portmapper round-trip itself is verified by unit tests and a standalone probe.

Tests (TDD)

New Vxi11PortmapperResolveTests:

  • ResolveCorePortAsync returns the Core port from a UDP GETPORT reply.
  • ResolveCorePortAsync throws when the portmapper is unreachable (refused/timeout).
  • OpenAsync connects to the portmapper-resolved port (fallback intentionally dead).
  • OpenAsync falls back to the fixed port when the portmapper is unreachable.

Existing Vxi11BackendTests / Vxi11EndToEndPairingTests stay green (fixed-port constructor → portmapper disabled).

Full suite green (Category!=Integration), csharpier + analyzers clean.

Docs

ADR 0029 §2 updated in-place: the "portmapper-at-111 deferred to v2" item is now marked shipped (UDP/111).

Closes #20.

Physical VXI-11 instruments (e.g. Kikusui PWR801L) publish their
portmapper on TCP/111 and assign the Device Core to a dynamic port.
The client previously connected straight to a fixed port (1024) and
timed out against such instruments.

OpenAsync now issues a real PMAPPROC_GETPORT over TCP/111 to learn the
Core port, falling back to the fixed port when no portmapper answers
(e.g. ivi-cli's co-located gateway, which does not listen on 111).

The GETPORT request/reply codec is extracted to a shared Vxi11Portmapper
helper, reused by the broadcast scanner to remove duplication.
Verified against a real Kikusui PWR801L: its portmapper accepts TCP
connections on 111 but never answers GETPORT there — it replies only
over UDP/111. Switch ResolveCorePortAsync to a unicast UDP datagram
(matching the broadcast scanner's transport) and parse the reply with
the shared TryParseGetportReply. Unicast UDP is routed normally, so
this also works across subnets.
@ShortArrow ShortArrow merged commit 3563bbb into main Jun 29, 2026
5 of 6 checks passed
@ShortArrow ShortArrow deleted the fix/vxi11-portmapper branch June 29, 2026 06:46
@ShortArrow ShortArrow mentioned this pull request Jun 29, 2026
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.

VXI-11 client backend: real portmapper (UDP/111) round-trip

1 participant