OsprioView — Conformance Workspace

OSDP Conformance & Verification Testing

Compliance claims become repeatable evidence

Conformance Workspace is the Osprio View tool for semi-automated OSDP conformance testing and interoperability verification. Drive a structured test plan against a peripheral (PD) or controller (ACU) at your desk and take away a detailed report of exactly how it behaved — command by command, down to the physical layer — to qualify a device in CI and ease the path to SIA OSDP Verified.

113runnable tests
15test suites
20operator-led
2DUT roles
Every test we run, published in full — preconditions, procedure, expected outcome
The conformance bench

One host, two roles on the wire

A conformance run is split across three responsibilities on a shared RS-485 bus. Osprio View orchestrates the whole thing from your host; a first Osprio Mini plays the opposite role to your device under test and actively exercises it; a second Osprio Mini does nothing but listen, so the evidence behind every verdict comes from an independent witness rather than the device that generated the traffic.

Host — orchestration & verdict

Osprio View owns the run end to end: it walks the plan, tells the conformer what to do at each step, and gates progress on the results. When a step completes it reads the captured bus trace, checks the exact bytes and their timing on the wire against what the spec requires, and records a pass, fail, or not-applicable — then rolls it all into the report.

Conformer — drives the DUT

One Osprio Mini stands in as the counterpart your device expects to talk to — an ACU when you are testing a PD, a PD when you are testing an ACU. The host drives it to issue commands, provoke edge cases, and inject faults, so the DUT is exercised by a controlled peer whose behaviour is known exactly.

Capture — independent evidence

A second Osprio Mini sits silently on the same bus and records every frame in both directions. Because it never transmits, the timing and byte-level evidence it collects is impartial — the unit generating the traffic is not also the sole judge of what landed on the wire, which is what makes a verdict defensible.

The shape of a test

How a verdict is reached

Every test in the catalogue runs the same four stages, whether it is fully automated or needs an operator at the device. That uniformity is the point: a result is only worth something if the conditions that produced it are declared up front and the same run repeats identically next week, on someone else's bench, against a later firmware build.

01 · Arrange

The executor sets up the test's preconditions — capabilities present, secure channel up or down, session freshly baselined. A DUT that can't meet them is skipped as not-applicable, not failed.

02 · Exercise

The conformer runs the procedure — issuing commands, arming replies, injecting faults, or prompting an operator for a physical action at the reader. Every step is declared up front, so the same run repeats identically tomorrow.

03 · Observe

The capture unit records every frame on the bus while the procedure runs. The evidence behind a verdict comes from an independent witness, not from the unit that generated the traffic.

04 · Adjudicate

The host — not the firmware — checks the captured evidence against the expectation the test declares. Without conclusive proof the verdict is inconclusive, never a pass.

Why It Exists

Catch conformance issues before they delay you

"Vendor says it's compliant" is not a test result. Conformance Workspace turns that claim into something you can reproduce, measure, and disagree with — early, on your own bench and in CI — so issues surface while they're still cheap to fix. Here's what it does.

01

Test a PD or an ACU

Point the workspace at either side of the bus. When your device under test is a peripheral (PD), the conformer stands in as the controlling ACU and drives it; when it is a controller (ACU), the conformer plays the PD and answers it — so the same tool qualifies readers and controllers alike.

Declare the device once — manufacturer, model, address, firmware — and the workspace tailors the plan and the setup steps to what you are actually testing, then carries that identity through to the saved report.

02

Build the two-unit bench

Prepare the test topology right in the UI. Conformance runs on two Osprio Mini units on the same RS-485 bus: one takes the conformer role and drives the exchange, while the other sits in capture mode and passively records every frame.

That independent capture unit is what makes the results trustworthy — the device generating the traffic is not also the sole judge of what happened on the wire, so the timing and framing evidence stands on its own.

Running a plan

From a selected plan to a signed-off report

Select a plan, then let the executor work through it — pausing for you only where a check genuinely needs a person at the device. Every test it can draw on is published in full further down this page.

01

Run the suite or a single test

Kick off the whole plan and let the executor work through it, or drill into any one test and run it on its own while you iterate on a fix. Each check lands as pass, fail, or not-applicable against the OSDP spec, with the actual reply bytes captured alongside the expectation.

Because a plan is a structured, repeatable procedure rather than a pile of ad-hoc commands, the same run you step through at the bench doubles as a regression guard — re-run it on every firmware build to catch a conformance regression the moment it appears.

02

Guided manual steps

Some checks touch the physical world — present a card, trip a tamper, confirm an LED or buzzer fired. When a test needs a person at the device, execution pauses and a prompt spells out exactly what to do, then waits for the operator before grading the result and moving on.

Human-in-the-loop checks live in the same recorded plan as the automated ones, so nothing that requires an operator quietly falls out of coverage.

03

An evidence-backed report

Every run produces a detailed, signed-off report: per-command results with the bytes that were exchanged, a physical-layer summary of turnaround and timing, and an ordered audit trail of exactly how the device behaved, step by step.

The packet capture behind each verdict travels with the report as evidence, and the whole thing is saved to your account to revisit or export — a self-contained artifact you can archive, compare across builds, or hand to a customer or auditor.

Inside the report

A document you can defend in a room

Each run produces a detailed conformance report that records how the device behaved against the OSDP command set and the physical-layer expectations — to gauge a device's readiness, compare candidates side by side, or attach to an internal interop deliverable.

Per-command results

Each command-level check lands as pass, fail, or partial, with the actual reply bytes captured against the expectation — so an engineer sees exactly how the device diverged from the spec, not merely that it failed.

Physical-layer summary

Turnaround and timing metrics roll up alongside the command-level checks, so one report covers protocol behaviour and bus behaviour — and a device that answers correctly but too slowly shows up as exactly that.

Audit trail

An ordered record of every scenario the plan ran and how the device answered each one, so you can revisit its behaviour in a specific situation later, not just whether it passed overall.

Shareable artifact

Export it for a customer, integrator, or auditor. Every run is structured the same way, so a recipient can compare two devices without re-learning the format each time.

The test catalogue

Every check, published in full

Runs draw on a deep catalogue of checks organised into suites — link-layer framing, command and status handling, NAK and error behaviour, reader outputs, COMSET, secure channel, file transfer, and the manufacturer and PIV extensions. Nothing is hidden behind a run: every test below declares its preconditions, its exact procedure, and the expectation the verdict is judged against. You are never forced to run all of it — pick the suites and individual tests that matter for this device or this build.

Work in progress

This catalogue is published while it is still being built. The internal DSL we use to describe a test is evolving quickly, and both the set of cases and the way each one is exercised move with it.

Read it as an accurate account of what we test today, not as a stable specification to build against. Test identifiers, preconditions, procedures, and expected outcomes may be added, renamed, re-scoped, or withdrawn at any point — with no version bump and no deprecation notice. Nothing here is fixed until it is formalised.

LegendAuto host-adjudicated, unattendedManual operator at the bench decidesdestructive voids the DUT baseline, runs lastcovered elsewhere disabled — catalogued with the reason it carries no verdict of its ownambient credited from normal trafficlong-running a real multi-minute wait, not a hang

The "envelope" layer: is the PD speaking clean OSDP on the wire? Correct wiring, baud, framing, CRC. Ordinary polling traffic already proves almost all of it — once the Driver (as CP) has exchanged eight conforming frames, the baseline link-layer requirements are satisfied without any separate stimulus.

Procedure

  1. WIRESend osdp_POLL ×8
  2. WIRECapture every frame on the bus in parallel

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

At least 8 conforming OSDP frames observed on the bus.

Requirement
required
Triggered by
ambient traffic
Evidence
bus capture
Est. duration
~5 s
physicalbaselinemmt

Procedure

  1. WIRERead the DUT identity and declared capabilitiesreads the reported timer tick rate to know which speeds resolve with timing margin
  2. WIRESend osdp_COMSET (new_address=1, new_speed=9600)move the DUT to the speed under test (address unchanged); repeat per speed 9600/19200/38400/57600/115200/230400
  3. WIRERe-point the Driver's line to 9600 baudfollow the DUT to the commanded speed
  4. WIREConfigure the Driver session (mode=CP_MANAGED, addr=1)re-latch the Driver at the (unchanged) address on the new line
  5. WIRESend osdp_POLL
  6. WIRECapture every frame on the bus in parallel

Preconditions

Changes persistent DUT state, so it is scheduled last and the operator is warned before it runs.

Expected outcome

The osdp_COM reply, then the ACK/PDID/COM poll reply at the new speed.

Requirement
one of
Triggered by
command
Evidence
bus capture
Est. duration
~3 s
signallingbaud

Procedure

  1. WIRESend osdp_MFG (command_specific_data=BOUNDARY_BYTES)a vendor message whose payload carries the chosen boundary bytes
  2. WIRESend osdp_POLLthe reader must still be in step afterwards
  3. WIRECapture every frame on the bus in parallel

This does not claim every one of the 256 byte values survives the link — only that the values most likely to be mistaken for framing do, in one frame, without desynchronising the reader. A PD that treats one of them as a delimiter, an escape, or a resync signal fails here: either the vendor message itself fails its checksum, or the reader is no longer in step on the poll that follows.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

A frame carrying the chosen boundary bytes, and a healthy exchange after it.

Requirement
required
Triggered by
command
Evidence
bus capture
Est. duration
~2 s
encodingcharacter-encoding

Procedure

  1. WIRESend osdp_POLL
  2. WIREMeasure response_time
  3. WIRECapture every frame on the bus in parallel

A reader slow to reply holds up every other device on the shared bus, which is why the 200 ms window is measured on the reply itself, whatever code it carries.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

The time between the poll leaving the wire and the reader's reply arriving.

Requirement
required
Triggered by
behavioural
Evidence
measurement
Est. duration
~1 s
channel-accessbusy

Procedure

  1. WIRESend osdp_POLL
  2. WIRECapture every frame on the bus in parallel

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

A CRC-valid OSDP frame observed on the bus.

Requirement
required
Triggered by
ambient traffic
Evidence
bus capture
Est. duration
~1 s
encodingendianness

Procedure

  1. WIRESend osdp_TEXT (max_len=true)a display message filling the largest frame the protocol allows
  2. WIREMeasure reply_size
  3. WIRESend osdp_POLLthe reader must still be talking afterwards
  4. WIRECapture every frame on the bus in parallel

Messages can be as large as 1440 bytes, and a reader must cope with one that big — either acting on it or refusing it cleanly. What it must not do is overrun its own buffer, which typically leaves the device unresponsive rather than merely wrong.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

The reader's answer to a maximum-length message, and a healthy exchange after it.

Requirement
required
Triggered by
fault injection
Evidence
bus capture
Est. duration
~2 s
packet-sizestress

Procedure

  1. WIRESend osdp_POLL ×8
  2. WIRECapture every frame on the bus in parallel

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

At least 8 conforming OSDP frames observed on the bus.

Requirement
required
Triggered by
ambient traffic
Evidence
bus capture
Est. duration
~5 s
framingbaselinemmt

Procedure

  1. WIRESend osdp_POLL
  2. WIRECapture every frame on the bus in parallel

Preconditions

A freshly baselined session, so the sequence number restarts at 0.

Expected outcome

A frame carrying sequence 0 observed on the bus.

Requirement
required
Triggered by
ambient traffic
Evidence
bus capture
Est. duration
~1 s
sequenceresync

Procedure

  1. WIRESend osdp_POLL ×8
  2. WIRECapture every frame on the bus in parallel

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

At least 8 conforming OSDP frames observed on the bus.

Requirement
required
Triggered by
ambient traffic
Evidence
bus capture
Est. duration
~5 s
framingsombaselinemmt

Procedure

  1. WIRESend osdp_POLLpoll a non-DUT address; PD must stay silent
  2. WIRESend osdp_POLLpoll the DUT address; PD must answer
  3. WIRECapture every frame on the bus in parallel

A reader that answers to another device's address makes the shared bus unusable.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

Silence when another reader's address was polled, and a reply when its own was.

Requirement
required
Triggered by
fault injection
Evidence
bus capture
Est. duration
~2 s
addressfiltering

Procedure

  1. WIRESend osdp_POLL ×8
  2. WIRECapture every frame on the bus in parallel

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

At least 8 conforming OSDP frames observed on the bus.

Requirement
required
Triggered by
ambient traffic
Evidence
bus capture
Est. duration
~5 s
framinglengthbaselinemmt

Procedure

  1. WIRESend osdp_POLL ×8
  2. WIRECapture every frame on the bus in parallel

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

At least 8 conforming OSDP frames observed on the bus.

Requirement
required
Triggered by
ambient traffic
Evidence
bus capture
Est. duration
~5 s
framingctrlbaselinemmt

Procedure

  1. WIRESend osdp_POLL
  2. WIRECapture every frame on the bus in parallel

Preconditions

DUT must advertise the secure channel capability; otherwise the test is skipped as N/A. An established secure channel — the executor handshakes first if one is not already up.

Expected outcome

A frame carrying a security block observed on the bus.

Requirement
optional
Triggered by
ambient traffic
Evidence
bus capture
Est. duration
~1 s
secure-channelscb

Procedure

  1. WIRESend osdp_POLL
  2. WIRECapture every frame on the bus in parallel

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

The ACK/NAK/PDID/PDCAP/LSTATR/ISTATR/OSTATR/RSTATR/RAW/KEYPAD/COM/BUSY reply observed on the bus.

Requirement
required
Triggered by
ambient traffic
Evidence
bus capture
Est. duration
~1 s
reply-code

Procedure

  1. WIREOverride the next frame's CMD_CODE field to 0xFF on the wireonly exercises the negative path if the DUT would echo/mirror; primarily an observation
  2. WIRESend osdp_POLL
  3. WIRECapture every frame on the bus in parallel

A PD reply outside the valid reply set is a failure.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

The ACK/NAK/PDID/PDCAP/LSTATR/ISTATR/OSTATR/RSTATR/RAW/KEYPAD/COM/BUSY reply observed on the bus.

Requirement
required
Triggered by
fault injection
Evidence
bus capture
Est. duration
~1 s
reply-codenegative

Procedure

  1. WIRESend osdp_POLL
  2. WIRECapture every frame on the bus in parallel

Caveat: a bad checksum is tolerated, not failed.

Preconditions

DUT must advertise the check character capability; otherwise the test is skipped as N/A.

Expected outcome

A CRC-valid OSDP frame observed on the bus.

Requirement
required
Triggered by
ambient traffic
Evidence
bus capture
Est. duration
~1 s
checksum

Procedure

  1. WIRESend osdp_POLL
  2. WIRECapture every frame on the bus in parallel

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

A CRC-valid OSDP frame observed on the bus.

Requirement
required
Triggered by
ambient traffic
Evidence
bus capture
Est. duration
~1 s
crc

Procedure

  1. WIREOverride the next frame's CRC field to flip on the wireno way to force a real PD to emit a bad CRC from this side; this documents the mechanism's actual reach
  2. WIRESend osdp_POLL
  3. WIRECapture every frame on the bus in parallel

Kept as a disabled placeholder, not deleted, so a reader does not go looking for a bad-CRC-reply test in the PD-DUT framing suite and wonder if it was missed.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Why this isn’t scored

This id's title and summary claimed the ACU must detect a corrupted PD reply, but its mechanism can only corrupt the frame the Driver-as-CP is about to send — flipping the CRC ahead of its own outgoing osdp_POLL, never the real PD's reply, which this harness does not control. So what ran here was the PD's handling of a garbled command, precisely what OCT_PERR_06 already tests with a real assertion (a NAK carrying BAD_CHECKSUM, or a conformant silent discard). The claim this id's title makes — an ACU rejecting a corrupted PD reply — is verified from the role that can actually produce it, in the ACU-DUT suite as OCT_ALNK_08.

Covered by OCT_PERR_06, OCT_ALNK_08

Requirement
required
Triggered by
fault injection
Evidence
Est. duration
crcnegativedetection

Procedure

  1. WIRESend osdp_ID
  2. WIRECapture every frame on the bus in parallel

The config address accepts only the few commands needed to identify and configure a device.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

The identity reply, given when the reader was addressed on the setup address.

Requirement
required
Triggered by
command
Evidence
bus capture
Est. duration
~1 s
addressconfig-address

Procedure

  1. WIREOverride the next frame's SECBLK field to SCS_17_no_content on the wire
  2. WIRESend osdp_POLL
  3. WIRECapture every frame on the bus in parallel

Pass on successful transmission of the rogue poll.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

The stimulus frame was transmitted on the wire (pass on successful send).

Requirement
required
Triggered by
fault injection
Evidence
transmitted frame
Est. duration
~1 s
secure-channelnegativeset-pass

Procedure

  1. WIRESend osdp_FILETRANSFER (segmented=true)
  2. WIREMeasure reply_size
  3. WIRECapture every frame on the bus in parallel

This is what makes firmware updates over OSDP possible; see the file-transfer suite for the end-to-end test.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Why this isn’t scored

Splitting and reassembling an oversized payload is exercised end to end by the file transfer tests, which cannot pass unless it works. Testing it separately would assert the same thing twice.

Covered by OCT_PFT_01

Requirement
optional
Triggered by
command
Evidence
Est. duration
multipartfile-transfer

The everyday OSDP conversation: the Driver (as CP) issues each mandatory command — POLL / ID / CAP / LSTAT / ISTAT / OSTAT / RSTAT / OUT / ACURXSIZE — and checks the PD's reply structure and content. Each command passes once it has been sent and the PD answers sensibly; the paired reply check confirms the reply itself is well-formed.

Procedure

  1. WIRESend osdp_POLLsend + decode reply + timestamp
  2. WIRECapture every frame on the bus in parallel
  3. WIREMeasure response_time

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

The ACK/LSTATR/ISTATR/OSTATR/RSTATR/RAW/FMT/KEYPAD reply observed on the bus, within the reply window.

Requirement
required
Triggered by
command
Evidence
bus capture
Est. duration
~1 s
pollstatusbaseline

Procedure

  1. WIRESend osdp_POLLPD answers with ACK when it has nothing to report
  2. WIRECapture every frame on the bus in parallel

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

The ACK reply observed on the bus.

Requirement
required
Triggered by
ambient traffic
Evidence
bus capture
Est. duration
~1 s
ackstatus

Procedure

  1. WIRESend osdp_IDsend + decode reply + timestamp; parse the returned osdp_PDID
  2. WIRECapture every frame on the bus in parallel

A valid PDID passes; an all-zero manufacturer OUI, or a NAK to the ID request, is a failure. A valid PDID also confirms the reader is responding correctly at the current signalling speed.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

The PDID reply observed on the bus.

Requirement
required
Triggered by
command
Evidence
bus capture
Est. duration
~1 s
identitypdid

Procedure

  1. WIRESend osdp_CAPparse the osdp_PDCAP tuples (function code, compliance level, unit count)
  2. WIRECapture every frame on the bus in parallel

A per-capability record is produced for each capability the PDCAP reports; those values set context used by later tests (e.g. secure-channel tests are disabled if the PD reports no secure-channel support).

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

The PDCAP reply observed on the bus.

Requirement
required
Triggered by
command
Evidence
bus capture
Est. duration
~1 s
capabilitiespdcap

Procedure

  1. WIRESend osdp_LSTATsend + decode reply + timestamp; parse osdp_LSTATR
  2. WIRECapture every frame on the bus in parallel

A well-formed LSTATR satisfies the local-status check — the reader answers the request with a standards-conformant reply.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

The LSTATR reply observed on the bus.

Requirement
required
Triggered by
command
Evidence
bus capture
Est. duration
~1 s
statuslocal-statustamperpower

Procedure

  1. WIRESend osdp_ISTATsend + decode reply + timestamp; parse osdp_ISTATR
  2. WIRECapture every frame on the bus in parallel

A well-formed ISTATR satisfies the input-status check. If the PD advertised inputs but NAKs the ISTAT request, that is a failure.

Preconditions

DUT must advertise the contact status monitoring capability; otherwise the test is skipped as N/A.

Expected outcome

The ISTATR reply observed on the bus.

Requirement
required
Triggered by
command
Evidence
bus capture
Est. duration
~1 s
statusinput-status

Procedure

  1. WIRESend osdp_OSTATsend + decode reply + timestamp; parse osdp_OSTATR
  2. WIRECapture every frame on the bus in parallel

A well-formed OSTATR satisfies the output-status check. A NAK to OSTAT when outputs were advertised is a failure.

Preconditions

DUT must advertise the output control capability; otherwise the test is skipped as N/A.

Expected outcome

The OSTATR reply observed on the bus.

Requirement
required
Triggered by
command
Evidence
bus capture
Est. duration
~1 s
statusoutput-status

Procedure

  1. WIREMark the capture — osdp_OUT actuationanchor the coming physical actuation into the trace
  2. OPERWatch the reader's relay/output, then press Ready — the Driver will send osdp_OUT with a control code and timer.ready gate; the operator must be watching before the command goes out, so the visible result isn't missed
  3. WIRESend osdp_OUT (output_no=0, control_code=5, timer=30)PD should activate the output and reply OSTATR/ACK. Control code 5 is "temporary ON, revert on timeout" with a 3.0 s timer, so the run cannot leave a door strike energised behind it — the instruction step promises the operator "a control code and timer", and this states them rather than sending an empty body and letting each executor invent its own.
  4. WIRECapture every frame on the bus in parallel
  5. ASKDid the relay/output physically actuate per the commanded control code and timer?Passes on “yes”

The command send is automated; the physical actuation is confirmed manually.

Preconditions

DUT must advertise the output control capability; otherwise the test is skipped as N/A.

Expected outcome

Operator confirms: Did the relay/output physically actuate per the commanded control code and timer?

Requirement
required
Triggered by
command
Evidence
operator answer
Est. duration
~2 min
output-controlactuationmanual

Procedure

  1. WIRESend osdp_RSTATsend + decode reply + timestamp; parse osdp_RSTATR
  2. WIRECapture every frame on the bus in parallel

A well-formed RSTATR satisfies the reader-status check. Because RSTAT is deprecated, a NAK is tolerated rather than treated as a failure.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

The RSTATR/NAK reply observed on the bus.

Requirement
required
Triggered by
command
Evidence
bus capture
Est. duration
~1 s
statusreader-statusdeprecated

Procedure

  1. WIRESend osdp_ACURXSIZEsend + decode reply + timestamp; announces the ACU max receive buffer
  2. WIRECapture every frame on the bus in parallel

Automated on send; a NAK is a failure.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

The ACK reply observed on the bus.

Requirement
optional
Triggered by
command
Evidence
bus capture
Est. duration
~1 s
acurxsizereply-size

Procedure

  1. WIRESend osdp_ISTATsend + decode reply; parse osdp_ISTATR input-status bits
  2. WIRECapture every frame on the bus in parallel

Confirms ISTATR to ISTAT when inputs are advertised.

Preconditions

DUT must advertise the contact status monitoring capability; otherwise the test is skipped as N/A.

Expected outcome

The ISTATR reply observed on the bus for a PD with supervised inputs.

Requirement
optional
Triggered by
command
Evidence
bus capture
Est. duration
~1 s
statusinput-statussupervised

Checks the PD's NAK replies: whether it produces a well-formed NAK with a valid reason code when it should, and — the audit-critical part — whether a NAK on a command tied to an advertised capability is treated as invalidating that capability claim, rather than brushed aside as a one-off failure.

Procedure

  1. WIREOverride the next frame's CMD_CODE field to 0xFF on the wirearm an unsupported/bogus command code (OSDP_BOGUS) the PD must NAK
  2. WIRESend osdp_POLL
  3. WIRECapture every frame on the bus in parallel

Automated, unconditional on any NAK. Trigger may also be passive, or induce-NAK to force one. Reason 0 is not a defined NAK reason (see OCT_PERR_03) and fails this check like any other undefined value.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

A well-formed NAK carrying one of the defined reason codes, observed on the bus.

Requirement
required
Triggered by
fault injection
Evidence
bus capture
Est. duration
~1 s
nakerror-handling

Procedure

  1. WIREOverride the next frame's CMD_CODE field to 0xFF on the wirearm an unsupported command code to provoke a NAK (induce-NAK reason 0 mainly used ACU-DUT)
  2. WIRESend osdp_POLL
  3. WIRECapture every frame on the bus in parallel

Zero is not one of the defined rejection reasons — it is the code that means "no error". A reader that rejects a command while claiming nothing went wrong leaves the controller with no way to react, so this checks it never does.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

The rejection carried a real reason code, not the reserved zero.

Requirement
optional
Triggered by
fault injection
Evidence
bus capture
Est. duration
~1 s
naknegativeerror-handling

Procedure

  1. WIREOverride the next frame's CMD_CODE field to 0xFF on the wirearm an unknown command to provoke NAK 3 (UNKNOWN_COMMAND); also probe via CRC / SEQ overrides for other reasons
  2. WIRESend osdp_POLL
  3. WIRECapture every frame on the bus in parallel

When a reader rejects a command it says why, using a numbered reason. A conforming reader picks the reason that actually matches the error rather than a catch-all.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Why this isn’t scored

This entry is the index of the reason-code family rather than a test of its own; each individual reason code is checked by its own test.

Covered by OCT_PERR_06, OCT_PERR_07, OCT_PERR_08, OCT_PERR_09, OCT_PERR_10, OCT_PERR_11, OCT_PERR_12, OCT_PERR_13, OCT_PERR_14, OCT_PERR_15, OCT_PERR_16

Requirement
optional
Triggered by
fault injection
Evidence
Est. duration
nakreason-codescoverage

Procedure

  1. WIREOverride the next frame's CRC field on the wirecorrupt the CRC without recomputing it — the frame now fails the check character
  2. WIRESend osdp_POLL
  3. WIRECapture every frame on the bus in parallel

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

A NAK with reason BAD_CHECKSUM (or a conformant silent discard) on the bus.

Requirement
optional
Triggered by
fault injection
Evidence
bus capture
Est. duration
~1 s
nakreason-codescrc

Procedure

  1. WIREOverride the next frame's LEN field on the wireset an inconsistent packet length
  2. WIRESend osdp_POLL
  3. WIRECapture every frame on the bus in parallel

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

A NAK with reason CMD_LENGTH (or a conformant silent discard) on the bus.

Requirement
optional
Triggered by
fault injection
Evidence
bus capture
Est. duration
~1 s
nakreason-codeslength

Procedure

  1. WIREOverride the next frame's CMD_CODE field to 0xFF on the wirearm an unsupported/bogus command code the PD must reject
  2. WIRESend osdp_POLL
  3. WIRECapture every frame on the bus in parallel

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

A NAK with reason UNKNOWN_COMMAND on the bus.

Requirement
optional
Triggered by
fault injection
Evidence
bus capture
Est. duration
~1 s
nakreason-codesunknown-command

Procedure

  1. WIREOverride the next frame's SEQ field to skip on the wireemit an out-of-order sequence number. `skip` is required, not decorative: the default flip-all-bits injection on the two-bit sequence field is XOR 3, and two of its three outcomes are conformant PD behaviour rather than errors — a retransmission, or the reserved 0 that means "the CP is restarting communication". See the injection primitive's own definition in schema/primitives.yaml.
  2. WIRESend osdp_POLL
  3. WIRECapture every frame on the bus in parallel

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

A NAK with reason SEQUENCE on the bus.

Requirement
optional
Triggered by
fault injection
Evidence
bus capture
Est. duration
~1 s
nakreason-codessequence

Procedure

  1. WIREOverride the next frame's SECBLK field to SCS_17_no_content on the wireforge a bare SCB (length + SCS type, no cryptogram) on an otherwise-plain command
  2. WIRESend osdp_POLL
  3. WIRECapture every frame on the bus in parallel

Preconditions

DUT must advertise the secure channel capability; otherwise the test is skipped as N/A.

Expected outcome

A NAK with reason SC_COND on the bus.

Requirement
optional
Triggered by
fault injection
Evidence
bus capture
Est. duration
~1 s
nakreason-codessecure-channel

Procedure

  1. WIREOverride the next frame's SECBLK field to SCS_17_no_content on the wireforge a bare SCB (length + SCS type, no cryptogram) on an otherwise-plain command
  2. WIRESend osdp_POLL
  3. WIRECapture every frame on the bus in parallel

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

A NAK with reason SC_UNSUP on the bus.

Requirement
optional
Triggered by
fault injection
Evidence
bus capture
Est. duration
~1 s
nakreason-codessecure-channel

Procedure

  1. WIRESend osdp_POLLagainst a PD enforcing secure channel, send a command requiring SC in cleartext; expect NAK reason SC_COND
  2. WIRECapture every frame on the bus in parallel

Enable once a cleartext-in-secure-context stimulus is available. Expect NAK reason SC_COND.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Why this isn’t scored

Provoking this needs the test runner to send an unencrypted command to a reader that is enforcing encryption — a stimulus it cannot produce yet.

Requirement
optional
Triggered by
fault injection
Evidence
Est. duration
nakreason-codesencryption

Procedure

  1. WIRESend osdp_POLLissue BIOREAD with an unsupported BIO_TYPE (Table 24); expect NAK reason BIO_TYPE
  2. WIRECapture every frame on the bus in parallel

Enable once BIOREAD stimulus params are modelled. Expect NAK reason BIO_TYPE.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Why this isn’t scored

Provoking this needs the test runner to ask for a specific biometric type and template format, which it cannot yet express.

Requirement
optional
Triggered by
fault injection
Evidence
Est. duration
nakreason-codesbiometrics

Procedure

  1. WIRESend osdp_POLLissue BIOREAD with an unsupported BIO_FORMAT (Table 25); expect NAK reason BIO_FORMAT
  2. WIRECapture every frame on the bus in parallel

Enable once BIOREAD stimulus params are modelled. Expect NAK reason BIO_FORMAT.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Why this isn’t scored

Provoking this needs the test runner to ask for a specific biometric type and template format, which it cannot yet express.

Requirement
optional
Triggered by
fault injection
Evidence
Est. duration
nakreason-codesbiometrics

Procedure

  1. WIRESend osdp_POLLsend a command with an invalid parameter record; expect NAK reason CANNOT_PROCESS
  2. WIRECapture every frame on the bus in parallel

Enable once an invalid-record stimulus is modelled. Expect NAK reason CANNOT_PROCESS.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Why this isn’t scored

What counts as an unusable command record differs by reader, so no single stimulus provokes this reliably on an arbitrary device.

Requirement
optional
Triggered by
fault injection
Evidence
Est. duration
nakreason-codescannot-process

Procedure

  1. WIRESend osdp_POLLobserve an opportunistic generic NAK; not deterministically forceable
  2. WIRECapture every frame on the bus in parallel

Informational; a PD may use GENERIC for unspecified errors. Expect nak reason GENERIC when seen.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Why this isn’t scored

This is the catch-all a reader may use for anything the numbered reasons do not cover. Nothing can force it on demand, so it is recorded when seen rather than tested for.

Requirement
optional
Triggered by
fault injection
Evidence
Est. duration
nakreason-codesgeneric

The PD's human-facing outputs (LED, buzzer, text display) and inputs (card read, keypad). Outputs can't be verified by a bus sniffer, so the Driver sends the command and a human confirms what actually happened at the reader — those tests are manual. Inputs are different: the credential or keys are presented (by a person, or by the engine when it controls the DUT), and the resulting osdp_RAW / osdp_KEYPAD reply on the bus is what's checked, so the card-read and keypad tests are automated.

Procedure

  1. WIREMark the capture — led commandanchor the operator-confirm point into the trace
  2. OPERWatch the reader's LED, then press Ready — the Driver will send osdp_LED (red).ready gate; the operator must be watching before the command goes out, so the visible result isn't missed
  3. WIRESend osdp_LED (led_number=0, perm_on_color=red, on_time=10, off_time=0)A steady colour is a nonzero ON with a zero OFF. OSDP forbids a permanent state whose ON and OFF times are both zero, and a PD that enforces that NAKs the command outright — so the times are stated here rather than left to an executor default.
  4. WIRECapture every frame on the bus in parallel
  5. ASKDid the LED show the commanded colour/pattern?Passes on “yes”

Preconditions

DUT must advertise the led capability; otherwise the test is skipped as N/A.

Expected outcome

Operator confirms: Did the LED show the commanded colour/pattern?

Requirement
required
Triggered by
command
Evidence
operator answer
Est. duration
~2 min
ledoutputoperator-confirm

Procedure

  1. WIREMark the capture — led colorrepeat the mark + command + confirm per colour under test
  2. OPERWatch the reader's LED, then press Ready — the Driver will command the colour under test.ready gate; the operator must be watching before the command goes out, so the visible result isn't missed
  3. WIRESend osdp_LED (led_number=0, perm_on_color=red, on_time=10, off_time=0)repeat per colour (Black / Red / Green / Amber / Blue / Magenta / Cyan / White). Steady ON, as in OCT_PRDR_01: the operator is judging the colour, not a blink pattern, and both times zero is not a legal permanent state.
  4. WIRECapture every frame on the bus in parallel
  5. ASKDid the LED display exactly the commanded colour?Passes on “yes”

Red and green have dedicated confirmation steps; other colours use the generic operator confirm. A NAK to an LED command fails that colour.

Preconditions

DUT must advertise the led capability; otherwise the test is skipped as N/A.

Expected outcome

Operator confirms: Did the LED display exactly the commanded colour?

Requirement
one of
Triggered by
command
Evidence
operator answer
Est. duration
~2 min
ledoutputoperator-confirmper-color

Procedure

  1. WIREMark the capture — buzzer commandanchor the operator-confirm point into the trace
  2. OPERListen to the reader's buzzer, then press Ready — the Driver will send osdp_BUZ.ready gate; the operator must be watching before the command goes out, so the visible result isn't missed
  3. WIRESend osdp_BUZ (tone_code=2, on_time=15, off_time=15, repeat=3)Tone code 2 is the reader's default tone. This said 0, which OSDP defines as "no tone" — so the test commanded silence and then asked the operator whether they heard a pattern, which no conformant PD could pass.
  4. WIRECapture every frame on the bus in parallel
  5. ASKDid the buzzer sound with the commanded on/off/repeat pattern?Passes on “yes”

Preconditions

DUT must advertise the audible output capability; otherwise the test is skipped as N/A.

Expected outcome

Operator confirms: Did the buzzer sound with the commanded on/off/repeat pattern?

Requirement
required
Triggered by
command
Evidence
operator answer
Est. duration
~2 min
buzzeroutputoperator-confirm

Procedure

  1. WIREMark the capture — text commandanchor the operator-confirm point into the trace
  2. OPERWatch the reader's display, then press Ready — the Driver will send osdp_TEXT.ready gate; the operator must be watching before the command goes out, so the visible result isn't missed
  3. WIRESend osdp_TEXT (message=OSDP TEST, reader=0, text_command=1, temp_time=0, row=1, column=1)
  4. WIRECapture every frame on the bus in parallel
  5. ASKDid the commanded text appear correctly on the display?Passes on “yes”

A NAK to the TEXT command is a failure. A max-length text variant also exercises the packet-size path (see 01-link-layer-framing.yaml).

Preconditions

DUT must advertise the text output capability; otherwise the test is skipped as N/A.

Expected outcome

Operator confirms: Did the commanded text appear correctly on the display?

Requirement
optional
Triggered by
command
Evidence
operator answer
Est. duration
~2 min
textdisplayoutputoperator-confirm

Procedure

  1. WIREMark the capture — present cardanchor the card presentation in the trace
  2. DUTPresent the configured credential at the reader now.
  3. WIRESend osdp_POLLthe queued card read arrives on this poll (or the next)
  4. WIRESend osdp_POLLsecond poll in case the PD's event queue needs a cycle
  5. WIRECapture every frame on the bus in parallel

Preconditions

DUT must advertise the card data format capability; otherwise the test is skipped as N/A.

Expected outcome

The osdp_RAW credential report observed on the bus.

Requirement
required
Triggered by
DUT stimulus
Evidence
bus capture
Est. duration
~22 s
cardrawinput

Procedure

  1. WIREMark the capture — enter keysanchor the keypad entry in the trace
  2. DUTEnter the agreed digit sequence (default 1234) on the reader keypad now.
  3. WIRESend osdp_POLLthe queued keypad report arrives on this poll (or the next)
  4. WIRESend osdp_POLLsecond poll in case the PD's event queue needs a cycle
  5. WIRECapture every frame on the bus in parallel

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

The osdp_KEYPAD report observed on the bus.

Requirement
required
Triggered by
DUT stimulus
Evidence
bus capture
Est. duration
~22 s
keypadinput

Changing the PD's address / baud via osdp_COMSET and validating the osdp_COM reply. The PD must reply at its old settings, switch to the new ones, echo the change in an osdp_COM reply, and come back reachable at the new address/speed. Includes a robustness case: a garbage baud must be rejected, not bricked onto the bus.

Procedure

  1. WIRESend osdp_COMSET (new_address=1, new_speed=19200)by default sent to the config/broadcast address unless send-direct
  2. WIRERe-point the Driver's line to 19200 baudre-point the Driver's port to the new speed
  3. WIREConfigure the Driver session (mode=CP_MANAGED, addr=1)re-point the Driver at the new PD address
  4. WIRESend osdp_POLL
  5. WIRECapture every frame on the bus in parallel

A successful COMSET is confirmed by the returned osdp_COM, which verifies both the reconfiguration and the new signalling speed.

Preconditions

Changes persistent DUT state, so it is scheduled last and the operator is warned before it runs.

Expected outcome

The COM reply observed on the bus.

Requirement
required
Triggered by
command
Evidence
bus capture
Est. duration
~2 s
comsetcommscommissioning

Procedure

  1. WIRESend osdp_COMSET (new_address=1, new_speed=19200)broadcast recovery — the single PD replies osdp_COM at the old baud, then switches. Repeat per speed (9600 / 19200 / 38400 / 115200)
  2. WIRERe-point the Driver's line to 19200 baudre-point the Driver's port to the commanded speed, after the PD's reply has been received
  3. WIREConfigure the Driver session (mode=CP_MANAGED, addr=1)re-establish the Driver fresh at the new speed before polling
  4. WIRESend osdp_POLL
  5. WIRECapture every frame on the bus in parallel

COMSET is 1-to-1 (single PD, no collision), so the PD replies osdp_COM at its old settings and then applies the change. The returned osdp_COM confirms the reconfiguration; the follow-up poll at the new baud confirms the new signalling speed.

Preconditions

Changes persistent DUT state, so it is scheduled last and the operator is warned before it runs.

Expected outcome

The osdp_COM reply at the old baud plus the follow-up poll reply at the new speed.

Requirement
one of
Triggered by
command
Evidence
bus capture
Est. duration
~2 s
comsetbaudsignalling

Procedure

  1. WIRESend osdp_COMSET (new_speed=999999)osdp_COMSET with invalid baud 999999 to the current PD address
  2. WIRESend osdp_POLLconfirm the PD is still reachable at the old speed
  3. WIRECapture every frame on the bus in parallel
  4. ASKDid the PD reject/ignore the bad COMSET and stay reachable at its current speed (did not switch to a garbage rate or drop off the bus)?Passes on “yes”

Sending the bad COMSET is automated; whether the PD correctly rejected it is for the operator to confirm by watching its response, or the absence of a speed change.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

Operator confirms: Did the PD reject/ignore the bad COMSET and stay reachable at its current speed (did not switch to a garbage rate or drop off the bus)?

Requirement
robustness
Triggered by
command
Evidence
operator answer
Est. duration
~2 min
comsetrobustnessnegative

The Driver-as-CP drives the OSDP Secure Channel handshake (CHLNG / CCRYPT / SCRYPT / RMAC_I) and validates the PD's AES-128 crypto replies. This is where the checks are the most exacting: cryptograms must decrypt to the expected random values, the cUID must be non-zero, and key install / paired-key / rotation are exercised.

Procedure

  1. WIRERun the secure-channel handshake (intent=normal)sends CHLNG (SCS_11) then receives CCRYPT (SCS_12); fault variants — a bad MAC, a wrong key, a malformed message, a replay — drive the negative cases
  2. WIRECapture every frame on the bus in parallel

Reaching CCRYPT confirms the challenge step; the CCRYPT itself passes only when the secure-channel state, key, and client cryptogram over RND.A are all correct, and fails on an all-zero cUID, wrong state, key mismatch, or RND.A mismatch. Negative cases arm a fault intent and expect the channel to stay down.

Preconditions

DUT must advertise the secure channel capability; otherwise the test is skipped as N/A. No secure channel: the executor tears any existing session down so the handshake starts from a clean CHLNG.

Expected outcome

The secure-channel handshake exchange observed on the bus.

Requirement
optional
Triggered by
command
Evidence
bus capture
Est. duration
~2 s
secure-channelhandshakecrypto

Procedure

  1. WIRERun the secure-channel handshake (intent=normal)sends SCRYPT (SCS_13) then receives RMAC_I (SCS_14); channel goes operational; negative cases use a bad MAC, a wrong key, a malformed message, or a replay
  2. WIRECapture every frame on the bus in parallel

RMAC-I completes the handshake and the channel becomes operational; the accepted status octet depends on the OSDP edition (IEC 60839 vs OSDP 2.2), and a pre-edition device fails. A later MAC mismatch silently resets the channel. Injecting a bad RMAC-I is an ACU-DUT test.

Preconditions

DUT must advertise the secure channel capability; otherwise the test is skipped as N/A. No secure channel: the executor tears any existing session down so the handshake starts from a clean CHLNG.

Expected outcome

The secure-channel handshake exchange observed on the bus.

Requirement
optional
Triggered by
command
Evidence
bus capture
Est. duration
~2 s
secure-channelhandshakecrypto

Procedure

  1. WIRESend osdp_KEYSET (psk=runtime_random)install a fresh runtime-generated site SCBK (32 hex characters on the wire, or the PD NAKs with BAD_KEY_LENGTH), distinct from the default pairing key
  2. WIRECapture every frame on the bus in parallel

This passes when the PD ACKs the KEYSET. A NAK is a failure. Whether a subsequent handshake actually succeeds under the new key is not checked here — see OCT_PSC_05.

Preconditions

DUT must advertise the secure channel capability; otherwise the test is skipped as N/A. An established secure channel — the executor handshakes first if one is not already up. Changes persistent DUT state, so it is scheduled last and the operator is warned before it runs.

Expected outcome

The ACK reply observed on the bus.

Requirement
optional
Triggered by
command
Evidence
bus capture
Est. duration
~1 s
secure-channelkeysetkey-management

Procedure

  1. WIRERun the secure-channel handshake (intent=normal)complete a secure session while keyed with a non-default (paired) SCBK
  2. WIRECapture every frame on the bus in parallel

Preconditions

DUT must advertise the secure channel capability; otherwise the test is skipped as N/A. No secure channel: the executor tears any existing session down so the handshake starts from a clean CHLNG.

Expected outcome

The secure-channel handshake exchange observed on the bus.

Requirement
optional
Triggered by
command
Evidence
bus capture
Est. duration
~2 s
secure-channelpaired-keykey-management

Procedure

  1. WIRERun the secure-channel handshake (intent=normal)bring the channel up on the key the session started with, so the rotation has a secure channel to run over
  2. WIRESend osdp_KEYSET (psk=runtime_random)install a freshly generated key while the reader is running
  3. WIRERun the secure-channel handshake (intent=normal)bring the encrypted channel back up under the new key
  4. WIRESend osdp_KEYSET (psk=session_entry)put the reader back on the key it started with
  5. WIRECapture every frame on the bus in parallel

Security policy usually requires the encryption key to be changed periodically. A reader must accept a new key while running and come back up encrypted under it — otherwise rotating keys means physically revisiting every door. osdp_KEYSET is itself only ever sent once the channel is already secure, so this test first establishes that channel on the key the session started with, then changes the reader's key, then puts the original back before it finishes.

Preconditions

DUT must advertise the secure channel capability; otherwise the test is skipped as N/A. No secure channel: the executor tears any existing session down so the handshake starts from a clean CHLNG. Changes persistent DUT state, so it is scheduled last and the operator is warned before it runs.

Expected outcome

The entry key's channel established, the new key accepted, a fresh encrypted session established under it, and the original key restored.

Requirement
optional
Triggered by
command
Evidence
bus capture
Est. duration
~5 s
secure-channelkey-rotationkey-management

The Driver-as-CP pushes a file to the PD via osdp_FILETRANSFER fragments and validates the PD's osdp_FTSTAT progress replies, exercising the multipart / large-data machinery including inter-fragment and final delays. The supporting ACURXSIZE and KEEPACTIVE commands advertise the ACU buffer size and hold the session open during long transfers.

Procedure

  1. WIRESend osdp_FILETRANSFER (segmented=true, file_type=OPAQUE)drives the whole transfer in fragments (four / twenty / hundred / twothousand); the step's facts are the final FTSTAT the PD returned
  2. WIRECapture every frame on the bus in parallel

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

The FTSTAT reply observed on the bus.

Requirement
optional
Triggered by
command
Evidence
bus capture
Est. duration
~1 s
file-transfermultipart

Procedure

  1. WIRESend osdp_FILETRANSFER (segmented=true)PD returns FTSTAT carrying a non-zero inter-fragment delay during an OK status
  2. WIREMeasure response_timedelayed-status window; the Driver honors the requested delay before sending the next fragment
  3. WIRECapture every frame on the bus in parallel

A reader that needs time — to write a page of firmware, say — can ask the controller to wait before sending the next chunk, so a fast controller does not overrun a slow reader.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Why this isn’t scored

Only the reader can request this pause, so it cannot be provoked when the reader is the device under test. The same behaviour is verified from the controller side, where the test rig plays the reader and requests the pause itself.

Covered by OCT_AFT_02

Requirement
optional
Triggered by
command
Evidence
Est. duration
file-transferflow-controldelay

Procedure

  1. WIRESend osdp_FILETRANSFER (segmented=true)PD returns FTSTAT with the "finishing" status (3) carrying a final delay
  2. WIREMeasure response_timedelayed-status window; the Driver honors the end-of-transfer delay before closing
  3. WIRECapture every frame on the bus in parallel

At the end of a transfer the reader reports the file received and asks for time to finish the job — commit the firmware, restart — before the controller treats the transfer as done.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Why this isn’t scored

Only the reader can signal this final pause, so it cannot be provoked when the reader is the device under test. It is verified from the controller side instead, with an operator confirming that the controller waited before treating the transfer as complete.

Covered by OCT_AFT_03

Requirement
optional
Triggered by
command
Evidence
Est. duration
file-transferflow-controldelay

Procedure

No procedure is defined for this entry yet — it is catalogued so the coverage gap stays visible.

A reader must recover cleanly when the controller abandons a transfer part-way through, rather than stalling while it waits for fragments that will never arrive.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Why this isn’t scored

Cancelling a transfer part-way needs a control the test runner does not expose yet.

Requirement
informational
Triggered by
Evidence
Est. duration
file-transferrobustnesscancel

Procedure

  1. WIRESend osdp_KEEPACTIVE (milliseconds=7000)send + decode reply + timestamp; default 7000 ms
  2. WIRECapture every frame on the bus in parallel

Automated on send; a NAK is a failure.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

The ACK reply observed on the bus.

Requirement
optional
Triggered by
command
Evidence
bus capture
Est. duration
~1 s
file-transferkeepactivesession

The advanced/optional reader families, all conditional on special hardware or a manufacturer feature: biometric capture/match, PIV data and cryptographic authentication (GENAUTH/CRAUTH, some card-triggered), manufacturer-specific commands (MFG), and extended/transparent smart-card mode (XWR/XRD). Checked on the response side — a well-formed reply passes, a NAK to an advertised feature fails.

Procedure

  1. WIREMark the capture — present biometricanchor the biometric presentation in the trace
  2. DUTPresent the enrolled finger/face at the reader's biometric sensor now.
  3. WIRESend osdp_BIOREAD (reader=0, type=…, format=…, quality=…)
  4. WIRECapture every frame on the bus in parallel

A NAK when biometrics are advertised is a failure.

Preconditions

DUT must advertise the biometrics capability; otherwise the test is skipped as N/A.

Expected outcome

The BIOREADR reply observed on the bus.

Requirement
optional
Triggered by
DUT stimulus
Evidence
bus capture
Est. duration
~21 s
biometricsbioreadoptional

Procedure

  1. WIREMark the capture — present biometricanchor the live-sample presentation in the trace
  2. DUTPresent the live finger/face for comparison at the reader's sensor now.
  3. WIRESend osdp_BIOMATCH (reader=0, type=…, format=…, quality=…, template=00000000000000000000000000000000)template defaults to 16 hex zeroes if omitted
  4. WIRECapture every frame on the bus in parallel

A NAK is a failure.

Preconditions

DUT must advertise the biometrics capability; otherwise the test is skipped as N/A.

Expected outcome

The BIOMATCHR reply observed on the bus.

Requirement
optional
Triggered by
DUT stimulus
Evidence
bus capture
Est. duration
~21 s
biometricsbiomatchoptional

Procedure

  1. WIREMark the capture — present piv cardanchor the card insertion in the trace
  2. DUTInsert/present the PIV card at the reader now.
  3. WIRESend osdp_PIVDATA (object_id=<3-byte hex>, data_element=<hex>, offset=<2-byte hex>)
  4. WIRECapture every frame on the bus in parallel

A well-formed PIVDATAR satisfies the read. Checking the reply is automated; presenting the PIV card is manual.

Preconditions

DUT must advertise the smart card capability; otherwise the test is skipped as N/A.

Expected outcome

The PIVDATAR reply observed on the bus.

Requirement
optional
Triggered by
DUT stimulus
Evidence
bus capture
Est. duration
~21 s
pivpivdatasmart-cardoptional

Procedure

  1. WIRESend osdp_GENAUTH (template=witness, algoref=07, keyref=<hex>, payload=<hex DAT>)algoref must be "07" (RSA); payload is a hex Dynamic Auth Template
  2. WIREMeasure reply_size
  3. WIRECapture every frame on the bus in parallel

A GENAUTHR within the maximum message size passes; an oversize response header fails.

Preconditions

DUT must advertise the smart card capability; otherwise the test is skipped as N/A.

Expected outcome

On-device reply-size measurement, checked against the window in expect.

Requirement
optional
Triggered by
command
Evidence
measurement
Est. duration
~1 s
pivgenauthauthoptional

Procedure

  1. WIREMark the capture — present cardanchor the card presentation in the trace
  2. DUTPresent the credential at the reader now.
  3. WIRESend osdp_POLLthe osdp_RAW card read arrives on this poll and arms the reaction
  4. WIRESend osdp_GENAUTH (template=on_card_read)sent automatically as the next action after the RAW card read
  5. WIRECapture every frame on the bus in parallel

The GENAUTH is armed as the reaction to the next card read (RAW), so it fires in realistic card-read-then-authenticate order. Asserting on the raw binding requires that a real card-read report actually preceded the GENAUTH — without it, this would only be OCT_PEXT_04 sent from a different trigger.

Preconditions

DUT must advertise the smart card capability; otherwise the test is skipped as N/A.

Expected outcome

The RAW card read that armed the reaction, then the GENAUTHR reply observed on the bus.

Requirement
optional
Triggered by
DUT stimulus
Evidence
bus capture
Est. duration
~22 s
pivgenauthcard-triggeredoptional

Procedure

  1. WIRESend osdp_CRAUTH (template=challenge, algoref=07, keyref=<hex>, payload=<hex>)
  2. WIREMeasure reply_size
  3. WIRECapture every frame on the bus in parallel

A CRAUTHR within the maximum message size passes; an oversize response header fails.

Preconditions

DUT must advertise the smart card capability; otherwise the test is skipped as N/A.

Expected outcome

On-device reply-size measurement, checked against the window in expect.

Requirement
optional
Triggered by
command
Evidence
measurement
Est. duration
~1 s
pivcrauthauthoptional

Procedure

  1. WIREMark the capture — present cardanchor the card presentation in the trace
  2. DUTPresent the credential at the reader now.
  3. WIRESend osdp_POLLthe osdp_RAW card read arrives on this poll and arms the reaction
  4. WIRESend osdp_CRAUTH (template=on_card_read)sent automatically as the next command after the RAW card read
  5. WIRECapture every frame on the bus in parallel

The CRAUTH is armed as the reaction to the next card read (RAW). Asserting on the raw binding requires that a real card-read report actually preceded the CRAUTH — without it, this would only be OCT_PEXT_06 sent from a different trigger.

Preconditions

DUT must advertise the smart card capability; otherwise the test is skipped as N/A.

Expected outcome

The RAW card read that armed the reaction, then the CRAUTHR reply observed on the bus.

Requirement
optional
Triggered by
DUT stimulus
Evidence
bus capture
Est. duration
~22 s
pivcrauthcard-triggeredoptional

Procedure

  1. WIRESend osdp_MFG (oui=<6 hex>, command_id=MFG_SUPPORTED, command_specific_data=<hex>)oui defaults to the Driver's vendor code; an optional configuration address may be given. MFG_SUPPORTED is a named intent — the bench config maps it to a vendor-specific command id the PD implements.
  2. WIRECapture every frame on the bus in parallel

Manual on pd-dut: a generic PD implements no real vendor command, so an MFGREP round-trip needs the operator to supply concrete MFG command details (vendor code + command id + expected reply) that the DUT's host handler answers. Headless runs skip it. An MFGREP with a success status confirms the round-trip.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

The MFGREP reply observed on the bus.

Requirement
optional
Triggered by
command
Evidence
bus capture
Est. duration
~2 min
manufacturermfgoptional

Procedure

  1. WIRESend osdp_MFG (oui=<6 hex>, command_id=MFG_UNSUPPORTED, command_specific_data=<hex>)MFG_UNSUPPORTED is a named intent — the bench config maps it to a vendor-specific command id the PD cannot process, provoking MFGERRR. Without it this stimulus would be indistinguishable from OCT_PEXT_08's.
  2. WIRECapture every frame on the bus in parallel

The error counterpart of a vendor-specific reply: when the reader cannot carry out a vendor command, it answers with a vendor-defined error rather than staying silent.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Why this isn’t scored

This error reply has to come from the reader, so it cannot be provoked when the reader is the device under test. It is verified from the controller side, where the test rig plays the reader and sends the error itself.

Covered by OCT_AEXT_02

Requirement
optional
Triggered by
command
Evidence
Est. duration
manufacturermfgerroroptional

Procedure

  1. WIRESend osdp_MFG (oui=tool_vendor_code, command_id=1, command_specific_data=FF)command id 1 sends osdp_MFG using the Driver's own vendor code
  2. WIRECapture every frame on the bus in parallel

Pass on successful send.

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Expected outcome

The stimulus frame was transmitted on the wire (pass on successful send).

Requirement
optional
Triggered by
fault injection
Evidence
transmitted frame
Est. duration
~1 s
manufacturermfgset-pass

Procedure

  1. WIRESend osdp_XWRITE (mode=<hex>, pcmnd=<hex>, pdata=<hex>)or action-based scan / get-mode / set-mode(+mode) / set-zero(+mode)
  2. WIRECapture every frame on the bus in parallel

Automated on send/receive: the XWR command is dispatched and the XRD response parsed.

Preconditions

DUT must advertise the smart card capability; otherwise the test is skipped as N/A.

Expected outcome

The XRD reply observed on the bus.

Requirement
optional
Triggered by
command
Evidence
bus capture
Est. duration
~1 s
extendedtransparentxwritesmart-cardoptional

Procedure

  1. WIRESend osdp_MFG (oui=tool_vendor_code, command_id=MFG_SUPPORTED)issue a vendor MFG command that returns a manufacturer status; expect an MFGSTATR reply
  2. WIRECapture every frame on the bus in parallel

Enable against a DUT whose vendor command set produces an MFGSTATR. Expect an MFGSTATR reply, distinct from the MFGERRR error path (OCT_PEXT_09).

Preconditions

None — the test is indifferent to session state and needs no declared capability. It runs anywhere in the plan.

Why this isn’t scored

Which vendor command produces this status reply is specific to each manufacturer, so there is no stimulus that works against an arbitrary reader. This test can be pointed at a device whose vendor command set produces one.

Requirement
optional
Triggered by
command
Evidence
Est. duration
manufacturermfgstatrstatus

Per-capability PDCAP coverage mirroring SIA OSDP-Verified group 05: for each capability function code the PD advertises, confirm it appears in a well-formed osdp_PDCAP reply. Each test is gated on its capability precondition, so it runs only when the DUT claims that function and is skipped (n/a) otherwise. The overall PDCAP structure is checked by OCT_PCMD_04; the behaviour behind LED / buzzer / text / card / secure-channel / biometrics / smart-card / receive-buffer / CRC capabilities is checked by the dedicated tests in the other suites. This suite adds the per-function advertisement checks SIA lists individually but that had no dedicated behaviour test.

Procedure

  1. WIRESend osdp_CAPread PDCAP; the input capability tuple must be present (gated by the precondition)
  2. WIRECapture every frame on the bus in parallel

Preconditions

DUT must advertise the contact status monitoring capability; otherwise the test is skipped as N/A.

Expected outcome

A PDCAP reply advertising the contact-status-monitoring capability.

Requirement
optional
Triggered by
command
Evidence
bus capture
Est. duration
~1 s
capabilitiespdcapinputs

Procedure

  1. WIRESend osdp_CAPread PDCAP; the output capability tuple must be present
  2. WIRECapture every frame on the bus in parallel

Preconditions

DUT must advertise the output control capability; otherwise the test is skipped as N/A.

Expected outcome

A PDCAP reply advertising the output-control capability.

Requirement
optional
Triggered by
command
Evidence
bus capture
Est. duration
~1 s
capabilitiespdcapoutputs

Procedure

  1. WIRESend osdp_CAPread PDCAP; the combined-message-size capability tuple must be present
  2. WIRECapture every frame on the bus in parallel

Preconditions

DUT must advertise the combined message size capability; otherwise the test is skipped as N/A.

Expected outcome

A PDCAP reply advertising the largest-combined-message-size capability.

Requirement
optional
Triggered by
command
Evidence
bus capture
Est. duration
~1 s
capabilitiespdcapcombined-message

Procedure

  1. WIRESend osdp_CAPread PDCAP; the secure-PIN-entry capability tuple must be present
  2. WIRECapture every frame on the bus in parallel

Preconditions

DUT must advertise the secure pin entry capability; otherwise the test is skipped as N/A.

Expected outcome

A PDCAP reply advertising the secure-PIN-entry capability.

Requirement
optional
Triggered by
command
Evidence
bus capture
Est. duration
~1 s
capabilitiespdcapsecure-pin-entry

Procedure

  1. WIRESend osdp_CAPread PDCAP; the OSDP-version capability tuple must be present
  2. WIRECapture every frame on the bus in parallel

Preconditions

DUT must advertise the osdp version capability; otherwise the test is skipped as N/A.

Expected outcome

A PDCAP reply advertising the OSDP-version capability.

Requirement
optional
Triggered by
command
Evidence
bus capture
Est. duration
~1 s
capabilitiespdcapversion
FAQ

We get these questions a lot

Can I run OSDP conformance tests automatically in CI?

Yes. The suite runs every scenario it can drive over the bus unattended, so the same plan fits into CI — re-check each firmware build and catch conformance regressions the moment they appear.

Is this the same as SIA OSDP Verified?

No. Conformance Workspace is an independent pre-certification and CI regression tool. It is not affiliated with SIA, and its reports do not grant OSDP Verified certification — they help you find issues before formal verification.

What hardware does OSDP conformance testing need?

Two Osprio Mini units: one drives the device under test — a PD or an ACU — while the other independently monitors the bus for trustworthy timing, with no lab gear to buy.

Have a question? Ask us →

Related OSDP Tools

Explore the rest of the toolkit

Hardware

Built for Osprio Mini

Test basis & notice

Built on SIA's public test vectors — but not affiliated with SIA

The checks in the catalogue above are based on the public information the Security Industry Association (SIA) publishes about the OSDP Verified program — the documented test vectors and test cases that define what a Verified device has to demonstrate. We implement every vector and test case we can source, then layer our own engineers' tests on top for behaviour the published matrix does not reach. A clean run here is therefore a strong predictor of how a device will fare in formal verification.

Conformance Workspace is an independent pre-certification and CI regression-testing tool. Osprio is not affiliated with, endorsed by, or sponsored by the Security Industry Association (SIA). "OSDP" and "OSDP Verified" are programs and marks of SIA; SIA's OSDP Verified certification is a separate process carried out by SIA and runs orthogonally to this product.

The reports this workspace produces reflect your own testing and do not constitute, grant, or replace OSDP Verified certification. Its purpose is to help you validate a PD on your own bench and in CI — easing your way into the verification process and reducing the time-to-market delays that verification surprises can cause.