OPC UA Part 4 — Client/Server (UACP + SecureChannel) — Spec Coverage
Source: docs/standards/cache/opcfoundation/opcua-part4-services-1.05.07.pdf
(Services). Cross-spec:
opcua-part6-mappings-1.05.07.pdf (UACP §7.1, OPC UA Secure Conversation §6.7,
binary codec §5.2),
opcua-part7-profiles-1.05.02.pdf (transport profiles, SecurityPolicies)
(all in the same cache; not tracked in the repo for IP/copyright reasons).
Public spec: OPC UA online reference https://reference.opcfoundation.org/ (Part 4 Services, Part 6 Mappings, Part 7 Profiles).
Context: A native pure-Rust no_std + alloc OPC-UA Client/Server stack —
the request/response counterpart to the UADP PubSub stack
(zerodds-opcua-pubsub). Same approach as ZeroDDS’s full CORBA/MQTT/AMQP
stacks: a real wire stack, not just a gateway bridge. The Part 6 binary codec
is reused from zerodds-opcua-pubsub. forbid(unsafe_code).
Implementation:
crates/opcua-uacp/· docs.rs — UACP (Hello/Ack/Error/ReverseHello, message chunking), OPC UA Secure Conversation (OPN/MSG/CLO chunks, security headers, SequenceHeader, ChannelSecurityToken) and the secured SecurityPolicies (featurecrypto); 20 tests green (--features crypto).crates/opcua-server/· docs.rs — the full service set (Session/Read/Write/Call/Browse/ Discovery/Subscription), in-memory AddressSpace with a reference graph,Serverstate machine,Clientandopc.tcpTCP transport; 22 tests green, including a real TCP end-to-end and a secured loopback.
SecurityMode None and the secured SecurityPolicies (RSA/AES crypto,
Basic256Sha256/Aes128_Sha256_RsaOaep/Aes256_Sha256_RsaPss) are implemented
end to end. Open items: none.
§7.1 OPC UA Connection Protocol (UACP)
Spec: Part 6 §7.1, p. 80 — message structure (8-byte header
MessageType + ChunkType + MessageSize), Hello/Acknowledge/Error plus
ReverseHello (§7.1.3 Establishing a connection, p. 83).
Repo: crates/opcua-uacp/src/connection.rs (MessageType, ChunkType,
MessageHeader, HelloMessage, AcknowledgeMessage, ErrorMessage,
ReverseHelloMessage).
Tests: crates/opcua-uacp/src/connection.rs::tests::header_round_trips_and_sizes_match,
acknowledge_round_trips, error_round_trips, reverse_hello_round_trips,
unknown_message_type_rejected, oversized_string_rejected.
Status: done
§6.7 OPC UA Secure Conversation — chunk framing
Spec: Part 6 §6.7, p. 62 — SecureChannel messages as chunks
(OPN/MSG/CLO), AsymmetricAlgorithmSecurityHeader (OPN) /
SymmetricAlgorithmSecurityHeader (MSG/CLO), SequenceHeader
(§6.7.2 MessageChunk structure, p. 62).
Repo: crates/opcua-uacp/src/securechannel.rs
(SecureChannel::open_chunk / message_chunk / close_chunk, parse_chunk,
ParsedChunk, SECURITY_POLICY_NONE).
Tests: crates/opcua-uacp/src/securechannel.rs::tests::message_chunk_round_trip,
open_secure_channel_round_trip_none.
Status: done (SecurityMode None; secured crypto see §6.7 crypto)
§6.7 SecureChannel crypto — secured SecurityPolicies
Spec: Part 6 §6.7.2 (chunk security layout: SequenceHeader‖Body‖Padding‖
Signature, signature over MessageHeader…Padding, then encrypted),
§6.7.6 Deriving keys (p. 70, P-SHA256); Part 7 SecurityPolicies
Basic256Sha256, Aes128_Sha256_RsaOaep, Aes256_Sha256_RsaPss.
Repo (crypto core): crates/opcua-uacp/src/crypto.rs (feature crypto):
SecurityPolicy (URI/algorithm params), p_sha256 + derive_keys (§6.7.6:
signing/encrypting/IV), symmetric build_symmetric_chunk/open_symmetric_chunk
(AES-128/256-CBC + HMAC-SHA256, padding, Sign & SignAndEncrypt), asymmetric
build_asymmetric_chunk/open_asymmetric_chunk (RSA-OAEP-SHA1/SHA256 +
RSA-PKCS#1-v1.5/PSS over SHA-256, block-wise OPN crypto with padding/extra
padding byte + certificate thumbprint via sha1_thumbprint).
Repo (wiring): crates/opcua-uacp/src/securechannel.rs
(SecuritySession, SecureChannel::install_security/open_incoming, secured
message_chunk/close_chunk), crates/opcua-server/src/server.rs
(ServerSecurity, Server::set_security, open_secure_channel_secured: open
OPN → nonce → key derivation → secured OPN response + session install),
crates/opcua-server/src/client.rs (ClientSecurity, Client::set_security,
open_secure_channel_secured). Trust store = supplied peer certificates/public
keys; RNG caller-provided (Box<dyn CryptoRngCore + Send>, OS RNG under std).
Tests: crates/opcua-uacp/src/crypto.rs::tests::p_sha256_is_deterministic_and_sized,
derive_keys_lengths_and_mirror, symmetric_sign_and_encrypt_round_trip
(all 3 policies), symmetric_sign_only_round_trip, symmetric_tamper_is_rejected,
asymmetric_round_trip_oaep_pkcs15, asymmetric_round_trip_oaep_sha256_pss,
asymmetric_wrong_signer_is_rejected, full_secured_handshake_flow;
secured end-to-end: crates/opcua-server/src/client.rs::tests::e2e_secured_loopback_sign_and_encrypt
(real RSA keys + OS RNG: encrypted+signed handshake → Read/Call/Write over
Basic256Sha256/SignAndEncrypt).
Status: done (crypto core + chunk security + Server/Client handshake fully wired and tested with a real secured E2E)
§5.6.2 OpenSecureChannel
Spec: Part 4 §5.6.2, p. 21 — OpenSecureChannelRequest/Response,
SecurityTokenRequestType, ChannelSecurityToken (RevisedLifetime).
Repo: crates/opcua-uacp/src/securechannel.rs
(OpenSecureChannelRequest, OpenSecureChannelResponse,
SecurityTokenRequestType, ChannelSecurityToken),
crates/opcua-server/src/server.rs (Server::open_secure_channel).
Tests: crates/opcua-uacp/src/securechannel.rs::tests::open_response_round_trip,
crates/opcua-server/src/client.rs::tests::e2e_loopback_connect_read_call
(runs OPN).
Status: done (SecurityMode None)
§5.7.2 CreateSession
Spec: Part 4 §5.7.2, p. 24 — CreateSessionRequest/Response
(SessionId, AuthenticationToken, RevisedSessionTimeout, ServerEndpoints,
ServerSignature).
Repo: crates/opcua-server/src/services.rs
(CreateSessionRequest, CreateSessionResponse),
crates/opcua-server/src/server.rs (handle_service CreateSession arm).
Tests: crates/opcua-server/src/client.rs::tests::e2e_loopback_connect_read_call,
e2e_tcp_connect_read_call.
Status: done
§5.7.3 ActivateSession
Spec: Part 4 §5.7.3, p. 29 — ActivateSessionRequest/Response
(ClientSignature, LocaleIds, UserIdentityToken, ServerNonce).
Repo: crates/opcua-server/src/services.rs
(ActivateSessionRequest, ActivateSessionResponse).
Tests: crates/opcua-server/src/services.rs::tests::session_lifecycle_round_trips,
crates/opcua-server/src/client.rs::tests::e2e_loopback_connect_read_call.
Status: done (anonymous UserIdentityToken; SecurityMode None)
§5.7.4 CloseSession
Spec: Part 4 §5.7.4, p. 31 — CloseSessionRequest (DeleteSubscriptions)
/Response.
Repo: crates/opcua-server/src/services.rs
(CloseSessionRequest, CloseSessionResponse).
Tests: crates/opcua-server/src/services.rs::tests::session_lifecycle_round_trips.
Status: done
§5.11.2 Read
Spec: Part 4 §5.11.2, p. 45 — ReadRequest (MaxAge, TimestampsToReturn,
ReadValueId[]) / ReadResponse (DataValue[]).
Repo: crates/opcua-server/src/services.rs
(ReadRequest, ReadResponse, ReadValueId),
crates/opcua-server/src/server.rs (Read arm against AddressSpace),
crates/opcua-server/src/client.rs (Client::read_values).
Tests: crates/opcua-server/src/services.rs::tests::read_request_round_trips,
read_response_round_trips,
crates/opcua-server/src/client.rs::tests::read_unknown_node_yields_bad_status.
Status: done (Value attribute)
§5.11.4 Write
Spec: Part 4 §5.11.4, p. 50 — WriteRequest (WriteValue[]) /
WriteResponse (StatusCode[]).
Repo: crates/opcua-server/src/services.rs
(WriteRequest, WriteResponse, WriteValue),
crates/opcua-server/src/server.rs (Write arm: set_value,
Bad_AttributeIdInvalid for non-Value attributes),
crates/opcua-server/src/client.rs (Client::write_values).
Tests: crates/opcua-server/src/services.rs::tests::write_round_trips,
crates/opcua-server/src/client.rs::tests::e2e_loopback_write_then_read.
Status: done (Value attribute)
§5.12.2 Call
Spec: Part 4 §5.12.2, p. 54 — CallRequest (CallMethodRequest[]) /
CallResponse (CallMethodResult[]).
Repo: crates/opcua-server/src/services.rs
(CallMethodRequest, CallMethodResult, CallRequest, CallResponse),
crates/opcua-server/src/address_space.rs (method handler registry),
crates/opcua-server/src/client.rs (Client::call_method).
Tests: crates/opcua-server/src/services.rs::tests::call_round_trips,
crates/opcua-server/src/address_space.rs::tests::method_call_dispatch,
crates/opcua-server/src/client.rs::tests::e2e_loopback_connect_read_call,
e2e_tcp_connect_read_call.
Status: done
§5.9.2 Browse (View Service Set)
Spec: Part 4 §5.9.2 Browse (p. 38), §7.29 ReferenceDescription (p. 148), §7.6 BrowseResult (p. 118), §7.44 ViewDescription (p. 169); ExpandedNodeId Part 6 §5.2.2.10.
Repo: crates/opcua-server/src/address_space.rs (node/reference model:
NodeMeta, ReferenceRecord, NodeClass, ns0 reference_types constants,
add_node/add_reference/node_meta/browse with direction +
reference-subtype filter (includeSubtypes) + node-class mask),
crates/opcua-server/src/services.rs (ViewDescription, BrowseDescription,
ReferenceDescription, BrowseResult, BrowseRequest/BrowseResponse,
ExpandedNodeId wire), crates/opcua-server/src/server.rs (browse_one:
reference filter + resultMask projection, Bad_NodeIdUnknown for unknown
nodes), crates/opcua-server/src/client.rs (Client::browse).
Tests: crates/opcua-server/src/address_space.rs::tests::browse_forward_and_inverse,
browse_subtype_filter_excludes_non_hierarchical, browse_node_class_mask_filters_targets,
crates/opcua-server/src/services.rs::tests::browse_round_trips,
crates/opcua-server/src/client.rs::tests::e2e_loopback_browse
(Objects→Boiler→Temperature over Organizes/HasComponent).
Status: done (continuation points: single batch, no BrowseNext —
address spaces of this size return everything in one BrowseResult)
§5.5.4 / §5.5.2 Discovery — GetEndpoints + FindServers
Spec: Part 4 §5.5.4 GetEndpoints (p. 14), §5.5.2 FindServers (p. 12) — session-less discovery services (SecureChannel only, no session needed).
Repo: crates/opcua-server/src/services.rs
(GetEndpointsRequest/GetEndpointsResponse (NodeIds 426/429),
FindServersRequest/FindServersResponse (NodeIds 422/425)),
crates/opcua-server/src/server.rs (dispatch arms: GetEndpoints returns the
server’s EndpointDescription, FindServers its ApplicationDescription),
crates/opcua-server/src/client.rs (Client::open_channel — Hello+OPN without
a session — plus Client::get_endpoints/find_servers).
Tests: crates/opcua-server/src/services.rs::tests::discovery_requests_round_trip,
crates/opcua-server/src/client.rs::tests::e2e_loopback_discovery
(session-less channel → GetEndpoints returns an endpoint with SecurityPolicy
None, FindServers returns the server).
Status: done
§5.13 / §5.14 Subscription + MonitoredItem Service Sets
Spec: Part 4 §5.14.2 CreateSubscription (p. 76), §5.14.4 SetPublishingMode (p. 79), §5.13.2 CreateMonitoredItems (p. 63), §5.14.5 Publish (p. 81), §5.14.8 DeleteSubscriptions (p. 85); §7.25.2 DataChangeNotification (p. 145), §7.26 NotificationMessage (p. 147).
Repo: crates/opcua-server/src/services.rs
(CreateSubscriptionRequest/Response, SetPublishingModeRequest/Response,
MonitoringParameters, MonitoredItemCreateRequest/Result,
CreateMonitoredItemsRequest/Response, SubscriptionAcknowledgement,
MonitoredItemNotification, DataChangeNotification
(ExtensionObject wrapping TypeId 811), NotificationMessage,
PublishRequest/Response, DeleteSubscriptionsRequest/Response),
crates/opcua-server/src/server.rs (subscription/monitored-item state,
publish_one: sample-on-publish — on each Publish, sample the monitored
items against the AddressSpace and report changed values as a
DataChangeNotification), crates/opcua-server/src/client.rs
(create_subscription/create_monitored_items/publish/delete_subscriptions).
Tests: crates/opcua-server/src/services.rs::tests::subscription_round_trips,
publish_data_change_notification_round_trips,
crates/opcua-server/src/client.rs::tests::e2e_loopback_subscription_publish
(subscription + monitored item on a node → first Publish reports the initial
value, no change → empty, after a Write the new value, then
DeleteSubscriptions).
Status: done (sample-on-publish model, suited to the synchronous transport; Modify/Republish and server-paced sampling are not required as the push use case is also covered by Part 14 PubSub)
§7.32/§7.33 Common service headers + common types
Spec: Part 4 §7.32 RequestHeader (p. 150), §7.33 ResponseHeader (p. 151), §7.12 DiagnosticInfo (p. 131), §7.36 SignatureData (p. 153), §7.28 ReadValueId (p. 148), §7.14 EndpointDescription (p. 133), §7.20 MessageSecurityMode (p. 135).
Repo: crates/opcua-uacp/src/securechannel.rs
(RequestHeader, ResponseHeader, null_extension_object, minimal
DiagnosticInfo skip), crates/opcua-server/src/services.rs
(SignatureData, ReadValueId, header encode/decode against the public structs),
crates/opcua-server/src/wire.rs (String/ByteString/Array/DiagnosticInfo helpers),
MessageSecurityMode/EndpointDescription from zerodds-opcua-pubsub.
Tests: crates/opcua-uacp/src/securechannel.rs::tests::response_header_with_string_table_round_trips,
crates/opcua-server/src/services.rs::tests::read_response_round_trips.
Status: done
§5.2 OPC UA Binary — codec reuse
Spec: Part 6 §5.2, p. 18 — binary encoding (built-in types, NodeId, Variant, DataValue, ExtensionObject, arrays).
Repo: reused from crates/opcua-pubsub/src/binary/ via
UaReader/UaWriter/UaEncode/UaDecode; NodeId/Variant/DataValue/
ExtensionObject from zerodds-opcua-gateway.
Tests: covered by the PubSub codec tests
(crates/opcua-pubsub/src/binary/) plus every round-trip test here.
Status: done
§7.2 OPC UA TCP — opc.tcp transport (end-to-end)
Spec: Part 6 §7.2, p. 86 — UA-TCP mapping; transport profile
uatcp-uasc-uabinary (Part 7).
Repo: crates/opcua-server/src/client.rs
(TcpTransport, serve_connection, Transport trait, LoopbackTransport),
crates/opcua-server/src/server.rs (Server::process).
Tests: crates/opcua-server/src/client.rs::tests::e2e_tcp_connect_read_call
(real opc.tcp socket: connect/Read/Call over TcpListener+thread),
e2e_loopback_connect_read_call, e2e_loopback_write_then_read.
Status: done
Audit status
16 done / 0 partial / 0 open / 0 n/a (informative) / 0 n/a (rejected).
Test run: cargo test -p zerodds-opcua-uacp -p zerodds-opcua-server --features crypto
— 42 tests green (20 UACP incl. 10 crypto + 22 server incl. secured E2E +
Browse + Discovery + Subscription/Publish), 0 failed; including a real
opc.tcp E2E and a secured Basic256Sha256 loopback.
Open items: none. Decision records: none.
OPC UA Part 4 — Client/Server (UACP + SecureChannel) — Spec-Coverage
Quelle: docs/standards/cache/opcfoundation/opcua-part4-services-1.05.07.pdf
(Services). Cross-Spec:
opcua-part6-mappings-1.05.07.pdf (UACP §7.1, OPC UA Secure Conversation §6.7,
Binär-Codec §5.2),
opcua-part7-profiles-1.05.02.pdf (Transport-Profile, SecurityPolicies)
(alle im selben Cache; aus IP-/Copyright-Gründen nicht im Repo getrackt).
Öffentliche Spec: OPC-UA-Online-Referenz https://reference.opcfoundation.org/ (Part 4 Services, Part 6 Mappings, Part 7 Profiles).
Kontext: Nativer pure-Rust no_std + alloc OPC-UA-Client/Server-Stack —
das Request/Response-Gegenstück zum UADP-PubSub-Stack
(zerodds-opcua-pubsub). Gleiches Vorgehen wie bei den vollen
CORBA-/MQTT-/AMQP-Stacks von ZeroDDS: echter Wire-Stack, nicht nur eine
Gateway-Brücke. Der Part-6-Binär-Codec wird aus zerodds-opcua-pubsub
wiederverwendet. forbid(unsafe_code).
Implementation:
crates/opcua-uacp/· docs.rs — UACP (Hello/Ack/Error/ReverseHello, Message-Chunking), OPC UA Secure Conversation (OPN/MSG/CLO-Chunks, Security-Header, SequenceHeader, ChannelSecurityToken) und die gesicherten SecurityPolicies (Featurecrypto); 20 Tests grün (--features crypto).crates/opcua-server/· docs.rs — voller Service-Satz (Session/Read/Write/Call/Browse/ Discovery/Subscription), in-memory AddressSpace mit Referenzgraph,Server-Zustandsautomat,Clientundopc.tcp-TCP-Transport; 22 Tests grün, inkl. echtem TCP-End-to-End und gesichertem Loopback.
SecurityMode None und die gesicherten SecurityPolicies (RSA-/AES-Krypto,
Basic256Sha256/Aes128_Sha256_RsaOaep/Aes256_Sha256_RsaPss) sind end-to-end
implementiert. Offene Punkte: keine.
§7.1 OPC UA Connection Protocol (UACP)
Spec: Part 6 §7.1, S. 80 — Message-Struktur (8-Byte-Header
MessageType + ChunkType + MessageSize), Hello/Acknowledge/Error sowie
ReverseHello (§7.1.3 Establishing a connection, S. 83).
Repo: crates/opcua-uacp/src/connection.rs (MessageType, ChunkType,
MessageHeader, HelloMessage, AcknowledgeMessage, ErrorMessage,
ReverseHelloMessage).
Tests: crates/opcua-uacp/src/connection.rs::tests::header_round_trips_and_sizes_match,
acknowledge_round_trips, error_round_trips, reverse_hello_round_trips,
unknown_message_type_rejected, oversized_string_rejected.
Status: done
§6.7 OPC UA Secure Conversation — Chunk-Rahmung
Spec: Part 6 §6.7, S. 62 — SecureChannel-Nachrichten als Chunks
(OPN/MSG/CLO), AsymmetricAlgorithmSecurityHeader (OPN) /
SymmetricAlgorithmSecurityHeader (MSG/CLO), SequenceHeader
(§6.7.2 MessageChunk structure, S. 62).
Repo: crates/opcua-uacp/src/securechannel.rs
(SecureChannel::open_chunk / message_chunk / close_chunk, parse_chunk,
ParsedChunk, SECURITY_POLICY_NONE).
Tests: crates/opcua-uacp/src/securechannel.rs::tests::message_chunk_round_trip,
open_secure_channel_round_trip_none.
Status: done (SecurityMode None; gesicherte Krypto siehe §6.7-Krypto)
§6.7 SecureChannel-Krypto — gesicherte SecurityPolicies
Spec: Part 6 §6.7.2 (Chunk-Security-Layout: SequenceHeader‖Body‖Padding‖
Signature, Signatur über MessageHeader…Padding, danach verschlüsselt),
§6.7.6 Deriving keys (S. 70, P-SHA256); Part 7 SecurityPolicies
Basic256Sha256, Aes128_Sha256_RsaOaep, Aes256_Sha256_RsaPss.
Repo (Krypto-Kern): crates/opcua-uacp/src/crypto.rs (Feature crypto):
SecurityPolicy (URI/Algo-Parameter), p_sha256 + derive_keys (§6.7.6:
Signing/Encrypting/IV), symmetrisch build_symmetric_chunk/
open_symmetric_chunk (AES-128/256-CBC + HMAC-SHA256, Padding, Sign &
SignAndEncrypt), asymmetrisch build_asymmetric_chunk/open_asymmetric_chunk
(RSA-OAEP-SHA1/SHA256 + RSA-PKCS#1-v1.5/PSS über SHA-256, block-weise OPN-Krypto
mit Padding/ExtraPaddingByte + Zertifikat-Thumbprint via sha1_thumbprint).
Repo (Verdrahtung): crates/opcua-uacp/src/securechannel.rs
(SecuritySession, SecureChannel::install_security/open_incoming,
gesicherte message_chunk/close_chunk), crates/opcua-server/src/server.rs
(ServerSecurity, Server::set_security, open_secure_channel_secured:
OPN öffnen → Nonce → Key-Derivation → gesicherte OPN-Antwort + Session-Install),
crates/opcua-server/src/client.rs (ClientSecurity, Client::set_security,
open_secure_channel_secured). Trust-Store = übergebene Peer-Zertifikate/
-Public-Keys; RNG Caller-bereitgestellt (Box<dyn CryptoRngCore + Send>,
OS-RNG unter std).
Tests: crates/opcua-uacp/src/crypto.rs::tests::p_sha256_is_deterministic_and_sized,
derive_keys_lengths_and_mirror, symmetric_sign_and_encrypt_round_trip
(alle 3 Policies), symmetric_sign_only_round_trip, symmetric_tamper_is_rejected,
asymmetric_round_trip_oaep_pkcs15, asymmetric_round_trip_oaep_sha256_pss,
asymmetric_wrong_signer_is_rejected, full_secured_handshake_flow;
gesicherter End-to-End: crates/opcua-server/src/client.rs::tests::e2e_secured_loopback_sign_and_encrypt
(echte RSA-Keys + OS-RNG: verschlüsselter+signierter Handshake → Read/Call/Write
über Basic256Sha256/SignAndEncrypt).
Status: done (Krypto-Kern + Chunk-Security + Server/Client-Handshake vollständig verdrahtet und mit echtem gesichertem E2E getestet)
§5.6.2 OpenSecureChannel
Spec: Part 4 §5.6.2, S. 21 — OpenSecureChannelRequest/Response,
SecurityTokenRequestType, ChannelSecurityToken (RevisedLifetime).
Repo: crates/opcua-uacp/src/securechannel.rs
(OpenSecureChannelRequest, OpenSecureChannelResponse,
SecurityTokenRequestType, ChannelSecurityToken),
crates/opcua-server/src/server.rs (Server::open_secure_channel).
Tests: crates/opcua-uacp/src/securechannel.rs::tests::open_response_round_trip,
crates/opcua-server/src/client.rs::tests::e2e_loopback_connect_read_call
(durchläuft OPN).
Status: done (SecurityMode None)
§5.7.2 CreateSession
Spec: Part 4 §5.7.2, S. 24 — CreateSessionRequest/Response
(SessionId, AuthenticationToken, RevisedSessionTimeout, ServerEndpoints,
ServerSignature).
Repo: crates/opcua-server/src/services.rs
(CreateSessionRequest, CreateSessionResponse),
crates/opcua-server/src/server.rs (handle_service CreateSession-Arm).
Tests: crates/opcua-server/src/client.rs::tests::e2e_loopback_connect_read_call,
e2e_tcp_connect_read_call.
Status: done
§5.7.3 ActivateSession
Spec: Part 4 §5.7.3, S. 29 — ActivateSessionRequest/Response
(ClientSignature, LocaleIds, UserIdentityToken, ServerNonce).
Repo: crates/opcua-server/src/services.rs
(ActivateSessionRequest, ActivateSessionResponse).
Tests: crates/opcua-server/src/services.rs::tests::session_lifecycle_round_trips,
crates/opcua-server/src/client.rs::tests::e2e_loopback_connect_read_call.
Status: done (Anonymous-UserIdentityToken; SecurityMode None)
§5.7.4 CloseSession
Spec: Part 4 §5.7.4, S. 31 — CloseSessionRequest (DeleteSubscriptions)
/Response.
Repo: crates/opcua-server/src/services.rs
(CloseSessionRequest, CloseSessionResponse).
Tests: crates/opcua-server/src/services.rs::tests::session_lifecycle_round_trips.
Status: done
§5.11.2 Read
Spec: Part 4 §5.11.2, S. 45 — ReadRequest (MaxAge, TimestampsToReturn,
ReadValueId[]) / ReadResponse (DataValue[]).
Repo: crates/opcua-server/src/services.rs
(ReadRequest, ReadResponse, ReadValueId),
crates/opcua-server/src/server.rs (Read-Arm gegen AddressSpace),
crates/opcua-server/src/client.rs (Client::read_values).
Tests: crates/opcua-server/src/services.rs::tests::read_request_round_trips,
read_response_round_trips,
crates/opcua-server/src/client.rs::tests::read_unknown_node_yields_bad_status.
Status: done (Value-Attribut)
§5.11.4 Write
Spec: Part 4 §5.11.4, S. 50 — WriteRequest (WriteValue[]) /
WriteResponse (StatusCode[]).
Repo: crates/opcua-server/src/services.rs
(WriteRequest, WriteResponse, WriteValue),
crates/opcua-server/src/server.rs (Write-Arm: set_value,
Bad_AttributeIdInvalid für Nicht-Value-Attribute),
crates/opcua-server/src/client.rs (Client::write_values).
Tests: crates/opcua-server/src/services.rs::tests::write_round_trips,
crates/opcua-server/src/client.rs::tests::e2e_loopback_write_then_read.
Status: done (Value-Attribut)
§5.12.2 Call
Spec: Part 4 §5.12.2, S. 54 — CallRequest (CallMethodRequest[]) /
CallResponse (CallMethodResult[]).
Repo: crates/opcua-server/src/services.rs
(CallMethodRequest, CallMethodResult, CallRequest, CallResponse),
crates/opcua-server/src/address_space.rs (Method-Handler-Registry),
crates/opcua-server/src/client.rs (Client::call_method).
Tests: crates/opcua-server/src/services.rs::tests::call_round_trips,
crates/opcua-server/src/address_space.rs::tests::method_call_dispatch,
crates/opcua-server/src/client.rs::tests::e2e_loopback_connect_read_call,
e2e_tcp_connect_read_call.
Status: done
§5.9.2 Browse (View Service Set)
Spec: Part 4 §5.9.2 Browse (S. 38), §7.29 ReferenceDescription (S. 148), §7.6 BrowseResult (S. 118), §7.44 ViewDescription (S. 169); ExpandedNodeId Part 6 §5.2.2.10.
Repo: crates/opcua-server/src/address_space.rs (Knoten-/Referenz-Modell:
NodeMeta, ReferenceRecord, NodeClass, reference_types-Konstanten ns0,
add_node/add_reference/node_meta/browse mit Richtung +
Reference-Subtype-Filter (includeSubtypes) + NodeClass-Maske),
crates/opcua-server/src/services.rs (ViewDescription, BrowseDescription,
ReferenceDescription, BrowseResult, BrowseRequest/BrowseResponse,
ExpandedNodeId-Wire), crates/opcua-server/src/server.rs (browse_one:
Reference-Filter + resultMask-Projektion, Bad_NodeIdUnknown für unbekannte
Knoten), crates/opcua-server/src/client.rs (Client::browse).
Tests: crates/opcua-server/src/address_space.rs::tests::browse_forward_and_inverse,
browse_subtype_filter_excludes_non_hierarchical, browse_node_class_mask_filters_targets,
crates/opcua-server/src/services.rs::tests::browse_round_trips,
crates/opcua-server/src/client.rs::tests::e2e_loopback_browse
(Objects→Boiler→Temperature über Organizes/HasComponent).
Status: done (Continuation-Points: einzelner Batch, kein BrowseNext —
AddressSpaces dieser Größe liefern alles in einem BrowseResult)
§5.5.4 / §5.5.2 Discovery — GetEndpoints + FindServers
Spec: Part 4 §5.5.4 GetEndpoints (S. 14), §5.5.2 FindServers (S. 12) — session-lose Discovery-Services (nur SecureChannel, keine Session nötig).
Repo: crates/opcua-server/src/services.rs
(GetEndpointsRequest/GetEndpointsResponse (NodeIds 426/429),
FindServersRequest/FindServersResponse (NodeIds 422/425)),
crates/opcua-server/src/server.rs (Dispatch-Arme: GetEndpoints liefert die
EndpointDescription des Servers, FindServers seine ApplicationDescription),
crates/opcua-server/src/client.rs (Client::open_channel — Hello+OPN ohne
Session — plus Client::get_endpoints/find_servers).
Tests: crates/opcua-server/src/services.rs::tests::discovery_requests_round_trip,
crates/opcua-server/src/client.rs::tests::e2e_loopback_discovery
(session-loser Channel → GetEndpoints liefert Endpoint mit
SecurityPolicy None, FindServers liefert den Server).
Status: done
§5.13 / §5.14 Subscription + MonitoredItem Service Sets
Spec: Part 4 §5.14.2 CreateSubscription (S. 76), §5.14.4 SetPublishingMode (S. 79), §5.13.2 CreateMonitoredItems (S. 63), §5.14.5 Publish (S. 81), §5.14.8 DeleteSubscriptions (S. 85); §7.25.2 DataChangeNotification (S. 145), §7.26 NotificationMessage (S. 147).
Repo: crates/opcua-server/src/services.rs
(CreateSubscriptionRequest/Response, SetPublishingModeRequest/Response,
MonitoringParameters, MonitoredItemCreateRequest/Result,
CreateMonitoredItemsRequest/Response, SubscriptionAcknowledgement,
MonitoredItemNotification, DataChangeNotification
(ExtensionObject-Wrapping TypeId 811), NotificationMessage,
PublishRequest/Response, DeleteSubscriptionsRequest/Response),
crates/opcua-server/src/server.rs (Subscription-/MonitoredItem-State,
publish_one: Sample-on-Publish — bei jedem Publish die MonitoredItems
gegen den AddressSpace abgleichen, geänderte Werte als DataChangeNotification),
crates/opcua-server/src/client.rs
(create_subscription/create_monitored_items/publish/delete_subscriptions).
Tests: crates/opcua-server/src/services.rs::tests::subscription_round_trips,
publish_data_change_notification_round_trips,
crates/opcua-server/src/client.rs::tests::e2e_loopback_subscription_publish
(Subscription + MonitoredItem auf einem Knoten → erster Publish liefert
Initialwert, kein Change → leer, nach Write neuer Wert, dann
DeleteSubscriptions).
Status: done (Sample-on-Publish-Modell, passend zum synchronen Transport; Modify/Republish und server-getaktetes Sampling sind nicht nötig, da der Push-Use-Case auch von Part-14-PubSub abgedeckt ist)
§7.32/§7.33 Gemeinsame Service-Header + Common-Types
Spec: Part 4 §7.32 RequestHeader (S. 150), §7.33 ResponseHeader (S. 151), §7.12 DiagnosticInfo (S. 131), §7.36 SignatureData (S. 153), §7.28 ReadValueId (S. 148), §7.14 EndpointDescription (S. 133), §7.20 MessageSecurityMode (S. 135).
Repo: crates/opcua-uacp/src/securechannel.rs
(RequestHeader, ResponseHeader, null_extension_object, minimaler
DiagnosticInfo-Skip), crates/opcua-server/src/services.rs
(SignatureData, ReadValueId, Header-Encode/Decode gegen die Public-Structs),
crates/opcua-server/src/wire.rs (String/ByteString/Array/DiagnosticInfo-Hilfen),
MessageSecurityMode/EndpointDescription aus zerodds-opcua-pubsub.
Tests: crates/opcua-uacp/src/securechannel.rs::tests::response_header_with_string_table_round_trips,
crates/opcua-server/src/services.rs::tests::read_response_round_trips.
Status: done
§5.2 OPC UA Binary — Codec-Wiederverwendung
Spec: Part 6 §5.2, S. 18 — Binär-Kodierung (Built-in-Typen, NodeId, Variant, DataValue, ExtensionObject, Arrays).
Repo: wiederverwendet aus crates/opcua-pubsub/src/binary/ über
UaReader/UaWriter/UaEncode/UaDecode; NodeId/Variant/DataValue/
ExtensionObject aus zerodds-opcua-gateway.
Tests: abgedeckt durch die PubSub-Codec-Tests
(crates/opcua-pubsub/src/binary/) + alle Round-Trip-Tests hier.
Status: done
§7.2 OPC UA TCP — opc.tcp-Transport (End-to-End)
Spec: Part 6 §7.2, S. 86 — UA-TCP-Mapping; Transport-Profil
uatcp-uasc-uabinary (Part 7).
Repo: crates/opcua-server/src/client.rs
(TcpTransport, serve_connection, Transport-Trait, LoopbackTransport),
crates/opcua-server/src/server.rs (Server::process).
Tests: crates/opcua-server/src/client.rs::tests::e2e_tcp_connect_read_call
(echter opc.tcp-Socket: Connect/Read/Call über TcpListener+Thread),
e2e_loopback_connect_read_call, e2e_loopback_write_then_read.
Status: done
Audit-Status
16 done / 0 partial / 0 open / 0 n/a (informative) / 0 n/a (rejected).
Test-Lauf: cargo test -p zerodds-opcua-uacp -p zerodds-opcua-server --features crypto
— 42 Tests grün (20 UACP inkl. 10 Krypto + 22 Server inkl. gesichertem E2E +
Browse + Discovery + Subscription/Publish), 0 failed; inkl. echtem opc.tcp-E2E
und gesichertem Basic256Sha256-Loopback.
Offene Punkte: keine. Decision-Records: keine.