A feature that is not tested is a feature that does not work. Not "probably works", not "should work" — does not work, until something has demonstrated otherwise.
That is not cynicism, it is the lesson I have watched play out too many times in my engineering life. Something gets pushed out without being tested, in the honest and entirely sincere belief that it is fine, because the author knows how it is supposed to behave and it did behave that way the one time they tried it. And then it comes back — weeks or months later, in a context nobody thought about, as somebody else's problem. I wanted GPIBEE to be done differently.
The honest caveat is that 100 % coverage is practically impossible. There is always another combination of instrument, host, VISA, timing and sequence that no test exercises. Since you cannot test everything, what matters is testing along different axes rather than deeper along one:
- Positive testing — does the intended operation do what it is supposed to do
- Negative testing — does the wrong input, the invalid handle, the out-of-range parameter, the call at the wrong moment get rejected the way the standard says, instead of being quietly accepted or taking the device down
- Diversity of tools — the same operation exercised through different VISA implementations, different operating systems, different languages and frameworks, because each of them uses a different subset of the protocol and they disagree about the edges
- Real instruments — hardware from five decades, which is the only way to find out what the specifications left open
And testing is not a static thing you finish. Coverage has to grow over time: every issue found, every question from a user, every case a new instrument reveals becomes another test that runs from then on. A test suite that stops growing is a test suite that is slowly falling behind the product it is supposed to be checking.
GPIBEE is a fairly complex piece of hardware and firmware — three host interfaces, several protocol modes, a full GPIB controller, a web server and an internal SCPI system, all in one small box. But the part that decides whether it is any good is not the implementation. Roughly as much time goes into testing as into writing the firmware in the first place. This article is about what that testing actually looks like.
The instrument side: five decades on one bus
GPIB is a bus from 1975 that is still in daily use, and "IEEE-488 compliant" has meant subtly different things in every decade since. Instruments differ in timing, in how strictly they follow the handshake, in what they do with EOI and termination characters, in how they behave when addressed while already talking. No specification covers what real hardware on a real bench actually does.
The one advantage here is history. USBGPIB, the open-source USB-to-GPIB adapter this project grew out of, has been maintained for over seven years. Every awkward instrument, every timing fix, every "works with everything except this one 1980s analyser" report from that project is a known case. Those learnings went into GPIBEE's design, and the instruments that were difficult back then were tested against GPIBEE deliberately — the awkward ones are the interesting ones.
A concrete result of that testing: after the GPIB transfer speed was raised significantly, some setups stopped being happy. The cause was T1, the talker settling time — the delay between putting a byte on the DIO lines and asserting DAV to say it is stable. Going faster means shortening T1, and a bus does not always tolerate that. Older instruments react more slowly to a byte appearing on the lines, and a bus carrying many instruments with a lot of cable simply takes longer to settle electrically. Neither is a defect; both need more time than a short, modern, lightly-loaded bus does.
So T1 became adjustable rather than fixed —
SYSTem:COMMunicate:GPIB:T1TIME, 350 to 2000 ns, 500 ns by
default, stored in non-volatile memory and applied immediately. Other GPIB adapters
expose the same knob for the same reason. If an instrument or an installation turns
out to be marginal at full speed, raising T1 slows the handshake back down until it
is reliable, and only for the bus that needs it. That is exactly the kind of thing no
specification tells you and no simulation finds — only real instruments on a
real bench do.
The hardware side
It is easy to read all of the above and conclude that GPIBEE is a software project. The firmware is a very significant part of it, but a major amount of the total effort went into the hardware — enough to produce several board revisions before the electrical behaviour was where it needed to be.
That work is measured, not argued about. What was characterised on the bench:
- DC characteristics of the I/O — drive levels, thresholds, what the lines actually sit at rather than what the datasheet promises
- AC parametrics — edges, propagation, the real shape of a handshake rather than its idealised timing diagram
- Drive strength and its effect on those edges, which is the same knob that decides how fast the bus can be pushed
- Maximum resistive and capacitive load the bus can carry and still meet timing — the measurement that has to hold if the promise of 15 instruments on one bus is going to mean anything
Power over Ethernet, and what "compliant" means
The other hardware story is PoE, which cost a redesign. The first design worked well — on passive injectors. Put it on a proper 802.3af switch and it caused trouble, and the switches it upset were precisely the ones that follow the standard correctly.
The reason is that a lot of PoE equipment in the wild only mimics the standard. A passive injector simply puts voltage on the pairs and hopes for the best. A compliant source does not: it probes for a powered device first, detecting and classifying it before any power is applied, and it keeps checking afterwards. A design that is happy with the naive case can still fail that negotiation — and testing against the forgiving equipment first is exactly how you end up not knowing.
PoE brought a second, entirely different problem in the first design: EMC. A PoE front end is a switching converter sitting a few centimetres from the Ethernet magnetics, and in that layout it disturbed the very interface it was powering — far enough to affect Ethernet data transfer stability. That is an unpleasant class of fault, because it does not present itself as "the PoE circuit is noisy"; it presents itself as a network that is occasionally not quite right. Finding it, and then laying the board out so that it stopped happening, was one of the more instructive parts of the hardware work.
After the redesign, both of those are settled: GPIBEE works on standard-compliant 802.3af PoE switches as well as on passive injectors, and the Ethernet interface behaves the same whether the power arrives over the network cable or over USB.
The software side: three suites
Bus behaviour is only half of it. The other half is the protocol stacks on top, and those are tested in software, automatically, against real hardware:
- a regression suite for USBTMC, the oldest of the three — USBTMC testing is well-trodden ground from the USBGPIB years
- a regression suite for VXI-11, exercising the behaviour a user actually depends on: locking, timeouts, concurrent access, GPIB primitives, the internal SCPI parameters
- a VXI-11 standards compliance suite, checking the firmware against the text of the specification rather than against my expectations
The third one is the interesting story.
Writing a VXI-11 compliance suite from scratch
VXI-11 was the part of this project I was least comfortable with from the start. USBTMC I knew. VXI-11 was new to me, and unlike USBTMC there is no test suite for it — it is a common, widely implemented standard, and as far as I could find, nobody publishes a conformance tester for it. So I wrote one. It currently holds 122 checks mapped to the rules, recommendations and observations of the VXI-11 and VXI-11.2 specifications.
The first run of the finished suite passed about 70 % of its checks — 69.4 %, to be exact. On firmware I had already been testing for months.
What the compliance suite found were things like: the exact error code a call must
return when a link identifier is invalid rather than merely stale; what has to happen
to locks, the abort channel and the interrupt channel when a core connection is
dropped without a clean teardown; which operations are and are not affected by
device_abort; how a read has to report the bytes it did transfer when it
ends in a timeout. Individually these are small. Together they are the difference
between "works with my VISA" and "implements the standard".
The hardest area by far was SRQ — service requests over the interrupt channel. Getting the delivery path right is straightforward; getting it right without race conditions, when a service request can arrive while a client is enabling or disabling interrupts, tearing down its channel, or closing the connection underneath it, took several iterations. Other boundary cases were similar in character: rare, timing-dependent, and invisible until something tests for them deliberately.
The chart at the top of this article is that process, one point per run of the suite: 69.4 % at the start, 100 % of applicable checks now. The full report is below — it lists every check, what rule it verifies, and the protocol log it produced.
The compliance report
This is the report of the most recent run, exactly as the suite produces it. One
check is skipped rather than failed: Pass Control (the
device_docmd 0x020004 operation) is not implemented at present, so the
suite marks it as not applicable and excludes it from the pass rate. Everything else
that ran, passed.
🟢 122 check(s) passed · ⚪ 1 skipped
🟢 Every check that ran passed.
Pass rate 100.0% — 122 of 122 applicable checks (🔴 0.0% failed, 🟡 0.0% warned; 1 skipped checks excluded).
| Target | 192.168.3.2 |
| Device | gpib0,4 |
| Device under test | XYPHROLABS,GPIBEE,LJPAT,V1.5.2608231401 |
| Version tested | V1.5.2608231401 |
| Core channel port | 1024 |
| Abort channel port | 34568 |
| Checks run | 123 |
| Result | Count | Share | Meaning |
|---|---|---|---|
| 🟢 PASS | 122 | 99.2% | the rule is respected |
| 🔴 FAIL | 0 | 0.0% | a MUST rule is violated |
| 🟡 WARN | 0 | 0.0% | a SHOULD rule is bent, or an unusual but legal choice |
| ⚪ SKIP | 1 | 0.8% | not applicable in this configuration |
| 🟠 ERROR | 0 | 0.0% | the check itself could not complete |
| Total | 123 |
By suite
| Suite | 🟢 | 🔴 | 🟡 | ⚪ | 🟠 | ⛔ | Pass rate |
|---|---|---|---|---|---|---|---|
Abort channel (abt) |
11 | 0 | 0 | 0 | 0 | 0 | 100% |
cmd (cmd) |
18 | 0 | 0 | 1 | 0 | 0 | 100% |
gen (gen) |
6 | 0 | 0 | 0 | 0 | 0 | 100% |
Interrupt channel (int) |
16 | 0 | 0 | 0 | 0 | 0 | 100% |
Read / write (io) |
14 | 0 | 0 | 0 | 0 | 0 | 100% |
Locking (lck) |
13 | 0 | 0 | 0 | 0 | 0 | 100% |
Link lifecycle (lnk) |
16 | 0 | 0 | 0 | 0 | 0 | 100% |
Port mapper (pm) |
9 | 0 | 0 | 0 | 0 | 0 | 100% |
Robustness (rob) |
6 | 0 | 0 | 0 | 0 | 0 | 100% |
RPC layer (rpc) |
13 | 0 | 0 | 0 | 0 | 0 | 100% |
Passing
🟢 122 of 123 checks passed (99.2%). Ids below are shown without the common VXI11-TS- prefix.
- Abort channel (11): EXT ABT-001, EXT ABT-005, REC B.2.1, RULE B.2.5, RULE B.2.8, RULE B.6.107, RULE B.6.108, RULE B.6.109, RULE B.6.12, RULE B.6.2-a, RULE B.6.81
- cmd (18): EXT CMD-001, EXT CMD-002, RULE B.1.3, RULE B.4, RULE B.4.10, RULE B.4.12, RULE B.4.17, RULE B.5, RULE B.5.1, RULE B.5.10, RULE B.5.11, RULE B.5.2, RULE B.5.3, RULE B.5.4, RULE B.5.5, RULE B.5.6, RULE B.5.7, RULE B.5.8
- gen (6): EXT GEN-001, RULE B.6.39, RULE B.6.47, RULE B.6.55, RULE B.6.63, RULE B.6.98
- Interrupt channel (16): EXT INT-005, RULE B.2.10, RULE B.4.5-b, RULE B.6.111, RULE B.6.82, RULE B.6.83, RULE B.6.85, RULE B.6.86, RULE B.6.87, RULE B.6.88, RULE B.6.89, RULE B.6.90, RULE B.6.92, RULE B.6.93-a, RULE B.6.93-b, RULE B.6.95
- Read / write (14): EXT IO-005, EXT IO-010, EXT IO-011, EXT IO-012, OBS B.6.6, RULE B.6.13, RULE B.6.16, RULE B.6.23-a, RULE B.6.23-b, RULE B.6.23-c, RULE B.6.23-d, RULE B.6.27, RULE B.6.3-d, RULE B.6.31
- Locking (13): EXT LCK-007, RULE B.4.3, RULE B.6.17, RULE B.6.18, RULE B.6.71, RULE B.6.72, RULE B.6.74-a, RULE B.6.74-b, RULE B.6.75, RULE B.6.76, RULE B.6.80-a, RULE B.6.80-b, RULE B.6.9
- Link lifecycle (16): EXT LNK-003, EXT LNK-006, EXT LNK-007, EXT LNK-011, REC B.6.1, RULE B.2.7, RULE B.4.5-a, RULE B.6.10-a, RULE B.6.10-b, RULE B.6.15, RULE B.6.3-a, RULE B.6.3-b, RULE B.6.3-c, RULE B.6.4, RULE B.6.6, RULE B.6.7
- Port mapper (9): EXT PM-003, EXT PM-004, EXT PM-005, EXT PM-008, EXT PM-009, RULE B.1.4, RULE B.2.1-a, RULE B.2.1-b, RULE B.6.1-a
- Robustness (6): EXT ROB-003, EXT ROB-005, EXT ROB-006, REC B.4.2, RULE B.4.5-c, RULE B.6.5
- RPC layer (13): EXT RPC-004, EXT RPC-005, EXT RPC-006, EXT RPC-007, EXT RPC-008, EXT RPC-009, EXT RPC-011, RULE B.1.5, RULE B.2.2, RULE B.2.3, RULE B.6.1-b, RULE B.6.2-b, RULE C.1
Coverage of the standards
137 of the 187 catalogued statements are exercised by this run, 50 are not checkable from a client on the network, 0 are not covered yet.
VXI-11 TCP/IP Instrument Protocol Specification, Revision 1.0
| Statement | Says | Checked by | |
|---|---|---|---|
| 🟢 | RULE B.1.2 |
Hosts support the Internet Protocol Suite; TCP is the transport layer. | VXI11-RULE-B.1.5 |
| 🟢 | RULE B.1.3 |
Messages are ONC/RPC compatible and use XDR at the presentation layer. | VXI11-RULE-C.1, VXI11-EXT-RPC-004, VXI11-EXT-RPC-005, VXI11-EXT-RPC-006, VXI11-EXT-RPC-007, VXI11-EXT-RPC-008, VXI11-EXT-RPC-009 |
| 🟢 | RULE B.1.4 |
A host acting as a network instrument server supports a port mapper. | VXI11-RULE-B.1.4 |
| 🟢 | RULE B.1.5 |
Hosts implement all the messages and data types of B.5 and B.6. | VXI11-RULE-B.1.5 |
| 🟢 | REC B.2.1 |
The abort channel should respond in a timely manner. | VXI11-REC-B.2.1 |
| 🟢 | RULE B.2.1 |
The server implements all three channels, established by the sequences of B.2.4 and B.2.5. | VXI11-RULE-B.2.1-a, VXI11-RULE-B.2.1-b |
| 🟢 | RULE B.2.2 |
Core channel RPCs are processed in the order received, and the reply is not sent until the action is complete. | VXI11-RULE-B.2.2 |
| 🟢 | RULE B.2.3 |
Other protocols carried on the core channel under different program numbers do not interfere with the instrument protocol. | VXI11-RULE-B.2.3 |
| 🟢 | RULE B.2.4 |
RPCs performing I/O to the same device or interface are serialized. | VXI11-REC-B.4.2 |
| 🟢 | RULE B.2.5 |
The abort channel carries only the device_abort RPC. | VXI11-RULE-B.2.5 |
| 🟢 | RULE B.2.6 |
The interrupt channel is established by the server to the client after the client issues create_intr_chan. | VXI11-RULE-B.6.82 |
| 🟢 | RULE B.2.7 |
The same abort port number is returned in every create_link reply sent on one core channel. | VXI11-RULE-B.2.7 |
| 🟢 | RULE B.2.8 |
The server accepts and processes core channel RPCs even if an abort channel is never established. | VXI11-RULE-B.2.8 |
| 🟢 | RULE B.2.9 |
create_intr_chan when a channel already exists does not create a new one; one interrupt channel serves all links on the connection. | VXI11-RULE-B.6.89 |
| 🟢 | RULE B.2.10 |
destroy_intr_chan makes the server destroy its RPC client and tear the interrupt channel down. | VXI11-RULE-B.2.10 |
| 🟢 | RULE B.3.1 |
Interrupt messages use the given RPCL: device_intr_srq, procedure 30, program 0x0607B1, version 1, returning void. | VXI11-RULE-B.6.111 |
| 🟢 | REC B.4.2 |
An instrument's host should route at least two links to any device. | VXI11-REC-B.4.2 |
| 🟢 | RULE B.4.2 |
The server allows at least io_timeout milliseconds for an I/O operation to complete. | VXI11-RULE-B.6.27 |
| 🟢 | REC B.4.3 |
The server should detect a downed network or crashed client and clean up as for a closed connection. | VXI11-RULE-B.4.5-c |
| 🟢 | RULE B.4.3 |
With a non-zero lock_timeout the server waits at least that long for a lock; with lock_timeout zero it does not wait at all and returns an error immediately. | VXI11-RULE-B.4.3 |
| 🟢 | RULE B.4.5 |
When the core channel is reset or closed, the server releases all resources of every link on that connection -- locks, abort channel and interrupt channel included. | VXI11-RULE-B.4.5-a, VXI11-RULE-B.4.5-b, VXI11-RULE-B.4.5-c |
| 🟢 | PERM B.6.1 |
The server may support a UDP interrupt channel. | VXI11-RULE-B.6.86 |
| 🟢 | REC B.6.1 |
A server should maintain at least two links on one connection. | VXI11-REC-B.6.1 |
| 🟢 | RULE B.6.1 |
The program and version numbers of Table B.3 are used: core 395183/1, abort 395184/1, interrupt 395185/1. | VXI11-RULE-B.1.5, VXI11-RULE-B.6.1-a, VXI11-RULE-B.6.1-b |
| 🟢 | PERM B.6.2 |
A server may support none, some or all cmd values in device_docmd. | VXI11-RULE-B.6.98 |
| 🟢 | RULE B.6.2 |
Only the defined procedure numbers are used with those programs; all others are reserved. | VXI11-RULE-B.6.2-a, VXI11-RULE-B.6.2-b |
| 🟢 | RULE B.6.3 |
create_link locks the device if lockDevice is set, returns a lid unique among active links, a maxRecvSize of at least 1024, the abort port, and error 0. | VXI11-RULE-B.6.3-a, VXI11-RULE-B.6.3-b, VXI11-RULE-B.6.3-c, VXI11-RULE-B.6.3-d |
| 🟢 | RULE B.6.4 |
The server does not alter its function based on clientId. | VXI11-RULE-B.6.4 |
| 🟢 | OBS B.6.5 |
A client sending more than maxRecvSize bytes splits the transfer over several device_write calls. | VXI11-RULE-B.6.3-d |
| 🟢 | RULE B.6.5 |
create_link with no link available terminates with error 9. | VXI11-RULE-B.6.5 |
| 🟢 | OBS B.6.6 |
device_write with a zero-length data parameter performs no device action. | VXI11-OBS-B.6.6 |
| 🟢 | RULE B.6.6 |
create_link ignores locks when lockDevice is false. | VXI11-RULE-B.6.6 |
| 🟢 | RULE B.6.7 |
With lockDevice true and the lock still held after lock_timeout, create_link creates no link and returns error 11. | VXI11-RULE-B.6.7 |
| 🟢 | RULE B.6.9 |
destroy_link deactivates the lid, frees the lock this link holds, disables this link's interrupts, and returns error 0. | VXI11-RULE-B.6.9, VXI11-RULE-B.6.10-b |
| 🟢 | RULE B.6.10 |
destroy_link with a lid matching no active link returns error 4. | VXI11-RULE-B.6.10-a, VXI11-RULE-B.6.10-b |
| 🟢 | RULE B.6.12 |
destroy_link is not affected by device_abort. | VXI11-RULE-B.6.12 |
| 🟢 | RULE B.6.13 |
device_write transfers data to the device, returns the number of bytes accepted in size, and returns error 0. | VXI11-RULE-B.6.13 |
| 🟢 | RULE B.6.14 |
With the end flag set, an END indicator accompanies the last byte. | VXI11-EXT-IO-010 |
| 🟢 | RULE B.6.15 |
device_write with an unmatched lid returns error 4. | VXI11-RULE-B.6.15 |
| 🟢 | RULE B.6.16 |
device_write with data longer than maxRecvSize transfers nothing and returns error 5. | VXI11-RULE-B.6.16 |
| 🟢 | RULE B.6.17 |
device_write against a lock held elsewhere blocks if waitlock is set, otherwise returns error 11. | VXI11-RULE-B.6.17 |
| 🟢 | OBS B.6.18 |
The server blocks when another link holds the lock, but not merely because another link is doing I/O. | VXI11-EXT-LCK-007 |
| 🟢 | RULE B.6.18 |
device_write returns error 11 if the lock is still held after lock_timeout. | VXI11-RULE-B.6.18 |
| 🟢 | OBS B.6.21 |
Service request enable states are per link and survive interrupt channel creation and destruction. | VXI11-RULE-B.6.93-b |
| 🟢 | RULE B.6.23 |
device_read transfers bytes until END (sets END), requestSize reached (sets REQCNT, also used when requestSize is zero), termChar matched with termchrset (sets CHR), or the response buffer is full (sets no bit); then returns error 0. | VXI11-RULE-B.6.23-a, VXI11-RULE-B.6.23-b, VXI11-RULE-B.6.23-c, VXI11-RULE-B.6.23-d |
| 🟢 | RULE B.6.24 |
device_read with an unmatched lid returns error 4. | VXI11-RULE-B.6.15 |
| 🟢 | RULE B.6.25 |
device_read against a lock held elsewhere blocks if waitlock is set, otherwise returns error 11. | VXI11-RULE-B.6.17 |
| 🟢 | RULE B.6.26 |
device_read returns error 11 with no data if the lock is still held after lock_timeout. | VXI11-RULE-B.6.18 |
| 🟢 | RULE B.6.27 |
device_read returns error 15 with reason zero and the bytes transferred so far if the transfer exceeds io_timeout. | VXI11-RULE-B.6.27 |
| 🟢 | RULE B.6.29 |
device_read returns error 23 if device_abort is called during it. | VXI11-RULE-B.6.107 |
| 🟢 | RULE B.6.30 |
device_read returns the bytes transferred in data even when it ends in a timeout or an abort. | VXI11-RULE-B.6.27 |
| 🟢 | RULE B.6.31 |
device_readstb returns the device's status byte and error 0. | VXI11-RULE-B.6.31 |
| 🟢 | RULE B.6.32 |
device_readstb returns error 8 if no status byte can be returned. | VXI11-RULE-B.6.31 |
| 🟢 | RULE B.6.33 |
device_readstb with an unmatched lid returns error 4. | VXI11-RULE-B.6.15 |
| 🟢 | RULE B.6.34 |
device_readstb against a lock held elsewhere blocks if waitlock is set, otherwise returns error 11. | VXI11-RULE-B.6.17 |
| 🟢 | RULE B.6.35 |
device_readstb returns error 11 if the lock is still held after lock_timeout. | VXI11-RULE-B.6.18 |
| 🟢 | RULE B.6.39 |
device_trigger sends a trigger to the device and returns error 0. | VXI11-RULE-B.6.39 |
| 🟢 | RULE B.6.40 |
device_trigger returns error 8 if the device has no trigger and the server can detect that. | VXI11-RULE-B.6.39 |
| 🟢 | RULE B.6.41 |
device_trigger with an unmatched lid returns error 4. | VXI11-RULE-B.6.15 |
| 🟢 | RULE B.6.42 |
device_trigger against a lock held elsewhere blocks if waitlock is set, otherwise returns error 11. | VXI11-RULE-B.6.17 |
| 🟢 | RULE B.6.43 |
device_trigger returns error 11 if the lock is still held after lock_timeout. | VXI11-RULE-B.6.18 |
| 🟢 | RULE B.6.47 |
device_clear clears the device and returns error 0. | VXI11-RULE-B.6.47 |
| 🟢 | RULE B.6.48 |
device_clear returns error 8 if the device has no clear and the server can detect that. | VXI11-RULE-B.6.47 |
| 🟢 | RULE B.6.49 |
device_clear with an unmatched lid returns error 4. | VXI11-RULE-B.6.15 |
| 🟢 | RULE B.6.50 |
device_clear against a lock held elsewhere blocks if waitlock is set, otherwise returns error 11. | VXI11-RULE-B.6.17 |
| 🟢 | RULE B.6.51 |
device_clear returns error 11 if the lock is still held after lock_timeout. | VXI11-RULE-B.6.18 |
| 🟢 | RULE B.6.55 |
device_remote places the device in the remote state, error 0. | VXI11-RULE-B.6.55 |
| 🟢 | RULE B.6.56 |
device_remote returns error 8 if the device has no remote state and the server can detect that. | VXI11-RULE-B.6.55 |
| 🟢 | RULE B.6.57 |
device_remote with an unmatched lid returns error 4. | VXI11-RULE-B.6.15 |
| 🟢 | RULE B.6.58 |
device_remote against a lock held elsewhere blocks if waitlock is set, otherwise returns error 11. | VXI11-RULE-B.6.17 |
| 🟢 | RULE B.6.59 |
device_remote returns error 11 if the lock is still held after lock_timeout. | VXI11-RULE-B.6.18 |
| 🟢 | RULE B.6.63 |
device_local places the device in the local state, error 0. | VXI11-RULE-B.6.63 |
| 🟢 | RULE B.6.64 |
device_local returns error 8 if the device has no local state and the server can detect that. | VXI11-RULE-B.6.63 |
| 🟢 | RULE B.6.65 |
device_local with an unmatched lid returns error 4. | VXI11-RULE-B.6.15 |
| 🟢 | RULE B.6.66 |
device_local against a lock held elsewhere blocks if waitlock is set, otherwise returns error 11. | VXI11-RULE-B.6.17 |
| 🟢 | RULE B.6.67 |
device_local returns error 11 if the lock is still held after lock_timeout. | VXI11-RULE-B.6.18 |
| 🟢 | RULE B.6.71 |
device_lock acquires the device's lock and returns error 0. | VXI11-RULE-B.6.71 |
| 🟢 | RULE B.6.72 |
device_lock from the link that already holds the lock returns error 11. | VXI11-RULE-B.6.72 |
| 🟢 | RULE B.6.73 |
device_lock with an unmatched lid returns error 4 before any attempt to acquire the lock. | VXI11-RULE-B.6.15 |
| 🟢 | RULE B.6.74 |
device_lock against a lock held elsewhere blocks if waitlock is set, otherwise returns error 11. | VXI11-RULE-B.6.74-a, VXI11-RULE-B.6.74-b |
| 🟢 | RULE B.6.75 |
device_lock returns error 11 if the lock is still held after lock_timeout. | VXI11-RULE-B.6.75 |
| 🟢 | RULE B.6.76 |
device_lock returns error 23 when aborted. | VXI11-RULE-B.6.76 |
| 🟢 | RULE B.6.77 |
Locks are tied to the core connection; a broken connection releases all of that connection's locks. | VXI11-RULE-B.4.5-a |
| 🟢 | RULE B.6.78 |
device_unlock releases the lock and returns error 0. | VXI11-RULE-B.6.71 |
| 🟢 | RULE B.6.79 |
device_unlock with an unmatched lid returns error 4. | VXI11-RULE-B.6.15 |
| 🟢 | RULE B.6.80 |
device_unlock from a link that does not hold the lock returns error 12. | VXI11-RULE-B.6.80-a, VXI11-RULE-B.6.80-b |
| 🟢 | RULE B.6.81 |
device_unlock is not affected by device_abort. | VXI11-RULE-B.6.81 |
| 🟢 | RULE B.6.82 |
create_intr_chan establishes an interrupt channel to hostAddr and hostPort with the given program, version and family; error 0. | VXI11-RULE-B.6.82 |
| 🟢 | RULE B.6.83 |
create_intr_chan returns error 6 if the channel cannot be established. | VXI11-RULE-B.6.83 |
| 🟢 | RULE B.6.84 |
The server supports a TCP interrupt channel. | VXI11-RULE-B.6.82 |
| 🟢 | RULE B.6.85 |
create_intr_chan returns error 8 for a progFamily other than DEVICE_TCP or DEVICE_UDP. | VXI11-RULE-B.6.85 |
| 🟢 | RULE B.6.86 |
create_intr_chan returns error 8 for a protocol the server does not support, such as UDP. | VXI11-RULE-B.6.86 |
| 🟢 | RULE B.6.87 |
create_intr_chan returns error 8 if progNum is not 395185. | VXI11-RULE-B.6.87 |
| 🟢 | RULE B.6.88 |
create_intr_chan returns error 8 if progVers is not 1. | VXI11-RULE-B.6.88 |
| 🟢 | RULE B.6.89 |
create_intr_chan when a channel already exists performs no operation and returns error 29. | VXI11-RULE-B.6.89 |
| 🟢 | RULE B.6.90 |
The server operates correctly even with no interrupt channel. | VXI11-RULE-B.6.90 |
| 🟢 | RULE B.6.91 |
destroy_intr_chan closes the interrupt channel and returns 0. | VXI11-RULE-B.6.82 |
| 🟢 | RULE B.6.92 |
destroy_intr_chan with no channel open returns error 6. | VXI11-RULE-B.6.92 |
| 🟢 | RULE B.6.93 |
device_enable_srq enables or disables interrupts for this link and stores the handle unmodified; error 0. | VXI11-RULE-B.6.93-a, VXI11-RULE-B.6.93-b |
| 🟢 | RULE B.6.94 |
device_enable_srq with an unmatched lid returns error 4. | VXI11-RULE-B.6.15 |
| 🟢 | RULE B.6.95 |
device_enable_srq behaves the same whether or not the link holds the lock. | VXI11-RULE-B.6.95 |
| 🟢 | RULE B.6.97 |
device_docmd with an unmatched lid returns error 4. | VXI11-RULE-B.6.15 |
| 🟢 | RULE B.6.98 |
device_docmd returns error 8 for a cmd value it does not support. | VXI11-RULE-B.6.98 |
| 🟢 | RULE B.6.99 |
The server byte-swaps data_in and data_out when its architecture differs from the client's, per network_order. | VXI11.2-RULE-B.5.4 |
| 🟢 | RULE B.6.100 |
Byte swapping follows datasize: 1 none, 2 word, 4 longword, 8 eight-byte boundaries. | VXI11.2-RULE-B.5.4 |
| 🟢 | RULE B.6.101 |
device_docmd against a lock held elsewhere blocks if waitlock is set, otherwise returns error 11. | VXI11-RULE-B.6.17 |
| 🟢 | RULE B.6.102 |
device_docmd returns error 11 if the lock is still held after lock_timeout. | VXI11-RULE-B.6.18 |
| 🟢 | RULE B.6.106 |
device_abort initiates termination of any in-progress core channel RPC on the link except destroy_link, device_enable_srq and device_unlock, and returns error 0. | VXI11-RULE-B.6.12, VXI11-RULE-B.6.81, VXI11-RULE-B.6.107 |
| 🟢 | RULE B.6.107 |
After replying to device_abort the server replies to the aborted call with error 23. | VXI11-RULE-B.6.107 |
| 🟢 | RULE B.6.108 |
device_abort with an unmatched lid returns error 4. | VXI11-RULE-B.6.108 |
| 🟢 | RULE B.6.109 |
device_abort is not affected by locking. | VXI11-RULE-B.6.109 |
| 🟢 | RULE B.6.110 |
device_intr_srq is sent only when interrupts are enabled for the link and an interrupt channel exists. | VXI11-RULE-B.6.111 |
| 🟢 | RULE B.6.111 |
device_intr_srq carries back the handle exactly as received in device_enable_srq. | VXI11-RULE-B.6.111 |
| 🟢 | RULE C.1 |
The host implements the RPCL constructs of section C, including the full result structures of each reply. | VXI11-RULE-C.1 |
VXI-11.2 TCP/IP-IEEE 488.1 Interface Specification, Draft 0.3
| Statement | Says | Checked by | |
|---|---|---|---|
| 🟢 | RULE B.1.1 |
The device string has the form |
VXI11.2-RULE-B.1.3 |
| 🟢 | RULE B.1.2 |
The interface name gpib0 is the first or only IEEE 488.1 interface; further interfaces are gpibN. | VXI11.2-RULE-B.1.3 |
| 🟢 | RULE B.1.3 |
A device string containing only the interface name is a link to the interface. | VXI11.2-RULE-B.1.3 |
| 🟢 | RULE B.1.4 |
A device string with an address is a link to the device at that address. | VXI11-RULE-B.6.3-a |
| 🟢 | REC B.2 |
Link and server counts should follow available resources, not arbitrary limits. | VXI11.2-RULE-B.4 |
| 🟢 | RULE B.2.1 |
The interface device supports the network instrument protocol and executes all of its RPCs. | VXI11-RULE-B.1.5 |
| 🟢 | RULE B.3 |
The RPC reply is not sent until the associated action is complete. | VXI11-RULE-B.2.2 |
| 🟢 | RULE B.4 |
At least 14 concurrent links per network instrument server are supported. | VXI11.2-RULE-B.4 |
| 🟢 | RULE B.4.10 |
device_remote on an interface link returns error 8. | VXI11.2-RULE-B.4.10 |
| 🟢 | RULE B.4.12 |
device_local on an interface link returns error 8. | VXI11.2-RULE-B.4.12 |
| 🟢 | RULE B.4.17 |
device_readstb on an interface link returns error 8. | VXI11.2-RULE-B.4.17 |
| 🟢 | RULE B.5 |
After power-on the interface device sets REN true. | VXI11.2-RULE-B.5 |
| 🟢 | RULE B.5.1 |
Only the cmd values of Table B.1 are supported; any other cmd returns immediately with error 8. | VXI11.2-RULE-B.5.1 |
| 🟢 | RULE B.5.2 |
device_docmd on a link associated with a device performs no action and returns error 8. | VXI11.2-RULE-B.5.2 |
| 🟢 | RULE B.5.3 |
A data_in_len or datasize conflicting with Table B.1 gives error 5 and no action; datasize X accepts any value. | VXI11.2-RULE-B.5.3, VXI11.2-EXT-CMD-002 |
| 🟢 | RULE B.5.4 |
data_in and data_out hold unsigned integers of datasize bytes. | VXI11.2-RULE-B.5.4, VXI11.2-RULE-B.5.6 |
| 🟢 | RULE B.5.5 |
Send Command (0x020000) executes SEND COMMAND with the bytes in data_in and returns them unchanged in data_out. | VXI11.2-RULE-B.5.5 |
| 🟢 | RULE B.5.6 |
Bus Status (0x020001) returns a two-byte data_out whose value depends on the subcode in data_in per Table B.2. | VXI11.2-RULE-B.5.6 |
| 🟢 | RULE B.5.7 |
ATN Control (0x020002) sets ATN true for a non-zero data_in and false for zero; data_out repeats data_in. | VXI11.2-RULE-B.5.7 |
| 🟢 | RULE B.5.8 |
REN Control (0x020003) sets the sre message true for a non-zero data_in and false for zero; data_out repeats data_in. | VXI11.2-RULE-B.5.8 |
| ⚪ | RULE B.5.9 |
Pass Control (0x020004) executes PASS CONTROL with the talk address data_in | 0x80; data_out repeats data_in. | VXI11.2-RULE-B.5.9 |
| 🟢 | RULE B.5.10 |
Bus Address (0x02000A) sets the interface address when data_in is 0 to 30, otherwise returns error 5; data_out repeats data_in. | VXI11.2-RULE-B.5.10 |
| 🟢 | RULE B.5.11 |
IFC Control (0x020010) executes SEND IFC and returns an empty data_out. | VXI11.2-RULE-B.5.11 |
Not checkable from the network
VXI-11 RULE B.1.1— Hosts support Ethernet/802.3 and 10BASE-T with an RJ-45 connector.
physical layer -- inspect the hardware, not the protocolVXI-11 RULE B.4.1— A server supports links to every device reachable by any other server in the host.
needs two servers in the same host and knowledge of its device listVXI-11 RULE B.4.4— The client provides a local timeout for unresponsive servers.
a rule for the client, which this suite implements itselfVXI-11 RULE B.6.8— create_link has no effect on the state of any device.
requires observing device state through a second, independent pathVXI-11 RULE B.6.11— destroy_link has no effect on the state of any device.
requires observing device state through a second, independent pathVXI-11 RULE B.6.19— device_write returns error 15 if the whole transfer has not completed within io_timeout.
needs a device that stalls a write; only device_read can be stalled reliably from the network side (RULE B.6.27)VXI-11 RULE B.6.20— device_write returns error 23 if device_abort is called during it.
these operations finish too quickly to be aborted deterministically; the abort path is checked on device_read and device_lock (RULE B.6.107, RULE B.6.76)VXI-11 RULE B.6.21— device_write returns the bytes transferred in size even when it ends in a timeout or an abort.
requires a write that times out or is aborted mid-transferVXI-11 RULE B.6.22— device_write returns error 17 on a device specific I/O error.
needs an induced device I/O error (pull the bus cable)VXI-11 RULE B.6.28— device_read returns error 17 on a device specific I/O error.
needs an induced device I/O errorVXI-11 RULE B.6.36— device_readstb returns error 15 if not complete within io_timeout.
needs an operation that stalls; see RULE B.6.27VXI-11 RULE B.6.37— device_readstb returns error 17 on a device specific I/O error.
needs an induced device I/O errorVXI-11 RULE B.6.38— device_readstb returns error 23 when aborted.
see RULE B.6.20VXI-11 RULE B.6.44— device_trigger returns error 15 if not complete within io_timeout.
needs an operation that stalls; see RULE B.6.27VXI-11 RULE B.6.45— device_trigger returns error 17 on a device specific I/O error.
needs an induced device I/O errorVXI-11 RULE B.6.46— device_trigger returns error 23 when aborted.
see RULE B.6.20VXI-11 RULE B.6.52— device_clear returns error 15 if not complete within io_timeout.
needs an operation that stalls; see RULE B.6.27VXI-11 RULE B.6.53— device_clear returns error 17 on a device specific I/O error.
needs an induced device I/O errorVXI-11 RULE B.6.54— device_clear returns error 23 when aborted.
see RULE B.6.20VXI-11 RULE B.6.60— device_remote returns error 15 if not complete within io_timeout.
needs an operation that stalls; see RULE B.6.27VXI-11 RULE B.6.61— device_remote returns error 17 on a device specific I/O error.
needs an induced device I/O errorVXI-11 RULE B.6.62— device_remote returns error 23 when aborted.
see RULE B.6.20VXI-11 RULE B.6.68— device_local returns error 15 if not complete within io_timeout.
needs an operation that stalls; see RULE B.6.27VXI-11 RULE B.6.69— device_local returns error 17 on a device specific I/O error.
needs an induced device I/O errorVXI-11 RULE B.6.70— device_local returns error 23 when aborted.
see RULE B.6.20VXI-11 RULE B.6.96— device_docmd executes the operation of cmd, byte-swapping as needed, returns data_out and error 0.
needs a cmd value the server supports; those are defined by the companion documents (VXI-11.1 to VXI-11.3)VXI-11 RULE B.6.103— device_docmd returns error 15 if cmd cannot complete within io_timeout.
needs a supported cmd that stalls; see RULE B.6.27VXI-11 RULE B.6.104— device_docmd returns error 17 on a device specific I/O error.
needs an induced device I/O errorVXI-11 RULE B.6.105— device_docmd returns error 23 when aborted.
see RULE B.6.20VXI-11.2 RULE B.1— The interface device complies with IEEE 488.1 and with the controller requirements of IEEE 488.2 section 15.
IEEE 488.1 / 488.2 controller conformance -- a bus analyser question, not a network oneVXI-11.2 RULE B.2— The interface device contains a Talker subset T5-T8 and a Listener subset L3 or L4.
Talker and Listener subsets are visible only on the busVXI-11.2 RULE B.2.2— Ethernet/802.3 and 802.3/10BASE-T with an RJ-45 connector are supported.
physical layer -- inspect the hardwareVXI-11.2 RULE B.3.1— create_link and destroy_link are implemented entirely within the interface device.
an internal structure requirement; its effects are covered by the VXI-11 link rulesVXI-11.2 RULE B.3.2— create_intr_chan and destroy_intr_chan are implemented entirely within the interface device.
internal structure; effects covered by the VXI-11 interrupt channel rulesVXI-11.2 RULE B.3.3— device_lock and device_unlock are implemented entirely within the interface device.
internal structure; effects covered by the VXI-11 locking rulesVXI-11.2 RULE B.3.4— device_abort is implemented entirely within the interface device and aborts active operations on the link.
internal structure; effects covered by VXI-11 RULE B.6.107VXI-11.2 RULE B.4.1— device_write on a device link uses the SEND control sequence with the link's listen address; END on the last byte when the end flag is set.
the SEND control sequence is only observable with a bus analyserVXI-11.2 RULE B.4.2— device_write on an interface link uses SEND DATA BYTES.
bus-level sequence; needs an analyserVXI-11.2 RULE B.4.3— device_read on a device link uses the RECEIVE control sequence with the link's talk address.
bus-level sequence; needs an analyserVXI-11.2 RULE B.4.4— device_read on an interface link uses RECEIVE RESPONSE MESSAGE.
bus-level sequence; needs an analyserVXI-11.2 RULE B.4.5— device_clear on a device link executes DEVICE CLEAR for the selected device.
bus-level sequence; needs an analyserVXI-11.2 RULE B.4.6— device_clear on an interface link executes DEVICE CLEAR for all devices.
bus-level sequence; needs an analyserVXI-11.2 RULE B.4.7— device_trigger on a device link executes TRIGGER for the selected device.
bus-level sequence; needs an analyserVXI-11.2 RULE B.4.8— device_trigger on an interface link executes TRIGGER for all addressed devices.
bus-level sequence; needs an analyserVXI-11.2 RULE B.4.9— device_remote on a device link executes SET RWLS.
bus-level sequence; needs an analyserVXI-11.2 RULE B.4.11— device_local on a device link executes ENABLE LOCAL CONTROLS for the selected device.
bus-level sequence; needs an analyserVXI-11.2 RULE B.4.13— device_intr_srq is sent when SRQ goes false to true and the channel exists with service requests enabled.
needs a controlled SRQ transition on the bus; the delivery path is covered by VXI-11 RULE B.6.111VXI-11.2 RULE B.4.14— device_intr_srq is sent when service requests are enabled while SRQ is already true.
needs SRQ already asserted before enabling; same path as RULE B.4.13VXI-11.2 RULE B.4.15— device_intr_srq is not sent under any other circumstances.
proving a negative over all circumstances is not possible from the network sideVXI-11.2 RULE B.4.16— device_readstb on a device link executes READ STATUS BYTE and returns the status byte with the RQS message.
the READ STATUS BYTE sequence is only observable with a bus analyser; the result is checked by VXI-11 RULE B.6.31
Summary
| ID | Title | Severity | Verifies | |
|---|---|---|---|---|
| 🟢 | VXI11.2-RULE-B.1.3 | A device string with no address links to the interface | MUST | VXI-11.2 RULE B.1.3, VXI-11.2 RULE B.1.2, VXI-11.2 RULE B.1.1 |
| 🟢 | VXI11-RULE-B.1.4 | Portmapper answers on TCP/111 | MUST | RULE B.1.4 |
| 🟢 | VXI11-RULE-B.1.5 | Every procedure defined by the standard is implemented | MUST | RULE B.1.5, RULE B.6.1, RULE B.1.2, VXI-11.2 RULE B.2.1 |
| 🟢 | VXI11-RULE-B.2.1-a | The advertised core port accepts TCP connections | MUST | RULE B.2.1 |
| 🟢 | VXI11-RULE-B.2.1-b | The advertised abort port accepts TCP connections | MUST | RULE B.2.1 |
| 🟢 | VXI11-RULE-B.2.2 | Two calls pipelined on one connection are both answered | SHOULD | RULE B.2.2, VXI-11.2 RULE B.3 |
| 🟢 | VXI11-RULE-B.2.3 | An unknown program number gives PROG_UNAVAIL | MUST | RULE B.2.3 |
| 🟢 | VXI11-RULE-B.2.5 | The abort channel rejects unknown procedures | SHOULD | RULE B.2.5 |
| 🟢 | VXI11-RULE-B.2.7 | Every create_link on one core channel returns the same abort port | MUST | RULE B.2.7 |
| 🟢 | VXI11-RULE-B.2.8 | The core channel works when no abort channel is ever established | MUST | RULE B.2.8 |
| 🟢 | VXI11-RULE-B.2.10 | The interrupt channel is closed when destroy_intr_chan is called | SHOULD | RULE B.2.10 |
| 🟢 | VXI11.2-RULE-B.4 | At least 14 concurrent links per server | MUST | VXI-11.2 RULE B.4, VXI-11.2 REC B.2 |
| 🟢 | VXI11-RULE-B.4.3 | lock_timeout=0 with waitlock does not block | SHOULD | RULE B.4.3 |
| 🟢 | VXI11-RULE-B.4.5-a | Closing the core connection releases the link's resources | MUST | RULE B.4.5, RULE B.6.77 |
| 🟢 | VXI11-RULE-B.4.5-b | The interrupt channel is torn down when the core connection drops | SHOULD | RULE B.4.5 |
| 🟢 | VXI11-RULE-B.4.5-c | Links are reclaimed when clients disappear without destroy_link | MUST | RULE B.4.5, REC B.4.3 |
| 🟢 | VXI11.2-RULE-B.4.10 | device_remote on an interface link returns error 8 | MUST | VXI-11.2 RULE B.4.10 |
| 🟢 | VXI11.2-RULE-B.4.12 | device_local on an interface link returns error 8 | MUST | VXI-11.2 RULE B.4.12 |
| 🟢 | VXI11.2-RULE-B.4.17 | device_readstb on an interface link returns error 8 | MUST | VXI-11.2 RULE B.4.17 |
| 🟢 | VXI11.2-RULE-B.5 | REN is true after power-on | SHOULD | VXI-11.2 RULE B.5 |
| 🟢 | VXI11.2-RULE-B.5.1 | Only the cmd values of Table B.1 are accepted | MUST | VXI-11.2 RULE B.5.1 |
| 🟢 | VXI11.2-RULE-B.5.2 | device_docmd on a device link returns error 8 | MUST | VXI-11.2 RULE B.5.2 |
| 🟢 | VXI11.2-RULE-B.5.3 | A wrong data_in length or datasize gives error 5 | MUST | VXI-11.2 RULE B.5.3 |
| 🟢 | VXI11.2-RULE-B.5.4 | data_in and data_out are byte-swapped when asked | MUST | VXI-11.2 RULE B.5.4, RULE B.6.99, RULE B.6.100 |
| 🟢 | VXI11.2-RULE-B.5.5 | Send Command transfers command bytes and echoes them | MUST | VXI-11.2 RULE B.5.5 |
| 🟢 | VXI11.2-RULE-B.5.6 | Bus Status returns two bytes for every subcode | MUST | VXI-11.2 RULE B.5.6, VXI-11.2 RULE B.5.4 |
| 🟢 | VXI11.2-RULE-B.5.7 | ATN Control sets and clears ATN | MUST | VXI-11.2 RULE B.5.7 |
| 🟢 | VXI11.2-RULE-B.5.8 | REN Control sets REN and echoes data_in | MUST | VXI-11.2 RULE B.5.8 |
| ⚪ | VXI11.2-RULE-B.5.9 | Pass Control hands control to the given address | MUST | VXI-11.2 RULE B.5.9 |
| 🟢 | VXI11.2-RULE-B.5.10 | Bus Address accepts 0-30 and rejects anything else | MUST | VXI-11.2 RULE B.5.10 |
| 🟢 | VXI11.2-RULE-B.5.11 | IFC Control sends IFC and returns no data | MUST | VXI-11.2 RULE B.5.11 |
| 🟢 | VXI11-RULE-B.6.1-a | DEVICE_CORE (0x0607AF) v1 is registered | MUST | RULE B.6.1 |
| 🟢 | VXI11-RULE-B.6.1-b | A wrong program version gives PROG_MISMATCH with a version range | MUST | RULE B.6.1 |
| 🟢 | VXI11-RULE-B.6.2-a | The core channel does not implement the abort procedure | INFO | RULE B.6.2 |
| 🟢 | VXI11-RULE-B.6.2-b | An unimplemented procedure gives PROC_UNAVAIL | MUST | RULE B.6.2 |
| 🟢 | VXI11-RULE-B.6.3-a | create_link on the configured device succeeds | MUST | RULE B.6.3, VXI-11.2 RULE B.1.4 |
| 🟢 | VXI11-RULE-B.6.3-b | maxRecvSize is at least 1024 bytes | MUST | RULE B.6.3 |
| 🟢 | VXI11-RULE-B.6.3-c | Link identifiers are unique across connections | MUST | RULE B.6.3 |
| 🟢 | VXI11-RULE-B.6.3-d | A write of exactly maxRecvSize bytes is accepted | MUST | RULE B.6.3, OBS B.6.5 |
| 🟢 | VXI11-RULE-B.6.4 | clientId is echoed back or ignored, never rejected | INFO | RULE B.6.4 |
| 🟢 | VXI11-RULE-B.6.5 | Running out of links is reported as error 9, not a crash | MUST | RULE B.6.5 |
| 🟢 | VXI11-RULE-B.6.6 | create_link with lockDevice=false ignores an existing lock | MUST | RULE B.6.6 |
| 🟢 | VXI11-RULE-B.6.7 | create_link with lockDevice=true acquires the lock | MUST | RULE B.6.7 |
| 🟢 | VXI11-RULE-B.6.9 | destroy_link releases the lock the link held | MUST | RULE B.6.9 |
| 🟢 | VXI11-RULE-B.6.10-a | destroy_link with an unknown link identifier gives error 4 | MUST | RULE B.6.10 |
| 🟢 | VXI11-RULE-B.6.10-b | destroy_link twice on the same link gives error 4 | MUST | RULE B.6.10, RULE B.6.9 |
| 🟢 | VXI11-RULE-B.6.12 | device_abort does not affect destroy_link | MUST | RULE B.6.12, RULE B.6.106 |
| 🟢 | VXI11-RULE-B.6.13 | device_write reports the number of bytes it accepted | MUST | RULE B.6.13 |
| 🟢 | VXI11-RULE-B.6.15 | Every operation on a destroyed link gives error 4 | MUST | RULE B.6.15, RULE B.6.24, RULE B.6.33, RULE B.6.41, RULE B.6.49, RULE B.6.57, RULE B.6.65, RULE B.6.73, RULE B.6.79, RULE B.6.94, RULE B.6.97 |
| 🟢 | VXI11-RULE-B.6.16 | device_write beyond maxRecvSize transfers nothing and returns error 5 | MUST | RULE B.6.16 |
| 🟢 | VXI11-RULE-B.6.17 | An operation from another link is refused while the device is locked | MUST | RULE B.6.17, RULE B.6.25, RULE B.6.34, RULE B.6.42, RULE B.6.50, RULE B.6.58, RULE B.6.66, RULE B.6.101 |
| 🟢 | VXI11-RULE-B.6.18 | waitlock on an operation waits instead of failing immediately | SHOULD | RULE B.6.18, RULE B.6.26, RULE B.6.35, RULE B.6.43, RULE B.6.51, RULE B.6.59, RULE B.6.67, RULE B.6.102 |
| 🟢 | VXI11-RULE-B.6.23-a | A write/read round trip returns instrument data with END set | MUST | RULE B.6.23 |
| 🟢 | VXI11-RULE-B.6.23-b | device_read never returns more than requestSize bytes | MUST | RULE B.6.23 |
| 🟢 | VXI11-RULE-B.6.23-c | termChar terminates a read and sets the CHR reason bit | SHOULD | RULE B.6.23 |
| 🟢 | VXI11-RULE-B.6.23-d | device_read with requestSize zero terminates immediately with REQCNT | MUST | RULE B.6.23 |
| 🟢 | VXI11-RULE-B.6.27 | device_read honours io_timeout and returns error 15 | MUST | RULE B.6.27, RULE B.4.2, RULE B.6.30 |
| 🟢 | VXI11-RULE-B.6.31 | device_readstb returns a status byte in range | MUST | RULE B.6.31, RULE B.6.32 |
| 🟢 | VXI11-RULE-B.6.39 | device_trigger sends a trigger or reports error 8 | MUST | RULE B.6.39, RULE B.6.40 |
| 🟢 | VXI11-RULE-B.6.47 | device_clear clears the device or reports error 8 | MUST | RULE B.6.47, RULE B.6.48 |
| 🟢 | VXI11-RULE-B.6.55 | device_remote sets the remote state or reports error 8 | MUST | RULE B.6.55, RULE B.6.56 |
| 🟢 | VXI11-RULE-B.6.63 | device_local sets the local state or reports error 8 | MUST | RULE B.6.63, RULE B.6.64 |
| 🟢 | VXI11-RULE-B.6.71 | device_lock succeeds on an unlocked device | MUST | RULE B.6.71, RULE B.6.78 |
| 🟢 | VXI11-RULE-B.6.72 | device_lock from the link that already holds the lock gives error 11 | MUST | RULE B.6.72 |
| 🟢 | VXI11-RULE-B.6.74-a | A second link cannot lock a device that is already locked | MUST | RULE B.6.74 |
| 🟢 | VXI11-RULE-B.6.74-b | waitlock acquires the lock as soon as the holder releases it | MUST | RULE B.6.74 |
| 🟢 | VXI11-RULE-B.6.75 | waitlock makes device_lock block for lock_timeout, then error 11 | MUST | RULE B.6.75 |
| 🟢 | VXI11-RULE-B.6.76 | device_abort terminates a blocked device_lock with error 23 | MUST | RULE B.6.76 |
| 🟢 | VXI11-RULE-B.6.80-a | device_unlock without holding the lock gives error 12 | MUST | RULE B.6.80 |
| 🟢 | VXI11-RULE-B.6.80-b | device_unlock from a link that does not own the lock gives error 12 | MUST | RULE B.6.80 |
| 🟢 | VXI11-RULE-B.6.81 | device_abort does not affect device_unlock | MUST | RULE B.6.81, RULE B.6.106 |
| 🟢 | VXI11-RULE-B.6.82 | create_intr_chan opens a channel back to the client | MUST | RULE B.6.82, RULE B.6.84, RULE B.2.6, RULE B.6.91 |
| 🟢 | VXI11-RULE-B.6.83 | create_intr_chan with an unreachable address returns error 6 | MUST | RULE B.6.83 |
| 🟢 | VXI11-RULE-B.6.85 | create_intr_chan with an undefined progFamily returns error 8 | MUST | RULE B.6.85 |
| 🟢 | VXI11-RULE-B.6.86 | create_intr_chan with progFamily=UDP is handled | INFO | RULE B.6.86, PERM B.6.1 |
| 🟢 | VXI11-RULE-B.6.87 | create_intr_chan with a progNum other than 395185 returns error 8 | MUST | RULE B.6.87 |
| 🟢 | VXI11-RULE-B.6.88 | create_intr_chan with a progVers other than 1 returns error 8 | MUST | RULE B.6.88 |
| 🟢 | VXI11-RULE-B.6.89 | create_intr_chan twice gives error 29 | MUST | RULE B.6.89, RULE B.2.9 |
| 🟢 | VXI11-RULE-B.6.90 | The server works normally when no interrupt channel is established | MUST | RULE B.6.90 |
| 🟢 | VXI11-RULE-B.6.92 | destroy_intr_chan without a channel gives error 6 | MUST | RULE B.6.92 |
| 🟢 | VXI11-RULE-B.6.93-a | device_enable_srq accepts a 40-byte handle | MUST | RULE B.6.93 |
| 🟢 | VXI11-RULE-B.6.93-b | device_enable_srq works when no interrupt channel is open | MUST | RULE B.6.93, OBS B.6.21 |
| 🟢 | VXI11-RULE-B.6.95 | device_enable_srq behaves the same whether or not the link is locked | MUST | RULE B.6.95 |
| 🟢 | VXI11-RULE-B.6.98 | device_docmd rejects an unsupported cmd with error 8 | MUST | RULE B.6.98, PERM B.6.2 |
| 🟢 | VXI11-RULE-B.6.107 | device_abort terminates an in-progress read with error 23 | MUST | RULE B.6.107, RULE B.6.106, RULE B.6.29 |
| 🟢 | VXI11-RULE-B.6.108 | device_abort with an unknown link identifier gives error 4 | MUST | RULE B.6.108 |
| 🟢 | VXI11-RULE-B.6.109 | device_abort works while another link holds the lock | MUST | RULE B.6.109 |
| 🟢 | VXI11-RULE-B.6.111 | An SRQ is delivered with the exact handle that was registered | MUST | RULE B.6.111, RULE B.6.110, RULE B.3.1 |
| 🟢 | VXI11-RULE-C.1 | Error replies still carry the complete result structure | MUST | RULE C.1, RULE B.1.3 |
| 🟢 | VXI11-REC-B.2.1 | The abort channel is reachable while the core channel is busy | MUST | REC B.2.1 |
| 🟢 | VXI11-REC-B.4.2 | Several links can be used concurrently without cross-talk | MUST | REC B.4.2, RULE B.2.4 |
| 🟢 | VXI11-REC-B.6.1 | A second link can be opened on the same device | SHOULD | REC B.6.1 |
| 🟢 | VXI11-OBS-B.6.6 | A zero-length write is handled cleanly | INFO | OBS B.6.6 |
| 🟢 | VXI11-EXT-ABT-001 | The abort channel accepts an RPC null call | MUST | beyond the standard |
| 🟢 | VXI11-EXT-ABT-005 | device_abort with nothing in progress is harmless | INFO | beyond the standard |
| 🟢 | VXI11.2-EXT-CMD-001 | Bus Status rejects an undefined subcode | INFO | beyond the standard |
| 🟢 | VXI11.2-EXT-CMD-002 | Send Command respects the 128 byte limit | SHOULD | VXI-11.2 RULE B.5.3 |
| 🟢 | VXI11-EXT-GEN-001 | The generic operations leave the link usable | SHOULD | beyond the standard |
| 🟢 | VXI11-EXT-INT-005 | A handle longer than 40 bytes is a parameter error | INFO | beyond the standard |
| 🟢 | VXI11-EXT-IO-005 | termChar outside 0..255 is a parameter error | INFO | beyond the standard |
| 🟢 | VXI11-EXT-IO-010 | A write without the END flag does not terminate the message | SHOULD | RULE B.6.14 |
| 🟢 | VXI11-EXT-IO-011 | device_read on a device with nothing pending does not return stale data | SHOULD | beyond the standard |
| 🟢 | VXI11-EXT-IO-012 | Reserved bits in Device_Flags are ignored, not rejected | INFO | beyond the standard |
| 🟢 | VXI11-EXT-LCK-007 | The lock owner can still use the device | MUST | OBS B.6.18 |
| 🟢 | VXI11-EXT-LNK-003 | abortPort matches the port mapper's DEVICE_ASYNC entry | SHOULD | beyond the standard |
| 🟢 | VXI11-EXT-LNK-006 | create_link on a nonexistent device name is refused | MUST | beyond the standard |
| 🟢 | VXI11-EXT-LNK-007 | create_link with a syntactically invalid device name is refused | SHOULD | beyond the standard |
| 🟢 | VXI11-EXT-LNK-011 | A link is not usable from a different core connection | SHOULD | beyond the standard |
| 🟢 | VXI11-EXT-PM-003 | DEVICE_ASYNC (0x0607B0) v1 is registered | INFO | beyond the standard |
| 🟢 | VXI11-EXT-PM-004 | GETPORT for an unregistered program returns 0, not an error | SHOULD | beyond the standard |
| 🟢 | VXI11-EXT-PM-005 | GETPORT for a wrong version of DEVICE_CORE does not resolve to v1 | SHOULD | beyond the standard |
| 🟢 | VXI11-EXT-PM-008 | Port mapper handles PMAPPROC_DUMP or rejects it cleanly | INFO | beyond the standard |
| 🟢 | VXI11-EXT-PM-009 | Port mapper survives a GETPORT with truncated arguments | SHOULD | beyond the standard |
| 🟢 | VXI11-EXT-ROB-003 | A very large requestSize does not upset the server | MUST | beyond the standard |
| 🟢 | VXI11-EXT-ROB-005 | Bare TCP connects and disconnects do not exhaust the server | SHOULD | beyond the standard |
| 🟢 | VXI11-EXT-ROB-006 | The server is still healthy at the end of the run | INFO | beyond the standard |
| 🟢 | VXI11-EXT-RPC-004 | Truncated arguments give GARBAGE_ARGS rather than a dropped connection | MUST | RULE B.1.3 |
| 🟢 | VXI11-EXT-RPC-005 | An RPC version other than 2 is denied with RPC_MISMATCH | SHOULD | RULE B.1.3 |
| 🟢 | VXI11-EXT-RPC-006 | The reply carries the transaction id of the call | MUST | RULE B.1.3 |
| 🟢 | VXI11-EXT-RPC-007 | A call split across several record fragments is reassembled | MUST | RULE B.1.3 |
| 🟢 | VXI11-EXT-RPC-008 | AUTH_UNIX credentials are accepted | SHOULD | RULE B.1.3 |
| 🟢 | VXI11-EXT-RPC-009 | The reply verifier is AUTH_NONE with an empty body | INFO | RULE B.1.3 |
| 🟢 | VXI11-EXT-RPC-011 | The server survives garbage on the core port | MUST | beyond the standard |
Details
🟢 VXI11.2-RULE-B.1.3 — A device string with no address links to the interface
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | cmd (cmd) |
| Duration | 0.00 s |
Verifies:
VXI-11.2 RULE B.1.3A device string containing only the interface name is a link to the interface.VXI-11.2 RULE B.1.2The interface name gpib0 is the first or only IEEE 488.1 interface; further interfaces are gpibN.VXI-11.2 RULE B.1.1The device string has the form[, [, ]].
What is checked: 'gpib0' on its own must open a link to the interface rather than to a device; device_docmd needs such a link
Observed: interface link opened on 'gpib0'
Protocol log
interface link 0 on 'gpib0'
🟢 VXI11-RULE-B.1.4 — Portmapper answers on TCP/111
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Port mapper (pm) |
| Duration | 0.02 s |
Verifies:
VXI-11 RULE B.1.4A host acting as a network instrument server supports a port mapper.
What is checked: the server must register with the port mapper
🟢 VXI11-RULE-B.1.5 — Every procedure defined by the standard is implemented
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | RPC layer (rpc) |
| Duration | 0.03 s |
Verifies:
VXI-11 RULE B.1.5Hosts implement all the messages and data types of B.5 and B.6.VXI-11 RULE B.6.1The program and version numbers of Table B.3 are used: core 395183/1, abort 395184/1, interrupt 395185/1.VXI-11 RULE B.1.2Hosts support the Internet Protocol Suite; TCP is the transport layer.VXI-11.2 RULE B.2.1The interface device supports the network instrument protocol and executes all of its RPCs.
What is checked: all 15 core channel procedures and device_abort on the async channel must exist; a missing one shows up as PROC_UNAVAIL long before any device-level error code does
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
create_link -> MSG_ACCEPTED/SUCCESS
device_write -> MSG_ACCEPTED/SUCCESS
device_read -> MSG_ACCEPTED/SUCCESS
device_readstb -> MSG_ACCEPTED/SUCCESS
device_trigger -> MSG_ACCEPTED/SUCCESS
device_clear -> MSG_ACCEPTED/SUCCESS
device_remote -> MSG_ACCEPTED/SUCCESS
device_local -> MSG_ACCEPTED/SUCCESS
device_lock -> MSG_ACCEPTED/SUCCESS
device_unlock -> MSG_ACCEPTED/SUCCESS
device_enable_srq -> MSG_ACCEPTED/SUCCESS
device_docmd -> MSG_ACCEPTED/SUCCESS
destroy_intr_chan -> MSG_ACCEPTED/SUCCESS
create_intr_chan -> MSG_ACCEPTED/SUCCESS
destroy_link -> MSG_ACCEPTED/SUCCESS
🟢 VXI11-RULE-B.2.1-a — The advertised core port accepts TCP connections
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Port mapper (pm) |
| Duration | 0.00 s |
Verifies:
VXI-11 RULE B.2.1The server implements all three channels, established by the sequences of B.2.4 and B.2.5.
What is checked: the registered port must be the live core channel
🟢 VXI11-RULE-B.2.1-b — The advertised abort port accepts TCP connections
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Port mapper (pm) |
| Duration | 0.01 s |
Verifies:
VXI-11 RULE B.2.1The server implements all three channels, established by the sequences of B.2.4 and B.2.5.
What is checked: VXI-11 B.2
🟢 VXI11-RULE-B.2.2 — Two calls pipelined on one connection are both answered
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | RPC layer (rpc) |
| Duration | 0.03 s |
Verifies:
VXI-11 RULE B.2.2Core channel RPCs are processed in the order received, and the reply is not sent until the action is complete.VXI-11.2 RULE B.3The RPC reply is not sent until the associated action is complete.
What is checked: a client may have several calls outstanding on one connection
Protocol log
xids answered: ['0x4100001d', '0x4100001e']
🟢 VXI11-RULE-B.2.3 — An unknown program number gives PROG_UNAVAIL
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | RPC layer (rpc) |
| Duration | 0.02 s |
Verifies:
VXI-11 RULE B.2.3Other protocols carried on the core channel under different program numbers do not interfere with the instrument protocol.
What is checked: MSG_ACCEPTED with PROG_UNAVAIL for programs the server does not implement
Protocol log
prog 0x0607FE -> MSG_ACCEPTED/PROG_UNAVAIL
🟢 VXI11-RULE-B.2.5 — The abort channel rejects unknown procedures
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | Abort channel (abt) |
| Duration | 0.02 s |
Verifies:
VXI-11 RULE B.2.5The abort channel carries only the device_abort RPC.
What is checked: an unimplemented procedure gives PROC_UNAVAIL
Protocol log
abort channel proc 42 -> MSG_ACCEPTED/PROC_UNAVAIL
🟢 VXI11-RULE-B.2.7 — Every create_link on one core channel returns the same abort port
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Link lifecycle (lnk) |
| Duration | 0.03 s |
Verifies:
VXI-11 RULE B.2.7The same abort port number is returned in every create_link reply sent on one core channel.
What is checked: the abort port identifies the connection's abort channel, not the individual link, so it must not change between create_link replies
Protocol log
abort ports returned: [34568, 34568, 34568]
🟢 VXI11-RULE-B.2.8 — The core channel works when no abort channel is ever established
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Abort channel (abt) |
| Duration | 0.03 s |
Verifies:
VXI-11 RULE B.2.8The server accepts and processes core channel RPCs even if an abort channel is never established.
What is checked: the abort channel is optional for the client; a connection that never opens one must be served normally
🟢 VXI11-RULE-B.2.10 — The interrupt channel is closed when destroy_intr_chan is called
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | Interrupt channel (int) |
| Duration | 0.53 s |
Verifies:
VXI-11 RULE B.2.10destroy_intr_chan makes the server destroy its RPC client and tear the interrupt channel down.
What is checked: the TCP connection to the client must be torn down cleanly
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
interrupt listener on 0.0.0.0:58834
create_intr_chan -> 192.168.3.3:58834
🟢 VXI11.2-RULE-B.4 — At least 14 concurrent links per server
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | cmd (cmd) |
| Duration | 0.06 s |
Verifies:
VXI-11.2 RULE B.4At least 14 concurrent links per network instrument server are supported.VXI-11.2 REC B.2Link and server counts should follow available resources, not arbitrary limits.
What is checked: an IEEE 488.1 interface device supports at least 14 links on one network instrument server
Protocol log
14 concurrent links on one connection
🟢 VXI11-RULE-B.4.3 — lock_timeout=0 with waitlock does not block
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | Locking (lck) |
| Duration | 0.08 s |
Verifies:
VXI-11 RULE B.4.3With a non-zero lock_timeout the server waits at least that long for a lock; with lock_timeout zero it does not wait at all and returns an error immediately.
What is checked: lock_timeout 0 means do not wait at all
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
waitlock with lock_timeout=0 -> 11 (device locked by another link) after 47 ms
🟢 VXI11-RULE-B.4.5-a — Closing the core connection releases the link's resources
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Link lifecycle (lnk) |
| Duration | 0.03 s |
Verifies:
VXI-11 RULE B.4.5When the core channel is reset or closed, the server releases all resources of every link on that connection -- locks, abort channel and interrupt channel included.VXI-11 RULE B.6.77Locks are tied to the core connection; a broken connection releases all of that connection's locks.
What is checked: an aborted TCP connection must not leak links or locks
Protocol log
opened and locked lid 0, then dropping the TCP connection
reclaimed after 0.0s
🟢 VXI11-RULE-B.4.5-b — The interrupt channel is torn down when the core connection drops
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | Interrupt channel (int) |
| Duration | 0.53 s |
Verifies:
VXI-11 RULE B.4.5When the core channel is reset or closed, the server releases all resources of every link on that connection -- locks, abort channel and interrupt channel included.
What is checked: closing the core channel ends the session, including its interrupt channel
Protocol log
interrupt listener on 0.0.0.0:58874
create_intr_chan -> 192.168.3.3:58874
🟢 VXI11-RULE-B.4.5-c — Links are reclaimed when clients disappear without destroy_link
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Robustness (rob) |
| Duration | 0.30 s |
Verifies:
VXI-11 RULE B.4.5When the core channel is reset or closed, the server releases all resources of every link on that connection -- locks, abort channel and interrupt channel included.VXI-11 REC B.4.3The server should detect a downed network or crashed client and clean up as for a closed connection.
What is checked: a server must not leak link resources when a client dies
Protocol log
25 connect/create_link/kill cycles survived
🟢 VXI11.2-RULE-B.4.10 — device_remote on an interface link returns error 8
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | cmd (cmd) |
| Duration | 0.01 s |
Verifies:
VXI-11.2 RULE B.4.10device_remote on an interface link returns error 8.
What is checked: remote state applies to a device, not to the interface
Protocol log
interface link 0 on 'gpib0'
device_remote on the interface link -> 8 (operation not supported)
🟢 VXI11.2-RULE-B.4.12 — device_local on an interface link returns error 8
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | cmd (cmd) |
| Duration | 0.02 s |
Verifies:
VXI-11.2 RULE B.4.12device_local on an interface link returns error 8.
What is checked: local state applies to a device, not to the interface
Protocol log
interface link 0 on 'gpib0'
device_local on the interface link -> 8 (operation not supported)
🟢 VXI11.2-RULE-B.4.17 — device_readstb on an interface link returns error 8
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | cmd (cmd) |
| Duration | 0.00 s |
Verifies:
VXI-11.2 RULE B.4.17device_readstb on an interface link returns error 8.
What is checked: an interface has no status byte to read
Protocol log
interface link 0 on 'gpib0'
device_readstb on the interface link -> 8 (operation not supported)
🟢 VXI11.2-RULE-B.5 — REN is true after power-on
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | cmd (cmd) |
| Duration | 0.03 s |
Verifies:
VXI-11.2 RULE B.5After power-on the interface device sets REN true.
What is checked: the interface device sets REN true after power-on; this reads it back through Bus Status, so it only holds if nothing has cleared REN since
Protocol log
interface link 0 on 'gpib0'
REMOTE = 1
🟢 VXI11.2-RULE-B.5.1 — Only the cmd values of Table B.1 are accepted
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | cmd (cmd) |
| Duration | 0.03 s |
Verifies:
VXI-11.2 RULE B.5.1Only the cmd values of Table B.1 are supported; any other cmd returns immediately with error 8.
What is checked: any cmd outside Table B.1 returns immediately with error 8, including values inside the reserved 0x020000-0x02FFFF range
Protocol log
interface link 0 on 'gpib0'
cmd 0x000000 -> 8 (operation not supported)
cmd 0x000001 -> 8 (operation not supported)
cmd 0x020005 -> 8 (operation not supported)
cmd 0x0200FF -> 8 (operation not supported)
cmd 0x02FFFF -> 8 (operation not supported)
cmd 0x7FFFFFFF -> 8 (operation not supported)
🟢 VXI11.2-RULE-B.5.2 — device_docmd on a device link returns error 8
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | cmd (cmd) |
| Duration | 0.03 s |
Verifies:
VXI-11.2 RULE B.5.2device_docmd on a link associated with a device performs no action and returns error 8.
What is checked: a link associated with a device performs no action for any cmd and returns 'operation not supported'
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
Bus Status on the device link 'gpib0,4' -> 8 (operation not supported)
🟢 VXI11.2-RULE-B.5.3 — A wrong data_in length or datasize gives error 5
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | cmd (cmd) |
| Duration | 0.03 s |
Verifies:
VXI-11.2 RULE B.5.3A data_in_len or datasize conflicting with Table B.1 gives error 5 and no action; datasize X accepts any value.
What is checked: Table B.1 fixes data_in_len and datasize per cmd; a mismatch is a parameter error and the operation must not be performed
Protocol log
interface link 0 on 'gpib0'
Bus Status, datasize 1 -> 5 (parameter error)
Bus Status, data_in 1 byte -> 5 (parameter error)
Bus Status, data_in 4 bytes -> 5 (parameter error)
Bus Status, datasize 4 -> 5 (parameter error)
🟢 VXI11.2-RULE-B.5.4 — data_in and data_out are byte-swapped when asked
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | cmd (cmd) |
| Duration | 0.02 s |
Verifies:
VXI-11.2 RULE B.5.4data_in and data_out hold unsigned integers of datasize bytes.VXI-11 RULE B.6.99The server byte-swaps data_in and data_out when its architecture differs from the client's, per network_order.VXI-11 RULE B.6.100Byte swapping follows datasize: 1 none, 2 word, 4 longword, 8 eight-byte boundaries.
What is checked: with network_order false the client is little-endian, so the server swaps data_in and data_out on datasize boundaries. Bus Status uses datasize 2, which makes the swap observable
Protocol log
interface link 0 on 'gpib0'
network order: data_in=b'\x00\x08' data_out=b'\x00\x00' (address 0)
little endian: data_in=b'\x08\x00' -> 0 (no error) data_out=b'\x00\x00'
🟢 VXI11.2-RULE-B.5.5 — Send Command transfers command bytes and echoes them
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | cmd (cmd) |
| Duration | 0.02 s |
Verifies:
VXI-11.2 RULE B.5.5Send Command (0x020000) executes SEND COMMAND with the bytes in data_in and returns them unchanged in data_out.
What is checked: the bytes in data_in are sent with the SEND COMMAND sequence and returned unchanged. UNL (0x3F) and UNT (0x5F) are used here: they unaddress the bus, which is how every addressed sequence starts anyway
Protocol log
interface link 0 on 'gpib0'
data_out = b'?_'
🟢 VXI11.2-RULE-B.5.6 — Bus Status returns two bytes for every subcode
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | cmd (cmd) |
| Duration | 0.01 s |
Verifies:
VXI-11.2 RULE B.5.6Bus Status (0x020001) returns a two-byte data_out whose value depends on the subcode in data_in per Table B.2.VXI-11.2 RULE B.5.4data_in and data_out hold unsigned integers of datasize bytes.
What is checked: each subcode of Table B.2 returns a two-byte value: 0 or 1 for the line and state queries, 0 to 30 for the bus address
Observed: address 0, REN 1, SRQ 0
Protocol log
interface link 0 on 'gpib0'
REMOTE = 1
SRQ = 0
NDAC = 1
SYSTEM CONTROLLER = 1
CONTROLLER-IN-CHARGE = 1
TALKER = 0
LISTENER = 0
BUS ADDRESS = 0
🟢 VXI11.2-RULE-B.5.7 — ATN Control sets and clears ATN
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | cmd (cmd) |
| Duration | 0.02 s |
Verifies:
VXI-11.2 RULE B.5.7ATN Control (0x020002) sets ATN true for a non-zero data_in and false for zero; data_out repeats data_in.
What is checked: a non-zero data_in asserts ATN, zero releases it, and data_out repeats data_in. Holding ATN interferes with data transfers, so this check restores ATN false when it is done
Protocol log
interface link 0 on 'gpib0'
ATN Control(1) -> 0 (no error) data_out=b'\x00\x01'
ATN Control(0) -> 0 (no error) data_out=b'\x00\x00'
🟢 VXI11.2-RULE-B.5.8 — REN Control sets REN and echoes data_in
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | cmd (cmd) |
| Duration | 0.03 s |
Verifies:
VXI-11.2 RULE B.5.8REN Control (0x020003) sets the sre message true for a non-zero data_in and false for zero; data_out repeats data_in.
What is checked: a non-zero data_in sets the sre message true, zero sets it false, and data_out repeats data_in. This check only ever sets REN true, which is the post power-on state, so it cannot leave instruments stuck in local
Protocol log
interface link 0 on 'gpib0'
data_out = b'\x00\x01'
⚪ VXI11.2-RULE-B.5.9 — Pass Control hands control to the given address
| Result | ⚪ SKIP |
| Severity | MUST |
| Suite | cmd (cmd) |
| Duration | 0.00 s |
Verifies:
VXI-11.2 RULE B.5.9Pass Control (0x020004) executes PASS CONTROL with the talk address data_in | 0x80; data_out repeats data_in.
What is checked: PASS CONTROL is executed with the talk address data_in | 0x80. This leaves the gateway no longer controller-in-charge, so it only runs with DOCMD_ALLOW_BUS_CONTROL and a target that can take control
Observed: no PASS_CONTROL_ADDRESS configured; passing control to a device that cannot take it leaves the bus without a controller
🟢 VXI11.2-RULE-B.5.10 — Bus Address accepts 0-30 and rejects anything else
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | cmd (cmd) |
| Duration | 0.03 s |
Verifies:
VXI-11.2 RULE B.5.10Bus Address (0x02000A) sets the interface address when data_in is 0 to 30, otherwise returns error 5; data_out repeats data_in.
What is checked: an address outside 0 to 30 is a parameter error; a valid one is applied and echoed. This check writes back the address the gateway already has, so it changes nothing
Protocol log
interface link 0 on 'gpib0'
current bus address = 0
Bus Address(31) -> 5 (parameter error)
Bus Address(255) -> 5 (parameter error)
Bus Address(1000) -> 5 (parameter error)
🟢 VXI11.2-RULE-B.5.11 — IFC Control sends IFC and returns no data
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | cmd (cmd) |
| Duration | 0.05 s |
Verifies:
VXI-11.2 RULE B.5.11IFC Control (0x020010) executes SEND IFC and returns an empty data_out.
What is checked: SEND IFC is executed and data_out comes back empty. IFC reinitialises the bus and unaddresses every device
Protocol log
interface link 0 on 'gpib0'
data_out = b''
🟢 VXI11-RULE-B.6.1-a — DEVICE_CORE (0x0607AF) v1 is registered
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Port mapper (pm) |
| Duration | 0.00 s |
Verifies:
VXI-11 RULE B.6.1The program and version numbers of Table B.3 are used: core 395183/1, abort 395184/1, interrupt 395185/1.
What is checked: the core channel program must be resolvable via GETPORT
Protocol log
core channel on port 1024
🟢 VXI11-RULE-B.6.1-b — A wrong program version gives PROG_MISMATCH with a version range
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | RPC layer (rpc) |
| Duration | 0.01 s |
Verifies:
VXI-11 RULE B.6.1The program and version numbers of Table B.3 are used: core 395183/1, abort 395184/1, interrupt 395185/1.
What is checked: PROG_MISMATCH must carry the supported low/high versions
Protocol log
DEVICE_CORE version 7 -> MSG_ACCEPTED/PROG_MISMATCH (low=1 high=1)
🟢 VXI11-RULE-B.6.2-a — The core channel does not implement the abort procedure
| Result | 🟢 PASS |
| Severity | INFO |
| Suite | Abort channel (abt) |
| Duration | 0.02 s |
Verifies:
VXI-11 RULE B.6.2Only the defined procedure numbers are used with those programs; all others are reserved.
What is checked: device_abort lives on the async channel only
Observed: core channel proc 1 -> MSG_ACCEPTED/PROC_UNAVAIL
Protocol log
proc 1 on the core channel -> MSG_ACCEPTED/PROC_UNAVAIL
🟢 VXI11-RULE-B.6.2-b — An unimplemented procedure gives PROC_UNAVAIL
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | RPC layer (rpc) |
| Duration | 0.00 s |
Verifies:
VXI-11 RULE B.6.2Only the defined procedure numbers are used with those programs; all others are reserved.
What is checked: PROC_UNAVAIL for procedures outside the program's set
Protocol log
core proc 21 -> MSG_ACCEPTED/PROC_UNAVAIL
core proc 24 -> MSG_ACCEPTED/PROC_UNAVAIL
core proc 99 -> MSG_ACCEPTED/PROC_UNAVAIL
🟢 VXI11-RULE-B.6.3-a — create_link on the configured device succeeds
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Link lifecycle (lnk) |
| Duration | 0.03 s |
Verifies:
VXI-11 RULE B.6.3create_link locks the device if lockDevice is set, returns a lid unique among active links, a maxRecvSize of at least 1024, the abort port, and error 0.VXI-11.2 RULE B.1.4A device string with an address is a link to the device at that address.
What is checked: create_link returns error 0 plus lid, abortPort and maxRecvSize
Protocol log
lid=0 abortPort=34568 maxRecvSize=1024
🟢 VXI11-RULE-B.6.3-b — maxRecvSize is at least 1024 bytes
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Link lifecycle (lnk) |
| Duration | 0.03 s |
Verifies:
VXI-11 RULE B.6.3create_link locks the device if lockDevice is set, returns a lid unique among active links, a maxRecvSize of at least 1024, the abort port, and error 0.
What is checked: create_link returns in maxRecvSize the largest data parameter the server accepts in device_write, and that value SHALL be at least 1024
Observed: maxRecvSize = 1024
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
🟢 VXI11-RULE-B.6.3-c — Link identifiers are unique across connections
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Link lifecycle (lnk) |
| Duration | 0.06 s |
Verifies:
VXI-11 RULE B.6.3create_link locks the device if lockDevice is set, returns a lid unique among active links, a maxRecvSize of at least 1024, the abort port, and error 0.
What is checked: a lid identifies exactly one link
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
link 16777216 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
link 33554432 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
lids: [0, 16777216, 33554432]
🟢 VXI11-RULE-B.6.3-d — A write of exactly maxRecvSize bytes is accepted
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Read / write (io) |
| Duration | 0.19 s |
Verifies:
VXI-11 RULE B.6.3create_link locks the device if lockDevice is set, returns a lid unique among active links, a maxRecvSize of at least 1024, the abort port, and error 0.VXI-11 OBS B.6.5A client sending more than maxRecvSize bytes splits the transfer over several device_write calls.
What is checked: the server must accept a data parameter up to maxRecvSize
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
writing 1024 bytes (maxRecvSize=1024)
🟢 VXI11-RULE-B.6.4 — clientId is echoed back or ignored, never rejected
| Result | 🟢 PASS |
| Severity | INFO |
| Suite | Link lifecycle (lnk) |
| Duration | 0.03 s |
Verifies:
VXI-11 RULE B.6.4The server does not alter its function based on clientId.
What is checked: clientId is advisory; unusual values must not break link creation
Protocol log
clientId=0 -> 0 (no error)
clientId=-1 -> 0 (no error)
clientId=2147483647 -> 0 (no error)
🟢 VXI11-RULE-B.6.5 — Running out of links is reported as error 9, not a crash
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Robustness (rob) |
| Duration | 0.08 s |
Verifies:
VXI-11 RULE B.6.5create_link with no link available terminates with error 9.
What is checked: 'out of resources' is the defined answer when no link can be created
Protocol log
opened 16 links before 9 (out of resources)
🟢 VXI11-RULE-B.6.6 — create_link with lockDevice=false ignores an existing lock
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Link lifecycle (lnk) |
| Duration | 0.02 s |
Verifies:
VXI-11 RULE B.6.6create_link ignores locks when lockDevice is false.
What is checked: the operation of create_link ignores locks if lockDevice is false, so a link may always be created on a locked device as long as it does not ask for the lock itself
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
link 0 holds the lock
create_link(lockDevice=false) on the locked device -> 0 (no error)
🟢 VXI11-RULE-B.6.7 — create_link with lockDevice=true acquires the lock
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Link lifecycle (lnk) |
| Duration | 0.16 s |
Verifies:
VXI-11 RULE B.6.7With lockDevice true and the lock still held after lock_timeout, create_link creates no link and returns error 11.
What is checked: lockDevice locks the device as part of link creation
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
second locking create_link -> 11 (device locked by another link)
🟢 VXI11-RULE-B.6.9 — destroy_link releases the lock the link held
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Locking (lck) |
| Duration | 0.05 s |
Verifies:
VXI-11 RULE B.6.9destroy_link deactivates the lid, frees the lock this link holds, disables this link's interrupts, and returns error 0.
What is checked: destroying a link frees any lock it holds
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
link B lock after A was destroyed -> 0 (no error)
🟢 VXI11-RULE-B.6.10-a — destroy_link with an unknown link identifier gives error 4
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Link lifecycle (lnk) |
| Duration | 0.00 s |
Verifies:
VXI-11 RULE B.6.10destroy_link with a lid matching no active link returns error 4.
What is checked: destroy_link on an unknown lid returns 'invalid link identifier'
🟢 VXI11-RULE-B.6.10-b — destroy_link twice on the same link gives error 4
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Link lifecycle (lnk) |
| Duration | 0.02 s |
Verifies:
VXI-11 RULE B.6.10destroy_link with a lid matching no active link returns error 4.VXI-11 RULE B.6.9destroy_link deactivates the lid, frees the lock this link holds, disables this link's interrupts, and returns error 0.
What is checked: once destroyed, the lid is no longer valid
🟢 VXI11-RULE-B.6.12 — device_abort does not affect destroy_link
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Abort channel (abt) |
| Duration | 0.02 s |
Verifies:
VXI-11 RULE B.6.12destroy_link is not affected by device_abort.VXI-11 RULE B.6.106device_abort initiates termination of any in-progress core channel RPC on the link except destroy_link, device_enable_srq and device_unlock, and returns error 0.
What is checked: destroy_link is one of the three procedures device_abort must leave alone; after an abort the link must still close cleanly
Protocol log
abort on idle link 0 -> 0 (no error)
destroy_link after abort -> 0 (no error)
🟢 VXI11-RULE-B.6.13 — device_write reports the number of bytes it accepted
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Read / write (io) |
| Duration | 0.02 s |
Verifies:
VXI-11 RULE B.6.13device_write transfers data to the device, returns the number of bytes accepted in size, and returns error 0.
What is checked: Device_WriteResp.size is the count of bytes actually written
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
🟢 VXI11-RULE-B.6.15 — Every operation on a destroyed link gives error 4
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Link lifecycle (lnk) |
| Duration | 0.00 s |
Verifies:
VXI-11 RULE B.6.15device_write with an unmatched lid returns error 4.VXI-11 RULE B.6.24device_read with an unmatched lid returns error 4.VXI-11 RULE B.6.33device_readstb with an unmatched lid returns error 4.VXI-11 RULE B.6.41device_trigger with an unmatched lid returns error 4.VXI-11 RULE B.6.49device_clear with an unmatched lid returns error 4.VXI-11 RULE B.6.57device_remote with an unmatched lid returns error 4.VXI-11 RULE B.6.65device_local with an unmatched lid returns error 4.VXI-11 RULE B.6.73device_lock with an unmatched lid returns error 4 before any attempt to acquire the lock.VXI-11 RULE B.6.79device_unlock with an unmatched lid returns error 4.VXI-11 RULE B.6.94device_enable_srq with an unmatched lid returns error 4.VXI-11 RULE B.6.97device_docmd with an unmatched lid returns error 4.
What is checked: 'invalid link identifier' is returned for any procedure taking a stale lid
Protocol log
device_write on stale lid -> 4 (invalid link identifier)
device_read on stale lid -> 4 (invalid link identifier)
device_readstb on stale lid -> 4 (invalid link identifier)
device_trigger on stale lid -> 4 (invalid link identifier)
device_clear on stale lid -> 4 (invalid link identifier)
device_remote on stale lid -> 4 (invalid link identifier)
device_local on stale lid -> 4 (invalid link identifier)
device_lock on stale lid -> 4 (invalid link identifier)
device_unlock on stale lid -> 4 (invalid link identifier)
device_enable_srq on stale lid -> 4 (invalid link identifier)
device_docmd on stale lid -> 4 (invalid link identifier)
🟢 VXI11-RULE-B.6.16 — device_write beyond maxRecvSize transfers nothing and returns error 5
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Read / write (io) |
| Duration | 0.03 s |
Verifies:
VXI-11 RULE B.6.16device_write with data longer than maxRecvSize transfers nothing and returns error 5.
What is checked: data longer than the maxRecvSize reported by create_link must be rejected outright, not silently truncated or partially written
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
writing 1025 bytes with maxRecvSize=1024
-> 5 (parameter error), size=0
🟢 VXI11-RULE-B.6.17 — An operation from another link is refused while the device is locked
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Locking (lck) |
| Duration | 0.05 s |
Verifies:
VXI-11 RULE B.6.17device_write against a lock held elsewhere blocks if waitlock is set, otherwise returns error 11.VXI-11 RULE B.6.25device_read against a lock held elsewhere blocks if waitlock is set, otherwise returns error 11.VXI-11 RULE B.6.34device_readstb against a lock held elsewhere blocks if waitlock is set, otherwise returns error 11.VXI-11 RULE B.6.42device_trigger against a lock held elsewhere blocks if waitlock is set, otherwise returns error 11.VXI-11 RULE B.6.50device_clear against a lock held elsewhere blocks if waitlock is set, otherwise returns error 11.VXI-11 RULE B.6.58device_remote against a lock held elsewhere blocks if waitlock is set, otherwise returns error 11.VXI-11 RULE B.6.66device_local against a lock held elsewhere blocks if waitlock is set, otherwise returns error 11.VXI-11 RULE B.6.101device_docmd against a lock held elsewhere blocks if waitlock is set, otherwise returns error 11.
What is checked: without waitlock, operations on a locked device return error 11
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
device_write from the non-owning link -> 11 (device locked by another link)
device_read from the non-owning link -> 11 (device locked by another link)
device_readstb from the non-owning link -> 11 (device locked by another link)
device_clear from the non-owning link -> 11 (device locked by another link)
🟢 VXI11-RULE-B.6.18 — waitlock on an operation waits instead of failing immediately
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | Locking (lck) |
| Duration | 1.58 s |
Verifies:
VXI-11 RULE B.6.18device_write returns error 11 if the lock is still held after lock_timeout.VXI-11 RULE B.6.26device_read returns error 11 with no data if the lock is still held after lock_timeout.VXI-11 RULE B.6.35device_readstb returns error 11 if the lock is still held after lock_timeout.VXI-11 RULE B.6.43device_trigger returns error 11 if the lock is still held after lock_timeout.VXI-11 RULE B.6.51device_clear returns error 11 if the lock is still held after lock_timeout.VXI-11 RULE B.6.59device_remote returns error 11 if the lock is still held after lock_timeout.VXI-11 RULE B.6.67device_local returns error 11 if the lock is still held after lock_timeout.VXI-11 RULE B.6.102device_docmd returns error 11 if the lock is still held after lock_timeout.
What is checked: the waitlock flag applies to every operation, not just device_lock
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
readstb with waitlock -> 11 (device locked by another link) after 1547 ms
🟢 VXI11-RULE-B.6.23-a — A write/read round trip returns instrument data with END set
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Read / write (io) |
| Duration | 0.30 s |
Verifies:
VXI-11 RULE B.6.23device_read transfers bytes until END (sets END), requestSize reached (sets REQCNT, also used when requestSize is zero), termChar matched with termchrset (sets CHR), or the response buffer is full (sets no bit); then returns error 0.
What is checked: reason bit END (0x04) is set when the transfer ended on EOI/END
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
reason=0x04(END) data=b'HEWLETT-PACKARD,34401A,0,5-1-1\n'
🟢 VXI11-RULE-B.6.23-b — device_read never returns more than requestSize bytes
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Read / write (io) |
| Duration | 0.03 s |
Verifies:
VXI-11 RULE B.6.23device_read transfers bytes until END (sets END), requestSize reached (sets REQCNT, also used when requestSize is zero), termChar matched with termchrset (sets CHR), or the response buffer is full (sets no bit); then returns error 0.
What is checked: the server must not transfer more than requestSize bytes
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
got 8 bytes, reason=0x01(REQCNT)
🟢 VXI11-RULE-B.6.23-c — termChar terminates a read and sets the CHR reason bit
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | Read / write (io) |
| Duration | 0.05 s |
Verifies:
VXI-11 RULE B.6.23device_read transfers bytes until END (sets END), requestSize reached (sets REQCNT, also used when requestSize is zero), termChar matched with termchrset (sets CHR), or the response buffer is full (sets no bit); then returns error 0.
What is checked: with termchrset the read ends on termChar and reason bit CHR (0x02) is set
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
reason=0x06(CHR|END) data=b'HEWLETT-PACKARD,34401A,0,5-1-1\n'
🟢 VXI11-RULE-B.6.23-d — device_read with requestSize zero terminates immediately with REQCNT
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Read / write (io) |
| Duration | 0.02 s |
Verifies:
VXI-11 RULE B.6.23device_read transfers bytes until END (sets END), requestSize reached (sets REQCNT, also used when requestSize is zero), termChar matched with termchrset (sets CHR), or the response buffer is full (sets no bit); then returns error 0.
What is checked: the requestSize termination condition is the one to use when requestSize is zero, so the read returns at once with no data and the REQCNT bit set
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
requestSize=0 -> 0 (no error) reason=0x01(REQCNT) 0 bytes after 0 ms
🟢 VXI11-RULE-B.6.27 — device_read honours io_timeout and returns error 15
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Read / write (io) |
| Duration | 2.08 s |
Verifies:
VXI-11 RULE B.6.27device_read returns error 15 with reason zero and the bytes transferred so far if the transfer exceeds io_timeout.VXI-11 RULE B.4.2The server allows at least io_timeout milliseconds for an I/O operation to complete.VXI-11 RULE B.6.30device_read returns the bytes transferred in data even when it ends in a timeout or an abort.
What is checked: when no data arrives within io_timeout the server returns 'I/O timeout'
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
read on an idle device: 15 (I/O timeout) after 2063 ms
🟢 VXI11-RULE-B.6.31 — device_readstb returns a status byte in range
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Read / write (io) |
| Duration | 0.03 s |
Verifies:
VXI-11 RULE B.6.31device_readstb returns the device's status byte and error 0.VXI-11 RULE B.6.32device_readstb returns error 8 if no status byte can be returned.
What is checked: device_readstb returns the instrument's status byte
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
stb = 0x00
🟢 VXI11-RULE-B.6.39 — device_trigger sends a trigger or reports error 8
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | gen (gen) |
| Duration | 0.02 s |
Verifies:
VXI-11 RULE B.6.39device_trigger sends a trigger to the device and returns error 0.VXI-11 RULE B.6.40device_trigger returns error 8 if the device has no trigger and the server can detect that.
What is checked: device_trigger triggers the device and returns 0; a server that can tell the device has no trigger returns 8 instead
Observed: device_trigger performed (error 0)
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
device_trigger on an idle, unlocked link -> 0 (no error)
🟢 VXI11-RULE-B.6.47 — device_clear clears the device or reports error 8
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | gen (gen) |
| Duration | 0.41 s |
Verifies:
VXI-11 RULE B.6.47device_clear clears the device and returns error 0.VXI-11 RULE B.6.48device_clear returns error 8 if the device has no clear and the server can detect that.
What is checked: device_clear performs a device clear and returns 0; a server that can tell the device has no clear returns 8 instead
Observed: device_clear performed (error 0)
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
device_clear on an idle, unlocked link -> 0 (no error)
🟢 VXI11-RULE-B.6.55 — device_remote sets the remote state or reports error 8
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | gen (gen) |
| Duration | 0.11 s |
Verifies:
VXI-11 RULE B.6.55device_remote places the device in the remote state, error 0.VXI-11 RULE B.6.56device_remote returns error 8 if the device has no remote state and the server can detect that.
What is checked: device_remote disables the front panel and returns 0, or returns 8 if the device has no remote state and the server can tell
Observed: device_remote performed (error 0)
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
device_remote on an idle, unlocked link -> 0 (no error)
🟢 VXI11-RULE-B.6.63 — device_local sets the local state or reports error 8
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | gen (gen) |
| Duration | 0.12 s |
Verifies:
VXI-11 RULE B.6.63device_local places the device in the local state, error 0.VXI-11 RULE B.6.64device_local returns error 8 if the device has no local state and the server can detect that.
What is checked: device_local re-enables the front panel and returns 0, or returns 8 if the device has no local state and the server can tell
Observed: device_local performed (error 0)
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
device_local on an idle, unlocked link -> 0 (no error)
🟢 VXI11-RULE-B.6.71 — device_lock succeeds on an unlocked device
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Locking (lck) |
| Duration | 0.02 s |
Verifies:
VXI-11 RULE B.6.71device_lock acquires the device's lock and returns error 0.VXI-11 RULE B.6.78device_unlock releases the lock and returns error 0.
What is checked: device_lock grants the lock and returns error 0
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
🟢 VXI11-RULE-B.6.72 — device_lock from the link that already holds the lock gives error 11
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Locking (lck) |
| Duration | 0.03 s |
Verifies:
VXI-11 RULE B.6.72device_lock from the link that already holds the lock returns error 11.
What is checked: the standard does not define nested locks: a second device_lock from the owning link returns 'device locked by another link'
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
second lock from the same link -> 11 (device locked by another link)
🟢 VXI11-RULE-B.6.74-a — A second link cannot lock a device that is already locked
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Locking (lck) |
| Duration | 0.05 s |
Verifies:
VXI-11 RULE B.6.74device_lock against a lock held elsewhere blocks if waitlock is set, otherwise returns error 11.
What is checked: error 11 'device locked by another link'
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
link B lock without waitlock -> 11 (device locked by another link) after 0 ms
🟢 VXI11-RULE-B.6.74-b — waitlock acquires the lock as soon as the holder releases it
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Locking (lck) |
| Duration | 1.03 s |
Verifies:
VXI-11 RULE B.6.74device_lock against a lock held elsewhere blocks if waitlock is set, otherwise returns error 11.
What is checked: a blocked device_lock completes when the lock becomes free
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
link B acquired after 1000 ms -> 0 (no error)
🟢 VXI11-RULE-B.6.75 — waitlock makes device_lock block for lock_timeout, then error 11
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Locking (lck) |
| Duration | 2.09 s |
Verifies:
VXI-11 RULE B.6.75device_lock returns error 11 if the lock is still held after lock_timeout.
What is checked: with waitlock the server waits up to lock_timeout before returning error 11
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
link B waitlock(2000 ms) -> 11 (device locked by another link) after 2047 ms
🟢 VXI11-RULE-B.6.76 — device_abort terminates a blocked device_lock with error 23
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Locking (lck) |
| Duration | 0.55 s |
Verifies:
VXI-11 RULE B.6.76device_lock returns error 23 when aborted.
What is checked: a device_lock waiting on the waitlock flag is an in-progress core channel RPC and must be abortable
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
device_abort on the blocked lock -> 0 (no error)
blocked device_lock returned 23 (abort) after 516 ms
🟢 VXI11-RULE-B.6.80-a — device_unlock without holding the lock gives error 12
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Locking (lck) |
| Duration | 0.03 s |
Verifies:
VXI-11 RULE B.6.80device_unlock from a link that does not hold the lock returns error 12.
What is checked: 'no lock held by this link'
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
🟢 VXI11-RULE-B.6.80-b — device_unlock from a link that does not own the lock gives error 12
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Locking (lck) |
| Duration | 0.05 s |
Verifies:
VXI-11 RULE B.6.80device_unlock from a link that does not hold the lock returns error 12.
What is checked: only the owning link may unlock
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
link B unlock -> 12 (no lock held by this link)
🟢 VXI11-RULE-B.6.81 — device_abort does not affect device_unlock
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Abort channel (abt) |
| Duration | 0.01 s |
Verifies:
VXI-11 RULE B.6.81device_unlock is not affected by device_abort.VXI-11 RULE B.6.106device_abort initiates termination of any in-progress core channel RPC on the link except destroy_link, device_enable_srq and device_unlock, and returns error 0.
What is checked: device_unlock is exempt from abort: a lock must still be releasable after an abort was delivered on the link
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
abort -> 0 (no error)
device_unlock after abort -> 0 (no error)
🟢 VXI11-RULE-B.6.82 — create_intr_chan opens a channel back to the client
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Interrupt channel (int) |
| Duration | 0.52 s |
Verifies:
VXI-11 RULE B.6.82create_intr_chan establishes an interrupt channel to hostAddr and hostPort with the given program, version and family; error 0.VXI-11 RULE B.6.84The server supports a TCP interrupt channel.VXI-11 RULE B.2.6The interrupt channel is established by the server to the client after the client issues create_intr_chan.VXI-11 RULE B.6.91destroy_intr_chan closes the interrupt channel and returns 0.
What is checked: the server connects to hostAddr/hostPort for interrupts
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
interrupt listener on 0.0.0.0:54299
create_intr_chan -> 192.168.3.3:54299
🟢 VXI11-RULE-B.6.83 — create_intr_chan with an unreachable address returns error 6
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Interrupt channel (int) |
| Duration | 1.01 s |
Verifies:
VXI-11 RULE B.6.83create_intr_chan returns error 6 if the channel cannot be established.
What is checked: an unusable interrupt address must yield an error, not a hung server
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
create_intr_chan to 192.0.2.1:9 -> 6 (channel not established) after 1.0s
🟢 VXI11-RULE-B.6.85 — create_intr_chan with an undefined progFamily returns error 8
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Interrupt channel (int) |
| Duration | 0.52 s |
Verifies:
VXI-11 RULE B.6.85create_intr_chan returns error 8 for a progFamily other than DEVICE_TCP or DEVICE_UDP.
What is checked: Device_AddrFamily has exactly two values, DEVICE_TCP and DEVICE_UDP; any other value is 'operation not supported'
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
interrupt listener on 0.0.0.0:54302
progFamily=7 -> 8 (operation not supported)
🟢 VXI11-RULE-B.6.86 — create_intr_chan with progFamily=UDP is handled
| Result | 🟢 PASS |
| Severity | INFO |
| Suite | Interrupt channel (int) |
| Duration | 0.53 s |
Verifies:
VXI-11 RULE B.6.86create_intr_chan returns error 8 for a protocol the server does not support, such as UDP.VXI-11 PERM B.6.1The server may support a UDP interrupt channel.
What is checked: Device_AddrFamily may be DEVICE_TCP or DEVICE_UDP
Observed: UDP interrupt channels -> 8 (operation not supported)
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
interrupt listener on 0.0.0.0:61339
create_intr_chan(DEVICE_UDP) -> 8 (operation not supported)
🟢 VXI11-RULE-B.6.87 — create_intr_chan with a progNum other than 395185 returns error 8
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Interrupt channel (int) |
| Duration | 0.53 s |
Verifies:
VXI-11 RULE B.6.87create_intr_chan returns error 8 if progNum is not 395185.
What is checked: the interrupt channel program number is fixed; anything else is 'operation not supported'
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
interrupt listener on 0.0.0.0:61341
progNum=0x0607B2 -> 8 (operation not supported)
🟢 VXI11-RULE-B.6.88 — create_intr_chan with a progVers other than 1 returns error 8
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Interrupt channel (int) |
| Duration | 0.53 s |
Verifies:
VXI-11 RULE B.6.88create_intr_chan returns error 8 if progVers is not 1.
What is checked: only version 1 of the interrupt program is defined
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
interrupt listener on 0.0.0.0:61343
progVers=2 -> 8 (operation not supported)
🟢 VXI11-RULE-B.6.89 — create_intr_chan twice gives error 29
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Interrupt channel (int) |
| Duration | 0.53 s |
Verifies:
VXI-11 RULE B.6.89create_intr_chan when a channel already exists performs no operation and returns error 29.VXI-11 RULE B.2.9create_intr_chan when a channel already exists does not create a new one; one interrupt channel serves all links on the connection.
What is checked: 'channel already established' when one is already open
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
interrupt listener on 0.0.0.0:61345
create_intr_chan -> 192.168.3.3:61345
create_intr_chan -> 192.168.3.3:61345
second create_intr_chan -> 29 (channel already established)
🟢 VXI11-RULE-B.6.90 — The server works normally when no interrupt channel is established
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Interrupt channel (int) |
| Duration | 0.01 s |
Verifies:
VXI-11 RULE B.6.90The server operates correctly even with no interrupt channel.
What is checked: a client that never calls create_intr_chan must see a fully functional server
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
🟢 VXI11-RULE-B.6.92 — destroy_intr_chan without a channel gives error 6
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Interrupt channel (int) |
| Duration | 0.01 s |
Verifies:
VXI-11 RULE B.6.92destroy_intr_chan with no channel open returns error 6.
What is checked: destroying a channel that was never created is an error
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
destroy_intr_chan with no channel -> 6 (channel not established)
🟢 VXI11-RULE-B.6.93-a — device_enable_srq accepts a 40-byte handle
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Interrupt channel (int) |
| Duration | 0.55 s |
Verifies:
VXI-11 RULE B.6.93device_enable_srq enables or disables interrupts for this link and stores the handle unmodified; error 0.
What is checked: handles up to 40 bytes must be accepted verbatim
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
interrupt listener on 0.0.0.0:61349
create_intr_chan -> 192.168.3.3:61349
🟢 VXI11-RULE-B.6.93-b — device_enable_srq works when no interrupt channel is open
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Interrupt channel (int) |
| Duration | 0.02 s |
Verifies:
VXI-11 RULE B.6.93device_enable_srq enables or disables interrupts for this link and stores the handle unmodified; error 0.VXI-11 OBS B.6.21Service request enable states are per link and survive interrupt channel creation and destruction.
What is checked: the enable state is per link and survives interrupt channel creation and destruction, so device_enable_srq must succeed even with no channel open; Table B.18 allows only errors 0 and 4
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
device_enable_srq before create_intr_chan -> 0 (no error)
🟢 VXI11-RULE-B.6.95 — device_enable_srq behaves the same whether or not the link is locked
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Interrupt channel (int) |
| Duration | 0.06 s |
Verifies:
VXI-11 RULE B.6.95device_enable_srq behaves the same whether or not the link holds the lock.
What is checked: enabling interrupts is independent of locking: it must not return error 11 when another link holds the lock, and it must not block
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
device_enable_srq from an unlocked link -> 0 (no error) after 0 ms
🟢 VXI11-RULE-B.6.98 — device_docmd rejects an unsupported cmd with error 8
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | gen (gen) |
| Duration | 0.03 s |
Verifies:
VXI-11 RULE B.6.98device_docmd returns error 8 for a cmd value it does not support.VXI-11 PERM B.6.2A server may support none, some or all cmd values in device_docmd.
What is checked: cmd values are defined by the companion documents; a server may support none of them, but an unsupported cmd must come back as 'operation not supported' rather than as a generic failure
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
device_docmd(cmd=0x7EEE0001) -> 8 (operation not supported)
🟢 VXI11-RULE-B.6.107 — device_abort terminates an in-progress read with error 23
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Abort channel (abt) |
| Duration | 0.59 s |
Verifies:
VXI-11 RULE B.6.107After replying to device_abort the server replies to the aborted call with error 23.VXI-11 RULE B.6.106device_abort initiates termination of any in-progress core channel RPC on the link except destroy_link, device_enable_srq and device_unlock, and returns error 0.VXI-11 RULE B.6.29device_read returns error 23 if device_abort is called during it.
What is checked: an aborted operation returns 'abort' (error 23) promptly
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
device_abort -> 0 (no error)
pending read returned 23 (abort) after 578 ms
🟢 VXI11-RULE-B.6.108 — device_abort with an unknown link identifier gives error 4
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Abort channel (abt) |
| Duration | 0.02 s |
Verifies:
VXI-11 RULE B.6.108device_abort with an unmatched lid returns error 4.
What is checked: device_abort validates the lid like every other procedure
🟢 VXI11-RULE-B.6.109 — device_abort works while another link holds the lock
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Abort channel (abt) |
| Duration | 0.05 s |
Verifies:
VXI-11 RULE B.6.109device_abort is not affected by locking.
What is checked: the operation of device_abort is not affected by locking, so it must never return error 11 or wait for a lock
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
device_abort on the unlocked link -> 0 (no error) after 0 ms
🟢 VXI11-RULE-B.6.111 — An SRQ is delivered with the exact handle that was registered
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Interrupt channel (int) |
| Duration | 1.03 s |
Verifies:
VXI-11 RULE B.6.111device_intr_srq carries back the handle exactly as received in device_enable_srq.VXI-11 RULE B.6.110device_intr_srq is sent only when interrupts are enabled for the link and an interrupt channel exists.VXI-11 RULE B.3.1Interrupt messages use the given RPCL: device_intr_srq, procedure 30, program 0x0607B1, version 1, returning void.
What is checked: device_intr_srq carries back the handle unchanged
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
interrupt listener on 0.0.0.0:61361
create_intr_chan -> 192.168.3.3:61361
SRQ from ('192.168.3.2', 44511) with handle b'CONFORM-SRQ-01'
🟢 VXI11-RULE-C.1 — Error replies still carry the complete result structure
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | RPC layer (rpc) |
| Duration | 0.02 s |
Verifies:
VXI-11 RULE C.1The host implements the RPCL constructs of section C, including the full result structures of each reply.VXI-11 RULE B.1.3Messages are ONC/RPC compatible and use XDR at the presentation layer.
What is checked: Device_ReadResp, Device_WriteResp and Device_ReadStbResp are structs, not unions: every member is encoded even when error != 0
Protocol log
device_read error reply body = 12 bytes (expected >= 12)
device_write error reply body = 8 bytes (expected >= 8)
device_readstb error reply body = 8 bytes (expected >= 8)
🟢 VXI11-REC-B.2.1 — The abort channel is reachable while the core channel is busy
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Abort channel (abt) |
| Duration | 0.44 s |
Verifies:
VXI-11 REC B.2.1The abort channel should respond in a timely manner.
What is checked: the abort channel must be serviced independently of in-progress core operations
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
device_abort answered in 15 ms -> 0 (no error)
🟢 VXI11-REC-B.4.2 — Several links can be used concurrently without cross-talk
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Robustness (rob) |
| Duration | 0.08 s |
Verifies:
VXI-11 REC B.4.2An instrument's host should route at least two links to any device.VXI-11 RULE B.2.4RPCs performing I/O to the same device or interface are serialized.
What is checked: concurrent links are independent sessions
🟢 VXI11-REC-B.6.1 — A second link can be opened on the same device
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | Link lifecycle (lnk) |
| Duration | 0.03 s |
Verifies:
VXI-11 REC B.6.1A server should maintain at least two links on one connection.
What is checked: multiple links to one device are allowed; refusal must be error 9
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
🟢 VXI11-OBS-B.6.6 — A zero-length write is handled cleanly
| Result | 🟢 PASS |
| Severity | INFO |
| Suite | Read / write (io) |
| Duration | 0.00 s |
Verifies:
VXI-11 OBS B.6.6device_write with a zero-length data parameter performs no device action.
What is checked: an empty data parameter is legal; it must not hang or error out oddly
Observed: empty write -> 0 (no error)
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
empty write -> 0 (no error) size=0
🟢 VXI11-EXT-ABT-001 — The abort channel accepts an RPC null call
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Abort channel (abt) |
| Duration | 0.00 s |
Beyond the standard — this check has no counterpart in VXI-11; it covers interoperability or robustness the specification leaves open.
What is checked: the abort channel is a separate, always-available RPC service
Protocol log
abort channel NULL -> MSG_ACCEPTED/SUCCESS
🟢 VXI11-EXT-ABT-005 — device_abort with nothing in progress is harmless
| Result | 🟢 PASS |
| Severity | INFO |
| Suite | Abort channel (abt) |
| Duration | 0.03 s |
Beyond the standard — this check has no counterpart in VXI-11; it covers interoperability or robustness the specification leaves open.
What is checked: an abort with no operation pending is not an error condition
Observed: idle abort -> 0 (no error)
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
idle device_abort -> 0 (no error)
🟢 VXI11.2-EXT-CMD-001 — Bus Status rejects an undefined subcode
| Result | 🟢 PASS |
| Severity | INFO |
| Suite | cmd (cmd) |
| Duration | 0.02 s |
Beyond the standard — this check has no counterpart in VXI-11; it covers interoperability or robustness the specification leaves open.
What is checked: Table B.2 defines subcodes 1 to 8; the standard does not say what happens for others, so this only records the behaviour
Observed: subcode 99 -> 5 (parameter error)
Protocol log
interface link 0 on 'gpib0'
subcode 99 -> 5 (parameter error) (0 bytes)
🟢 VXI11.2-EXT-CMD-002 — Send Command respects the 128 byte limit
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | cmd (cmd) |
| Duration | 0.01 s |
Verifies:
VXI-11.2 RULE B.5.3A data_in_len or datasize conflicting with Table B.1 gives error 5 and no action; datasize X accepts any value.
What is checked: Table B.1 allows data_in_len 0 to 128 for Send Command; more than that conflicts with the table and should be a parameter error (RULE B.5.3)
Protocol log
interface link 0 on 'gpib0'
129 command bytes -> 5 (parameter error)
🟢 VXI11-EXT-GEN-001 — The generic operations leave the link usable
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | gen (gen) |
| Duration | 0.64 s |
Beyond the standard — this check has no counterpart in VXI-11; it covers interoperability or robustness the specification leaves open.
What is checked: trigger, clear, remote and local in sequence must not wedge the link or the server -- a practical follow-up to B.6.39 to B.6.70
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
device_trigger -> 0 (no error)
device_clear -> 0 (no error)
device_remote -> 0 (no error)
device_local -> 0 (no error)
🟢 VXI11-EXT-INT-005 — A handle longer than 40 bytes is a parameter error
| Result | 🟢 PASS |
| Severity | INFO |
| Suite | Interrupt channel (int) |
| Duration | 0.52 s |
Beyond the standard — this check has no counterpart in VXI-11; it covers interoperability or robustness the specification leaves open.
What is checked: Device_EnableSrqParms.handle is opaque<40>
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
interrupt listener on 0.0.0.0:53273
create_intr_chan -> 192.168.3.3:53273
41-byte handle -> 5 (parameter error)
🟢 VXI11-EXT-IO-005 — termChar outside 0..255 is a parameter error
| Result | 🟢 PASS |
| Severity | INFO |
| Suite | Read / write (io) |
| Duration | 0.03 s |
Beyond the standard — this check has no counterpart in VXI-11; it covers interoperability or robustness the specification leaves open.
What is checked: error 5 when termchrset is set and termChar is not a valid character
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
termChar=0x1234 -> 5 (parameter error)
🟢 VXI11-EXT-IO-010 — A write without the END flag does not terminate the message
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | Read / write (io) |
| Duration | 0.03 s |
Verifies:
VXI-11 RULE B.6.14With the end flag set, an END indicator accompanies the last byte.
What is checked: END (0x08) sets EOI on the last byte; without it the message continues
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
split write '*I' + 'DN?\n' -> 0 (no error) b'HEWLETT-PACKARD,34401A,0,5-1-1\n'
🟢 VXI11-EXT-IO-011 — device_read on a device with nothing pending does not return stale data
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | Read / write (io) |
| Duration | 1.56 s |
Beyond the standard — this check has no counterpart in VXI-11; it covers interoperability or robustness the specification leaves open.
What is checked: each read reflects the current transfer, not a cached buffer
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
follow-up read -> 15 (I/O timeout) b''
🟢 VXI11-EXT-IO-012 — Reserved bits in Device_Flags are ignored, not rejected
| Result | 🟢 PASS |
| Severity | INFO |
| Suite | Read / write (io) |
| Duration | 0.02 s |
Beyond the standard — this check has no counterpart in VXI-11; it covers interoperability or robustness the specification leaves open.
What is checked: only bits 0, 3 and 7 are defined; the rest are reserved
Observed: reserved flag bit -> 0 (no error)
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
device_write with flags=0x48 -> 0 (no error)
🟢 VXI11-EXT-LCK-007 — The lock owner can still use the device
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Locking (lck) |
| Duration | 0.02 s |
Verifies:
VXI-11 OBS B.6.18The server blocks when another link holds the lock, but not merely because another link is doing I/O.
What is checked: the holding link operates normally while locked
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
🟢 VXI11-EXT-LNK-003 — abortPort matches the port mapper's DEVICE_ASYNC entry
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | Link lifecycle (lnk) |
| Duration | 0.01 s |
Beyond the standard — this check has no counterpart in VXI-11; it covers interoperability or robustness the specification leaves open.
What is checked: abortPort identifies the abort channel for this link
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
🟢 VXI11-EXT-LNK-006 — create_link on a nonexistent device name is refused
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Link lifecycle (lnk) |
| Duration | 0.00 s |
Beyond the standard — this check has no counterpart in VXI-11; it covers interoperability or robustness the specification leaves open.
What is checked: an unknown device gives error 3 (not accessible) or 21 (invalid address)
🟢 VXI11-EXT-LNK-007 — create_link with a syntactically invalid device name is refused
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | Link lifecycle (lnk) |
| Duration | 0.03 s |
Beyond the standard — this check has no counterpart in VXI-11; it covers interoperability or robustness the specification leaves open.
What is checked: device names follow inst
Protocol log
create_link('!!!not a device!!!') -> 5 (parameter error)
create_link('gpib0,not_a_number') -> 5 (parameter error)
create_link('xxxxxxxxxxxxxxxxxxxxxxxx') -> 5 (parameter error)
🟢 VXI11-EXT-LNK-011 — A link is not usable from a different core connection
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | Link lifecycle (lnk) |
| Duration | 0.02 s |
Beyond the standard — this check has no counterpart in VXI-11; it covers interoperability or robustness the specification leaves open.
What is checked: links belong to the channel that created them; a foreign lid is invalid
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
readstb on connection B with A's lid -> 4 (invalid link identifier)
🟢 VXI11-EXT-PM-003 — DEVICE_ASYNC (0x0607B0) v1 is registered
| Result | 🟢 PASS |
| Severity | INFO |
| Suite | Port mapper (pm) |
| Duration | 0.02 s |
Beyond the standard — this check has no counterpart in VXI-11; it covers interoperability or robustness the specification leaves open.
What is checked: not required: VXI-11 delivers the abort port in the create_link reply (RULE B.6.3) and only the core channel is registered with the port mapper (Figure B.12). Registering the abort program too is harmless and helps tools that go looking for it.
Protocol log
abort channel on port 34568
🟢 VXI11-EXT-PM-004 — GETPORT for an unregistered program returns 0, not an error
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | Port mapper (pm) |
| Duration | 0.00 s |
Beyond the standard — this check has no counterpart in VXI-11; it covers interoperability or robustness the specification leaves open.
What is checked: GETPORT yields port 0 when no mapping exists
🟢 VXI11-EXT-PM-005 — GETPORT for a wrong version of DEVICE_CORE does not resolve to v1
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | Port mapper (pm) |
| Duration | 0.00 s |
Beyond the standard — this check has no counterpart in VXI-11; it covers interoperability or robustness the specification leaves open.
What is checked: mappings are per (prog, vers, prot)
🟢 VXI11-EXT-PM-008 — Port mapper handles PMAPPROC_DUMP or rejects it cleanly
| Result | 🟢 PASS |
| Severity | INFO |
| Suite | Port mapper (pm) |
| Duration | 0.03 s |
Beyond the standard — this check has no counterpart in VXI-11; it covers interoperability or robustness the specification leaves open.
What is checked: DUMP is optional in practice; it must not wedge the server
Observed: DUMP supported
Protocol log
PMAPPROC_DUMP -> MSG_ACCEPTED/SUCCESS
🟢 VXI11-EXT-PM-009 — Port mapper survives a GETPORT with truncated arguments
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | Port mapper (pm) |
| Duration | 15.03 s |
Beyond the standard — this check has no counterpart in VXI-11; it covers interoperability or robustness the specification leaves open.
What is checked: undecodable arguments give GARBAGE_ARGS, not a dropped service
Protocol log
truncated GETPORT -> no reply within 15.0s from 192.168.3.2:111
🟢 VXI11-EXT-ROB-003 — A very large requestSize does not upset the server
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | Robustness (rob) |
| Duration | 2.09 s |
Beyond the standard — this check has no counterpart in VXI-11; it covers interoperability or robustness the specification leaves open.
What is checked: requestSize is a u_long; the server must clamp it, not trust it
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
requestSize=0x7FFFFFFF -> 15 (I/O timeout), 0 bytes
🟢 VXI11-EXT-ROB-005 — Bare TCP connects and disconnects do not exhaust the server
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | Robustness (rob) |
| Duration | 0.20 s |
Beyond the standard — this check has no counterpart in VXI-11; it covers interoperability or robustness the specification leaves open.
What is checked: half-open or abandoned connections must be cleaned up
🟢 VXI11-EXT-ROB-006 — The server is still healthy at the end of the run
| Result | 🟢 PASS |
| Severity | INFO |
| Suite | Robustness (rob) |
| Duration | 0.03 s |
Beyond the standard — this check has no counterpart in VXI-11; it covers interoperability or robustness the specification leaves open.
What is checked: Sanity check: everything above must leave the device usable
Protocol log
link 0 opened on 'gpib0,4' (maxRecvSize=1024 abortPort=34568)
final readstb -> 0 (no error)
🟢 VXI11-EXT-RPC-004 — Truncated arguments give GARBAGE_ARGS rather than a dropped connection
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | RPC layer (rpc) |
| Duration | 0.01 s |
Verifies:
VXI-11 RULE B.1.3Messages are ONC/RPC compatible and use XDR at the presentation layer.
What is checked: undecodable arguments are reported as GARBAGE_ARGS
Protocol log
truncated create_link -> MSG_ACCEPTED/GARBAGE_ARGS
🟢 VXI11-EXT-RPC-005 — An RPC version other than 2 is denied with RPC_MISMATCH
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | RPC layer (rpc) |
| Duration | 0.02 s |
Verifies:
VXI-11 RULE B.1.3Messages are ONC/RPC compatible and use XDR at the presentation layer.
What is checked: MSG_DENIED/RPC_MISMATCH when rpcvers != 2
Protocol log
rpcvers=3 -> MSG_DENIED/RPC_MISMATCH (low=2 high=2)
🟢 VXI11-EXT-RPC-006 — The reply carries the transaction id of the call
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | RPC layer (rpc) |
| Duration | 0.03 s |
Verifies:
VXI-11 RULE B.1.3Messages are ONC/RPC compatible and use XDR at the presentation layer.
What is checked: the xid of a reply matches the call it answers
Protocol log
xid sent 0x0badc0de, received 0x0badc0de
🟢 VXI11-EXT-RPC-007 — A call split across several record fragments is reassembled
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | RPC layer (rpc) |
| Duration | 0.02 s |
Verifies:
VXI-11 RULE B.1.3Messages are ONC/RPC compatible and use XDR at the presentation layer.
What is checked: record marking allows any fragmentation; the last fragment sets the high bit
Protocol log
fragmented create_link -> MSG_ACCEPTED/SUCCESS
🟢 VXI11-EXT-RPC-008 — AUTH_UNIX credentials are accepted
| Result | 🟢 PASS |
| Severity | SHOULD |
| Suite | RPC layer (rpc) |
| Duration | 0.02 s |
Verifies:
VXI-11 RULE B.1.3Messages are ONC/RPC compatible and use XDR at the presentation layer.
What is checked: servers that require no authentication must still accept AUTH_UNIX
Protocol log
AUTH_UNIX create_link -> MSG_ACCEPTED/SUCCESS
🟢 VXI11-EXT-RPC-009 — The reply verifier is AUTH_NONE with an empty body
| Result | 🟢 PASS |
| Severity | INFO |
| Suite | RPC layer (rpc) |
| Duration | 0.01 s |
Verifies:
VXI-11 RULE B.1.3Messages are ONC/RPC compatible and use XDR at the presentation layer.
What is checked: a server that does not authenticate replies with a null verifier
Protocol log
reply verf flavor=0 len=0
🟢 VXI11-EXT-RPC-011 — The server survives garbage on the core port
| Result | 🟢 PASS |
| Severity | MUST |
| Suite | RPC layer (rpc) |
| Duration | 0.02 s |
Beyond the standard — this check has no counterpart in VXI-11; it covers interoperability or robustness the specification leaves open.
What is checked: malformed input must not take the service down
Protocol log
post-garbage create_link -> MSG_ACCEPTED/SUCCESS
Generated by make_report.py from report.json.
The regression suite
Compliance is one axis; not breaking what already worked is the other. The VXI-11 regression suite runs against a real GPIBEE with a real instrument on the bus — an HP 3457A multimeter at GPIB address 22 — and checks behaviour rather than protocol letter:
- GPIB primitives — device clear, trigger, status byte read, read termination, SRQ signalling, all verified against what the instrument actually does
- Locking — simple locks, repeated lock and unlock calls, whether destroying a link releases its lock, how an unlocked link behaves while another holds the lock, locking at link creation time
- Timeouts — requested versus measured I/O timeout across five decades of duration, lock timeouts, and whether a lock correctly extends an I/O timeout instead of eating into it
- Resource limits — how many concurrent links the server really sustains, and whether it is still responsive afterwards
- Instance names — which of
inst0,gpib0,hpib0and their addressed variants must open and which must be rejected - The internal SCPI interface — every adjustable parameter checked for its default, for accepting a valid change, and for rejecting an out-of-range value and clamping to a sane one
- Unsynchronised simultaneous access — four threads hammering the same instrument through separate links with no locking at all, which is exactly what a user does by accident
Not all of these were planned coverage. Several of the test cases in this suite started life as issue reports and were turned into permanent tests afterwards, which is the rule here: a reported problem becomes a regression test, and that test then runs before every firmware release. A bug that made it into the field once does not get a second chance to come back quietly in a later version.
Here is the log of a full run — 18 test cases, about 52 seconds, every step recorded with the values it measured:
GPIBee DUT details:
- Serial#: LJPAT, FW: V1.5.2608231401
Table of contents
- Summarized testcase results
- Detailed testcase logs
- basic_gpib_primitives
- basic_vxi-11_connectiontest
- exclusivelock_check_unlocked_link_behavior
- exclusivelock_does_destroy_link_unlock
- exclusivelock_multiple_lockcalls
- exclusivelock_simple
- instancenames
- internal_scpi_param_change
- internal_scpi_param_defaults
- internal_scpi_param_limits
- io_timeout
- lock_on_link_creation
- lock_timeout
- max_connectioncount
- scan
- timeout_behavior_on_locked_link_with_no_wait_lock
- timeout_extension_by_lock
- unsynchronized_simultaneous_access
Summarized testcase results
| Testcase name | Result | Duration [s] | Additional details |
|---|---|---|---|
| basic_gpib_primitives | ✅ PASSED | 9.063 | |
| basic_vxi-11_connectiontest | ✅ PASSED | 0.013 | |
| exclusivelock_check_unlocked_link_behavior | ✅ PASSED | 0.049 | |
| exclusivelock_does_destroy_link_unlock | ✅ PASSED | 0.019 | |
| exclusivelock_multiple_lockcalls | ✅ PASSED | 0.016 | |
| exclusivelock_simple | ✅ PASSED | 0.006 | |
| instancenames | ✅ PASSED | 0.033 | |
| internal_scpi_param_change | ✅ PASSED | 1.189 | |
| internal_scpi_param_defaults | ✅ PASSED | 0.076 | |
| internal_scpi_param_limits | ✅ PASSED | 0.631 | |
| io_timeout | ✅ PASSED | 8.823 | |
| lock_on_link_creation | ✅ PASSED | 1.074 | |
| lock_timeout | ✅ PASSED | 8.472 | |
| max_connectioncount | ✅ PASSED | 1.921 | |
| scan | ✅ PASSED | 0.089 | |
| timeout_behavior_on_locked_link_with_no_wait_lock | ✅ PASSED | 0.576 | |
| timeout_extension_by_lock | ✅ PASSED | 14.686 | |
| unsynchronized_simultaneous_access | ✅ PASSED | 5.449 |
Overall result: ✅ PASSED
Total duration: ⏱ 52.183 seconds
Detailed testcase logs
basic_gpib_primitives
Testcase description
Test some basic GPIB functionality: Clearing, triggering, status byte reading. This testcases expects a HP3458A on GPIB address 22.
Log
Using visa provider: rs
Subtest: Trying to read measurement results from the instrument in auto trigger mode.
Result of 5 reads: 2.3713700E+00\r\n / 2.3715830E+00\r\n / 2.3716510E+00\r\n / 2.3713800E+00\r\n / 2.3715860E+00\r\n
Subtest: Clearing and trying to read. If clear was successful we should run into a timeout.
As expected, we ran into a timeout.
Subtest: Testing Status byte reading
Status byte reading worked. Value = 0x58
Subtest: Testing trigger function
Results: 2.3793640E+00\r\n / [read did not work as exepected] / 2.3799860E+00\r\n / [read did not work as exepected] / 2.3810750E+00\r\n / [read did not work as exepected] / 2.3827190E+00\r\n / [read did not work as exepected]
Trigger functionality confirmed working.
Subtest: Test read termination setting
response parts: part1 = "HP34", part2 = "57A\r\n"
Read termination setting worked correctly.
disabling read termination character and reading ID? query again
Query response: HP3457A\r\n
response is correct as expected
Subtest: Testing SRQ signalling
SRQ properly signalled
Summary: - test result: ✅ PASSED - duration: 9.063s
basic_vxi-11_connectiontest
Testcase description
Basic vxi-11 connection test. Used also to query GPIBee FW version / serial number for logging purposes
Log
Using visa provider: pyvisa-py
Creating link
Execute *IDN? query
Summary: - test result: ✅ PASSED - duration: 0.013s
exclusivelock_check_unlocked_link_behavior
Testcase description
Test locking behavior on unlocked instance.
Log
Using visa provider: pyvisa-py
1st Query failed as expected
2nd Query result = XYPHROLABS,GPIBEE,LJPAT,V1.5.2608231401\r\n
Summary: - test result: ✅ PASSED - duration: 0.049s
exclusivelock_does_destroy_link_unlock
Testcase description
Test if destroying a link does remove a lock
Log
Using visa provider: pyvisa-py
Creating first link
Creating second link
Lock 2nd link
Trying if 1st link is really locked as expected
1st Query failed as expected
destroying 2nd link
trying if 1st link is responsive
2nd Query result = XYPHROLABS,GPIBEE,LJPAT,V1.5.2608231401\r\n
Summary: - test result: ✅ PASSED - duration: 0.019s
exclusivelock_multiple_lockcalls
Testcase description
Test if multiple lock and unlock tries return an error on 2nd, 3rd, ... lock and not on 1st.
Log
Using visa provider: pyvisa-py
Checking multiple lock behavior
Trying Lock #1
Locking worked without error
Trying Lock #2
Lock returned an error
Trying Lock #3
Lock returned an error
Trying Lock #4
Lock returned an error
Checking multiple unlock behavior
Trying Unlock #1
Unlocking worked without error
Trying Unlock #2
Unlock returned an error
Trying Unlock #3
Unlock returned an error
Trying Unlock #4
Unlock returned an error
Summary: - test result: ✅ PASSED - duration: 0.016s
exclusivelock_simple
Testcase description
create a link, lock it, then create a new link and check if opening fails as expected
Log
Using visa provider: pyvisa-py
opening ressource TCPIP::192.168.3.2::inst0::INSTR
Locking device
Trying to open a 2nd instance to the same device
Summary: - test result: ✅ PASSED - duration: 0.006s
instancenames
Testcase description
Trying to open different flavors of VXI-11 instance names
Log
Using visa provider: pyvisa-py
opening ressource TCPIP::192.168.3.2::inst0::INSTR
opened successfully
opening ressource TCPIP::192.168.3.2::gpib0::INSTR
opened successfully
opening ressource TCPIP::192.168.3.2::hpib0::INSTR
opened successfully
opening ressource TCPIP::192.168.3.2::inst,22::INSTR
open failed
opening ressource TCPIP::192.168.3.2::gpib,22::INSTR
open failed
opening ressource TCPIP::192.168.3.2::hpib,22::INSTR
open failed
opening ressource TCPIP::192.168.3.2::inst0,22::INSTR
opened successfully
opening ressource TCPIP::192.168.3.2::gpib0,22::INSTR
opened successfully
opening ressource TCPIP::192.168.3.2::hpib0,22::INSTR
opened successfully
opening ressource TCPIP::192.168.3.2::inst1::INSTR
open failed
opening ressource TCPIP::192.168.3.2::gpib1::INSTR
open failed
opening ressource TCPIP::192.168.3.2::inst0,240::INSTR
open failed
Summary: - test result: ✅ PASSED - duration: 0.033s
internal_scpi_param_change
Testcase description
Check the internal scpi command parameters can be changed.
Log
Using visa provider: pyvisa-py
Creating link
Resetting settings to presets
Trying to apply new values
Reading out default values
Resetting settings to presets
Parameter name New value applied Actual value Passed? SYSTem:COMMunicate:LAN:IPADdress "10.0.0.5" "10.0.0.5" PASSED SYSTem:COMMunicate:LAN:SUBNet "255.255.0.0" "255.255.0.0" PASSED SYSTem:COMMunicate:LAN:DHCP OFF OFF PASSED SYSTem:COMMunicate:LAN:MDNS OFF OFF PASSED SYSTem:COMMunicate:LAN:SSDP OFF OFF PASSED SYSTem:COMMunicate:LAN:HOSTname "MYDEVICE" "MYDEVICE" PASSED SYSTem:COMMunicate:LAN:DHCP:TIMEout 11 11 PASSED SYSTem:COMMunicate:LAN:PPprot OFF OFF PASSED SYSTem:COMMunicate:USB:FALLback 15 15 PASSED SYSTem:COMMunicate:USB:FORCEfullspeed ON ON PASSED SYSTem:COMMunicate:USBTMC:NAME "USBTMCDEVICE" "USBTMCDEVICE" PASSED SYSTem:COMMunicate:USBTMC:DELAY 10 10 PASSED SYSTem:COMMunicate:USBTMC:AUTOidRETry 13 13 PASSED SYSTem:COMMunicate:USBTMC:SCANSTARTaddr 2 2 PASSED SYSTem:COMMunicate:USB:PROTocol USBTMC USBTMC PASSED SYSTem:COMMunicate:GPIB:T1TIME 700 700 PASSED SYSTem:COMMunicate:USBNET:IPADdress "192.168.5.2" "192.168.5.2" PASSED SYSTem:COMMunicate:VXI11:PRESENCEcheck OFF OFF PASSED SYSTem:COMMunicate:VXI11:MINimumIOTimeOut 42 42 PASSED SYSTem:COMMunicate:VXI11:MAXimumIOTimeOut 1600 1600 PASSED SYSTem:COMMunicate:VXI11:SRQAUTOpoll ON ON PASSED SYSTem:COMMunicate:USBTMC:suppressIDN ON ON PASSED SYSTem:COMMunicate:GPIB:CTRLADdress 22 22 PASSED Summary: - test result: ✅ PASSED - duration: 1.189s
internal_scpi_param_defaults
Testcase description
Test the the internal SCPI adjustable parameters have correct default settings.
Log
Using visa provider: pyvisa-py
Creating link
Resetting settings to presets
Reading out default values
Parameter name Expected default value Actual default value Correct? SYSTem:COMMunicate:LAN:IPADdress "192.168.1.2" "192.168.1.2" correct SYSTem:COMMunicate:LAN:SUBNet "255.255.255.0" "255.255.255.0" correct SYSTem:COMMunicate:LAN:DHCP ON ON correct SYSTem:COMMunicate:LAN:MDNS ON ON correct SYSTem:COMMunicate:LAN:SSDP ON ON correct SYSTem:COMMunicate:LAN:HOSTname "GPIBEE-{UID}" "GPIBEE-{UID}" correct SYSTem:COMMunicate:LAN:DHCP:TIMEout 15 15 correct SYSTem:COMMunicate:LAN:PPprot ON ON correct SYSTem:COMMunicate:USB:FALLback 4 4 correct SYSTem:COMMunicate:USB:FORCEfullspeed OFF OFF correct SYSTem:COMMunicate:USBTMC:NAME "GPIB-{ADDR}-{UID}" "GPIB-{ADDR}-{UID}" correct SYSTem:COMMunicate:USBTMC:DELAY 1 1 correct SYSTem:COMMunicate:USBTMC:AUTOidRETry 0 0 correct SYSTem:COMMunicate:USBTMC:SCANSTARTaddr 1 1 correct SYSTem:COMMunicate:USB:PROTocol NET NET correct SYSTem:COMMunicate:USBNET:IPADdress "192.168.3.2" "192.168.3.2" correct SYSTem:COMMunicate:VXI11:PRESENCEcheck ON ON correct SYSTem:COMMunicate:VXI11:MINimumIOTimeOut 10 10 correct SYSTem:COMMunicate:VXI11:SRQAUTOpoll OFF OFF correct SYSTem:COMMunicate:GPIB:T1TIME 500 500 correct SYSTem:COMMunicate:VXI11:MAXimumIOTimeOut 30000 30000 correct SYSTem:COMMunicate:USBTMC:suppressIDN OFF OFF correct SYSTem:COMMunicate:GPIB:CTRLADdress 0 0 correct Summary: - test result: ✅ PASSED - duration: 0.076s
internal_scpi_param_limits
Testcase description
Test if boundary/correctness checks on internal SCPI commands parameter set functions work.
Log
Using visa provider: pyvisa-py
Creating link
Resetting settings to presets
Applying on purpose wrong values
Resetting settings to presets
Parameter name Incorrect value applied Expected value Actual value Passed? SYSTem:COMMunicate:LAN:IPADdress "224.168.1.2" "192.168.1.2" "192.168.1.2" PASSED SYSTem:COMMunicate:LAN:SUBNet "255.255.6.255" "255.255.0.0" "255.255.0.0" PASSED SYSTem:COMMunicate:LAN:DHCP 2 ON ON PASSED SYSTem:COMMunicate:LAN:MDNS -1 ON ON PASSED SYSTem:COMMunicate:LAN:SSDP 5 ON ON PASSED SYSTem:COMMunicate:LAN:HOSTname "GPIBEE- {UID}" "GPIBEE-{UID}" "GPIBEE-{UID}" PASSED SYSTem:COMMunicate:LAN:DHCP:TIMEout 1000 30 30 PASSED SYSTem:COMMunicate:LAN:PPprot 3 ON ON PASSED SYSTem:COMMunicate:USB:FALLback -1 30 30 PASSED SYSTem:COMMunicate:USB:FORCEfullspeed 4 OFF OFF PASSED SYSTem:COMMunicate:USBTMC:NAME "-GPIB-{ADDR}{UID}" "GPIB-{ADDR}_{UID}" "GPIB-{ADDR}_{UID}" PASSED SYSTem:COMMunicate:USBTMC:DELAY 1000 30 30 PASSED SYSTem:COMMunicate:USBTMC:AUTOidRETry 1000 600 600 PASSED SYSTem:COMMunicate:USBTMC:SCANSTARTaddr 31 30 30 PASSED SYSTem:COMMunicate:USB:PROTocol ETHERNET NET NET PASSED SYSTem:COMMunicate:USBNET:IPADdress "224.0.0.0" "192.168.3.2" "192.168.3.2" PASSED SYSTem:COMMunicate:VXI11:PRESENCEcheck 7 ON ON PASSED SYSTem:COMMunicate:VXI11:SRQAUTOpoll 5 OFF OFF PASSED SYSTem:COMMunicate:GPIB:T1TIME 2500 2000 2000 PASSED SYSTem:COMMunicate:GPIB:T1TIME 0 350 350 PASSED SYSTem:COMMunicate:VXI11:MINimumIOTimeOut 20000 5000 5000 PASSED SYSTem:COMMunicate:VXI11:MAXimumIOTimeOut 480000 30000 30000 PASSED SYSTem:COMMunicate:USBTMC:suppressIDN 5 OFF OFF PASSED SYSTem:COMMunicate:GPIB:CTRLADdress 32 30 30 PASSED Summary: - test result: ✅ PASSED - duration: 0.631s
io_timeout
Testcase description
Test if io timeout values are correctly considered. Made for HP3457a on GPIB address 22.
Note, that the measured values include additional overhead and is not a pure measurement of network call to reply time.
Log
Allowed timing inaccuracy: 800.0ms
Using visa provider: rs
Creating link
Ensuring that the instrument is not responding to reads.
Starting IO timeout measurement
Testing timeout of 5000.0ms
Testing timeout of 2000.0ms
Testing timeout of 1000.0ms
Testing timeout of 100.0ms
Testing timeout of 10.0ms
Requested timeout duration [ms] Actual measured timeout duration [ms] Actual - measured duration [ms] 5000.000 5026.149 26.149 2000.000 2062.899 62.899 1000.000 1030.070 30.070 100.000 129.161 29.161 10.000 34.036 24.036 Summary: - test result: ✅ PASSED - duration: 8.823s
lock_on_link_creation
Testcase description
Test several VXI-11 locking scenarios where link creation is involved.
Log
TRY 1 with VXI11 GPIB device presence check in state ON
Testing if opening a device with lock requested does really lock
SUCCESS: CREATE_LINK with LockDevice=1 does lock the device as expected
Testing if opening a locked device works when the new connection is done without lock (Rule B.6.6).
SUCCESS: CREATE_LINK with LockDevice=0 is manages to connect to a command
Summary: - test result: ✅ PASSED - duration: 1.074s
lock_timeout
Testcase description
Test if lock timeout values are correctly considered. Uses HP3457a on GPIB address 22.
Note, that the measured values include additional overhead and is not a pure measurement of network call to reply time.
Log
Allowed timing inaccuracy: 150.0ms
Using visa provider: rs
Creating 1st link - used to lock and unlock instrument
Ensuring that instrument is in auto trigger mode via 1st link
Creating 2nd link - used to measure lock timeout duration
Locking via 1st link the instrument (2nd link is already acquired)
Starting IO timeout measurement
Testing timeout of 5000.0ms
Testing timeout of 2000.0ms
Testing timeout of 1000.0ms
Testing timeout of 100.0ms
Testing timeout of 10.0ms
Requested timeout duration [ms] Actual measured timeout duration [ms] Actual - measured duration [ms] 5000.000 5050.052 50.052 2000.000 2051.148 51.148 1000.000 1051.458 51.458 100.000 151.293 51.293 10.000 60.652 50.652 Summary: - test result: ✅ PASSED - duration: 8.472s
max_connectioncount
Testcase description
Test how many concurrent connections can be made. This test tests VXI-11 server stack limits.
Log
Using visa provider: rs
Creating link #1
Communication with all 1 active connections worked
Creating link #2
Communication with all 2 active connections worked
Creating link #3
Communication with all 3 active connections worked
Creating link #4
Communication with all 4 active connections worked
Creating link #5
Communication with all 5 active connections worked
Creating link #6
Communication with all 6 active connections worked
Creating link #7
Communication with all 7 active connections worked
Creating link #8
Communication with all 8 active connections worked
Creating link #9
Communication with all 9 active connections worked
Creating link #10
Communication with all 10 active connections worked
Creating link #11
Communication with all 11 active connections worked
Creating link #12
Communication with all 12 active connections worked
Creating link #13
Communication with all 13 active connections worked
Creating link #14
Communication with all 14 active connections worked
Creating link #15
Communication with all 15 active connections worked
Creating link #16
Communication with all 16 active connections worked
Creating link #17
Communication with all 17 active connections worked
Creating link #18
Communication with all 18 active connections worked
Creating link #19
Communication with all 19 active connections worked
Creating link #20
Communication with all 20 active connections worked
Creating link #21
Communication with all 21 active connections worked
Creating link #22
Communication with all 22 active connections worked
Creating link #23
Communication with all 23 active connections worked
Creating link #24
Communication with all 24 active connections worked
Creating link #25
Communication with all 25 active connections worked
Creating link #26
Communication with all 26 active connections worked
Creating link #27
Communication with all 27 active connections worked
Creating link #28
Communication with all 28 active connections worked
Creating link #29
link creation failed after 28 active connections
Maximum connection count reached: 28, we expected 27 simultaneous connections to work
Closing all connections
opening one connection again to see if GPIBee is stil responsive
Success! Query result: XYPHROLABS,GPIBEE,LJPAT,V1.5.2608231401
Summary: - test result: ✅ PASSED - duration: 1.921s
scan
Testcase description
Testing if the GPIB scan function works
Log
Using visa provider: pyvisa-py
Scan result: "22"
Summary: - test result: ✅ PASSED - duration: 0.089s
timeout_behavior_on_locked_link_with_no_wait_lock
Testcase description
Test if timeouts on locked devices is "close to zero" when no WAIT_LOCK is active
Note, that the measured values include additional overhead and is not a pure measurement of network call to reply time.
Log
Allowed timing inaccuracy: 600.0ms
Using visa provider: rs
Creating 1st link - used to lock and unlock instrument
Ensuring that instrument is not responding to reads
Creating 2nd link - used to measure lock timeout duration
Locking via 1st link the instrument (2nd link is already acquired)
Testing if a non WAIT_LOCK transaction on a locked link is returning "immediately"
Duration of read timeout: 1.004ms
Summary: - test result: ✅ PASSED - duration: 0.576s
timeout_extension_by_lock
Testcase description
Test if timeouts extend in time when a lock is active. iotimeout should only start counting once lock is acquired if WAIT_LOCK is 1. This testcases blocks with a lock for a defined time and then releaes it to see if this extension is visible.
Note, that the measured values include additional overhead and is not a pure measurement of network call to reply time.
Log
Allowed timing inaccuracy: 600.0ms
Using visa provider: rs
Creating 1st link - used to lock and unlock instrument
Ensuring that instrument is not responding to reads
Creating 2nd link - used to measure lock timeout duration
Locking via 1st link the instrument (2nd link is already acquired)
Starting IO timeout measurement
Testing timeout of 5000.0ms
[started exclusive locking in a seperate thread] Locking for 2 seconds
Kicked off read.
[stopped exclusive locking]
Testing timeout of 2000.0ms
[started exclusive locking in a seperate thread] Locking for 2 seconds
Kicked off read.
[stopped exclusive locking]
Testing timeout of 1000.0ms
[started exclusive locking in a seperate thread] Locking for 2 seconds
Kicked off read.
[stopped exclusive locking]
Lock duration [ms] Requested io timeout duration [ms] Expected overall timeout duration [ms] Actual measured overall timeout duration [ms] measured - Expected [ms] 2000.000 5000.000 7000.000 7118.497 118.497 2000.000 2000.000 4000.000 3970.012 -29.988 2000.000 1000.000 3000.000 3000.970 0.970 Summary: - test result: ✅ PASSED - duration: 14.686s
unsynchronized_simultaneous_access
Testcase description
Access GPIBee with multiple clients simultaneously in an asynchronous manner to see if any issues occur without locking. This requires a HP3457 to be present on GPIB address 22. Addresses https://github.com/xyphro/GpiBee/issues/33
Log
Creating link
Ensuring that instrument is in auto trigger mode
[started] Thread 0
[started] Thread 1
[started] Thread 2
[started] Thread 3
Thread 0 HP3457A
Thread 1 2.4181210E+00
Thread 2 2.4185260E+00
Thread 3 HP3457A
Thread 0 2.4182650E+00
Thread 1 2.4183580E+00
Thread 2 2.4182730E+00
Thread 3 HP3457A
Thread 0 2.4179380E+00
Thread 1 2.4178230E+00
Thread 2 2.4178170E+00
Thread 3 HP3457A
Thread 0 2.4175030E+00
Thread 1 2.4175770E+00
Thread 2 2.4174770E+00
Thread 3 HP3457A
Thread 0 2.4169550E+00
Thread 1 2.4169850E+00
Thread 2 2.4168540E+00
Thread 3 HP3457A
Thread 0 2.4161040E+00
Thread 1 2.4162460E+00
Thread 2 2.4164140E+00
Thread 3 HP3457A
Thread 0 2.4160120E+00
Thread 1 2.4160030E+00
Thread 2 2.4159310E+00
Thread 3 HP3457A
Thread 0 2.4153660E+00
Thread 1 2.4153460E+00
Thread 2 2.4152950E+00
Thread 3 HP3457A
Thread 0 2.4147510E+00
Thread 1 2.4146660E+00
Thread 2 2.4146430E+00
Thread 3 HP3457A
Thread 0 2.4141840E+00
Thread 1 2.4141710E+00
Thread 2 2.4141270E+00
Thread 3 HP3457A
Thread 0 2.4130850E+00
Thread 1 2.4128990E+00
Thread 2 2.4134360E+00
Thread 3 HP3457A
Thread 0 2.4127280E+00
Thread 1 2.4126050E+00
Thread 2 2.4127320E+00
Thread 3 HP3457A
[stopped] Thread 3
Thread 0 2.4119290E+00
[stopped] Thread 0
Thread 1 2.4119380E+00
[stopped] Thread 1
Thread 2 2.4119680E+00
[stopped] Thread 2
Summary: - test result: ✅ PASSED - duration: 5.449s
What cannot be automated
Suites cover what a machine can judge on its own. A good part of the testing here is still done by hand, because some things simply have no automated verdict.
The clearest case is anything you have to look at. Whether an instrument really went to remote and back to local, whether its front panel locked out, what the display shows after a device clear — the bus says one thing, the front panel is the ground truth, and only a person standing in front of the instrument can confirm the two agree. The same goes for the button behaviour on GPIBEE itself, the LED indications, and the firmware update procedure, where the device appears as a virtual flash drive and the interesting part is what the host operating system decides to do with it.
The other case is anything that needs a differently configured machine. Every VISA implementation behaves slightly differently — in what it sends during discovery, in which parts of VXI-11 or USBTMC it uses, in how it maps its own timeout settings onto the protocol. Each of them is tested with its own script, run by hand against that VISA on a machine where it is installed. These are deliberately not part of a suite: they are not portable, they depend on a specific installation on a specific operating system, and turning them into one automated run would mean maintaining a farm of machines rather than testing.
Manual testing does not scale, which is exactly why the automated suites exist. But pretending that everything worth checking can be checked by a script is how the observable, physical half of a bench instrument's behaviour ends up untested.
Other people's eyes
Everything described so far has one structural weakness: I wrote it. When the person who does the implementation is also the person who tests it, you go blind — not through carelessness, but because you test what you built, in the way you imagined it being used, with the assumptions that produced the design in the first place. The paths you never thought of are exactly the ones you never think to check.
So a group of beta testers received GPIBEE adapters free of charge, with instruments, benches, host systems and habits that are nothing like mine. They found a lot. Third-party feedback is not a nice extra here; it is the only reliable way to find the class of problem that is invisible from the inside.
And it did not stop at defects. A good share of what they reported was not "this is broken" but "why can it not do this" — and several features exist because somebody outside the project asked for them while using the device for real work. Both outcomes matter, but the second one is the one I could not have produced on my own at any amount of testing effort.
What this means for the next firmware
The upcoming firmware release is a significant step up in both quality and VXI-11 compliance. It is worth being precise about what that does and does not mean for you: almost none of the issues the compliance suite uncovered would have affected a normal VISA-based setup, because a VISA never goes near those code paths. If your measurements have been working, they were working. What changed is that the parts nobody was exercising are now correct too — which matters the moment somebody writes against VXI-11 directly, or a VISA implementation decides to use more of the standard than the last one did.
A long-term test is also running continuously on real hardware, looking for the class of problem that only appears after hours or days rather than seconds. Its results will be picked up in later news articles here, as they come in.
Why this much effort
I am, frankly, paranoid about defects. An instrument adapter sits in the middle of somebody else's measurement: if it is subtly wrong, it does not announce itself, it just quietly corrupts a result someone will trust. The highest objective of GPIBEE is functionally correct operation — ahead of features, ahead of speed, ahead of release dates. Every suite above exists so that claim is something I can point at rather than something I assert.
And it comes back to where this started: a feature that is not tested is a feature that does not work. The tests are not there to prove the firmware is good. They are there because, without them, I have no reason to believe it is.