Giter Site home page Giter Site logo

locka99 / opcua Goto Github PK

View Code? Open in Web Editor NEW
457.0 22.0 126.0 12.8 MB

A client and server implementation of the OPC UA specification written in Rust

License: Mozilla Public License 2.0

Rust 99.12% Batchfile 0.01% JavaScript 0.74% HTML 0.14% Shell 0.01%
opc-ua embedded rust monitoring opc iec-62541 iot

opcua's Introduction

Introduction

This is an OPC UA server / client API implementation for Rust.

Build Status

OPC UA is an industry standard for monitoring of data. It's used extensively for embedded devices, industrial control, IoT, etc. - just about anything that has data that something else wants to monitor, control or visualize.

Rust is a systems programming language and is therefore a natural choice for implementing OPC UA. This implementation supports the embedded, micro and nano profiles but may grow to support features in time.

Read the compatibility page for how the implementation conforms with the OPC UA spec.

Read the change log for changes per version as well as aspirational / upcoming work.

License

The code is licenced under MPL-2.0. Like all open source code, you use this code at your own risk.

Setup

Read the setup for instructions on building OPCUA for Rust.

Read cross compilation for hints for cross compiling OPC UA for Rust to other platforms.

Migration notes

If you're using an earlier version of OPC UA for Rust, read the migration notes.

Design

Read the design for more in-depth description of implementation.

Tutorial

Tutorials / user guides are still work in progress.

Further Documentation

The API documentation is generated from the latest published crates. This may be some way behind current development.

Samples

If you want to get stuck in, there are a number of samples in the samples/ folder. The simple-client and the simple-server projects are minimal client and server programs respectively.

# In one bash
cd opcua/samples/simple-server
cargo run
# In another bash
cd opcua/samples/simple-client
cargo run

The full list of samples:

  1. simple-server - an OPC UA server that adds 4 variables v1, v2, v3 and v4 and updates them from a timer via push and pull mechanisms.
  2. simple-client - an OPC UA client that connects to a server and subscribes to the values of v1, v2, v3 and v4.
  3. discovery-client - an OPC UA client that connects to a discovery server and lists the servers registered on it.
  4. chess-server - an OPC UA server that connects to a chess engine as its back end and updates variables representing the state of the game.
  5. demo-server - an OPC UA server that is more complex than the simple server and can be used for compliance testing.
  6. mqtt-client - an OPC UA client that subscribes to some values and publishes them to an MQTT broker.
  7. web-client - an OPC UA client that subscribes to some values and streams them over a websocket.
  8. modbus-server - an OPC UA server that translates variables from MODBUS.

opcua's People

Contributors

0x2ec avatar biancode avatar claytondavidson avatar colinfinck avatar ctron avatar dependabot[bot] avatar divi255 avatar einarmo avatar florolf avatar gstvg avatar jarngreipr avatar jh-isw avatar jijun99 avatar joshuagleaton avatar laumann avatar locka99 avatar lovasoa avatar markussilvan avatar matthiasbeyer avatar milgner avatar nkbai avatar schroeder- avatar simonhoss avatar svanharmelen avatar szallol avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

opcua's Issues

Issue when using endpoints with private hostnames

Hello !

I found what I think is a bug in the way this library handles endpoints (but maybe I am wrong and there is a way to bypass this behavior).

I try to connect an OPC-UA server using a public hostname, but this server exposes endpoints that match private hostnames on its network.
Unfortunately, the library attempts to resolve the private hostname and since it cannot it fails to use it.

[opcua-client-0.5.0/src/client.rs:opcua_client::client] [ERROR] Invalid address privatehost.mycompany.com:49320, cannot be parsed Custom { kind: Other, error: StringError("failed to lookup address information: Name or service not known") }
[opcua-client-0.5.0/src/client.rs:opcua_client::client] [ERROR] Got an error while creating the default session - The Server does not recognize the QueryString specified.

I managed to "solve" the issue by setting the hostname in my /etc/hosts and associating it with the server public IP but I think the library should always do it without trying to resolve the hostname (other clients and libraries seem to do that at least).

Please note that I am not at all an expert in OPC-UA and I may have misunderstood how things are expected to work.

Thank you !

Server connection loss is not propageted up to session

I'm currently testing edge cases against a small python server setup. When killing the server process and restarting it, the client does not seem to be able to reconnect. That said, I'm not quite sure, whether it notices that the server has been disconnected. Is there anyway to catch this? (I tried the connection state changed and session closed callbacks, but they're not being called though).

Log output:

2019-01-25 10:54:40.071 - INFO - opcua_client::comms::tcp_transport - ReadState has dropped
2019-01-25 10:54:40.071 - INFO - opcua_client::comms::tcp_transport - Read loop finished
2019-01-25 10:54:41.581 - ERROR - opcua_client::comms::tcp_transport - Write IO error Os { code: 32, kind: BrokenPipe, message: "Broken pipe" }
2019-01-25 10:54:41.582 - ERROR - opcua_client::comms::tcp_transport - Write loop is finished with an error ()
2019-01-25 10:54:41.582 - INFO - opcua_client::comms::tcp_transport - WriteState has dropped
2019-01-25 10:55:09.579 - INFO - opcua_client::session_state - Making secure channel request
2019-01-25 10:55:09.579 - INFO - opcua_client::session_state - security_mode = None
2019-01-25 10:55:09.579 - INFO - opcua_client::session_state - security_policy = None
2019-01-25 10:55:19.608 - INFO - opcua_client::session_state - Timeout waiting for response from server
2019-01-25 10:55:19.609 - INFO - opcua_client::message_queue - Request 53 has timed out and any response will be ignored
2019-01-25 10:55:19.609 - INFO - opcua_client::session_state - Making secure channel request
2019-01-25 10:55:19.609 - INFO - opcua_client::session_state - security_mode = None
2019-01-25 10:55:19.609 - INFO - opcua_client::session_state - security_policy = None

The making secure channel request with sec mode and policy endlessly loop after that point.

Implement crypto in the client

Start passing certs, nonces and using crypto to connect, create session and activate. Create session will have to be called on a timer to periodically renew credentials.

How to retrieve NamespaceIndexes with the client

Hi

Is there a way for the OPC-UA client to retrieve (browse) the name-space Indexes of an server (root-folder)

I tried the browse function of the

let bd:[BrowseDescription;1] = [BrowseDescription {
            node_id: NodeId::new(0,"RootFolder"),
            browse_direction: BrowseDirection::Forward,
            reference_type_id: NodeId::new(0,"RootFolder"),
            include_subtypes: true,
            node_class_mask:  0xff,
            result_mask:  0xff
        }];

match session.browse( &bd) {
            Ok(r) => {
                let e = r.unwrap();
                for i in &e{
                    println!("Status Code {:?} ",i.status_code);
                    //println!("Status Code {:?} {:?}",i.continuation_point,i.status_code);
                }
            }
            Err(e)=> println!("Faied due to {:?}",e.to_string()),
        };

But this always returns
Status Code IS_ERROR | BadResourceUnavailable | BadEncodingLimitsExceeded | BadShutdown | BadNotImplemented | BadMonitoredItemFilterUnsupported | BadContentFilterInvalid | BadReferenceTypeIdInvalid

The session it-self must be valid because creating a monitored item subscription with hard-coded namespaceIdx works fine.

Best Regards

Wolfgang

Subscription notifications and acknowledgements are not working correctly

Subscriptions and monitored items are sort-of working, i.e. an item can be monitored and its value is changing, but some of the notifications are coming back with old values and there is an issue with publish request acknowledgements. Some clients are printing errors of unknown acknowledgements.

It means that monitoring is sending data but it skips values.

Question about ARM cross-compile

Hi Adam,

are you experienced to cross-compile for ARM or ARMv7, please?

I tried to run cargo build --target=arm-unknown-linux-gnueabi or cargo build --target=armv7-unknown-linux-gnueabihf , but it does not compile crates with openssl dependency.
Some advice would be very great. I searched for the environment variables or PATH entries, but it doesn't compile, whatever I try to configure.

Happy coding!
Klaus

Panic when running sample servers

When running the any of the sample servers, and then using any of the sample clients i get this panic on the server.

thread 'tokio-runtime-worker-2' panicked at 'explicit panic', server/src/state.rs:145:20
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
thread 'tokio-runtime-worker-5' panicked at 'called `Result::unwrap()` on an `Err` value: "PoisonError { inner: .. }"', src/libcore/result.rs:thread 'thread 'tokio-runtime-worker-2tokio-runtime-worker-1' panicked at '' panicked at 'called `Result::unwrap()` on an `Err` value: "PoisonError { inner: .. }"called `Result::unwrap()` on an `Err` value: "PoisonError { inner: .. }"', ', src/libcore/result.rssrc/libcore/result.rs::11651165::55

I tracked it down to user_pass_security_policy_id
Which only matches a subset of the SecurityPolicies.

I worked around it by just adding a couple of new cases, but i'm not sure what the correct behaviour is, and maybe it should fail but with a better error description.

SSL

Why openssl dependency instead of native-tls?

Panic with very large requested_session_timeout

Hi,

First of all, thank you for creating this library 💯

I am trying to use a (slightly modified) simple-server to monitor some values on a server, however, the server seems to request an (unreasonably) long session timeout, which results in a panic.

$ RUST_BACKTRACE=1 RUST_OPCUA_LOG=debug ./client
2020-09-24 11:36:21.095 - INFO - opcua_console_logging - Logging is enabled, use RUST_OPCUA_LOG environment variable to control filtering, logging level
2020-09-24 11:36:21.096 - WARN - opcua_client::config - Endpoint config contains no endpoints
2020-09-24 11:36:21.108 - INFO - opcua_client::session - Connect
2020-09-24 11:36:21.109 - INFO - opcua_client::session - Security policy = None
2020-09-24 11:36:21.109 - INFO - opcua_client::session - Security mode = None
2020-09-24 11:36:21.109 - DEBUG - opcua_client::comms::tcp_transport - Connecting to "opc.tcp://192.168.1.100/"
2020-09-24 11:36:21.109 - DEBUG - opcua_client::comms::tcp_transport - Creating a connection task to connect to 192.168.1.100:4840 with url opc.tcp://192.168.1.100/
2020-09-24 11:36:21.110 - DEBUG - opcua_core::runtime - deregistering component connection-task, 1
2020-09-24 11:36:21.110 - DEBUG - opcua_client::comms::tcp_transport - Waiting for a connect (or failure to connect)
2020-09-24 11:36:21.111 - DEBUG - opcua_client::comms::tcp_transport - Client tokio tasks are starting for connection
2020-09-24 11:36:21.111 - DEBUG - opcua_core::runtime - deregistering component client-connection-thread-ThreadId(3)
2020-09-24 11:36:21.114 - DEBUG - tokio_reactor - adding I/O source: 0
2020-09-24 11:36:21.114 - DEBUG - tokio_reactor::registration - scheduling Write for: 0
2020-09-24 11:36:21.135 - DEBUG - opcua_client::comms::tcp_transport - Sending HELLO
2020-09-24 11:36:21.135 - DEBUG - opcua_core::runtime - deregistering component finished-monitor-task, 1
2020-09-24 11:36:21.135 - DEBUG - opcua_core::runtime - deregistering component read-task, 1
2020-09-24 11:36:21.136 - DEBUG - opcua_core::runtime - deregistering component write-task, 1
2020-09-24 11:36:21.137 - DEBUG - opcua_core::runtime - deregistering component connection-task, 1
2020-09-24 11:36:21.137 - DEBUG - tokio_reactor::registration - scheduling Read for: 0
2020-09-24 11:36:21.196 - DEBUG - opcua_client::comms::tcp_transport - Reader got ack AcknowledgeMessage { message_header: MessageHeader { message_type: Acknowledge, message_size: 28 }, protocol_version: 0, receive_buffer_size: 65536, send_buffer_size: 65536, max_message_size: 16777216, max_chunk_count: 1 }
2020-09-24 11:36:21.197 - DEBUG - tokio_reactor::registration - scheduling Read for: 0
2020-09-24 11:36:21.210 - DEBUG - opcua_client::comms::tcp_transport - Connected
2020-09-24 11:36:21.211 - DEBUG - opcua_client::session - session:1 open_secure_channel
2020-09-24 11:36:21.211 - INFO - opcua_client::session_state - Making secure channel request
2020-09-24 11:36:21.211 - INFO - opcua_client::session_state - security_mode = None
2020-09-24 11:36:21.211 - INFO - opcua_client::session_state - security_policy = None
2020-09-24 11:36:21.211 - DEBUG - opcua_client::comms::tcp_transport - About to write
2020-09-24 11:36:21.211 - DEBUG - opcua_core::comms::secure_channel - AsymmetricSecurityHeader = AsymmetricSecurityHeader { security_policy_uri: UAString { value: Some("http://opcfoundation.org/UA/SecurityPolicy#None") }, sender_certificate: ByteString { value: None }, receiver_certificate_thumbprint: ByteString { value: None } }
2020-09-24 11:36:21.212 - DEBUG - opcua_client::message_queue - Request 1 was processed by the server
2020-09-24 11:36:21.231 - DEBUG - opcua_client::message_queue - Response to Request 1 has been stored
2020-09-24 11:36:21.232 - DEBUG - tokio_reactor::registration - scheduling Read for: 0
2020-09-24 11:36:21.261 - DEBUG - opcua_client::session_state - Setting transport's security token
2020-09-24 11:36:21.261 - INFO - opcua_client::session - Connect was successful
2020-09-24 11:36:21.261 - DEBUG - opcua_client::session - session:1 get_endpoints
2020-09-24 11:36:21.262 - DEBUG - opcua_client::comms::tcp_transport - About to write
2020-09-24 11:36:21.262 - DEBUG - opcua_client::message_queue - Request 2 was processed by the server
2020-09-24 11:36:21.270 - DEBUG - tokio_reactor::registration - scheduling Read for: 0
2020-09-24 11:36:21.273 - DEBUG - tokio_reactor::registration - scheduling Read for: 0
2020-09-24 11:36:21.275 - DEBUG - opcua_client::message_queue - Response to Request 2 has been stored
2020-09-24 11:36:21.276 - DEBUG - tokio_reactor::registration - scheduling Read for: 0
2020-09-24 11:36:21.312 - DEBUG - opcua_client::session - session:1 get_endpoints, success
2020-09-24 11:36:21.312 - DEBUG - opcua_client::message_queue - Sending a quit to the message receiver
2020-09-24 11:36:21.312 - DEBUG - opcua_client::comms::tcp_transport - Waiting for a disconnect
2020-09-24 11:36:21.312 - DEBUG - opcua_client::comms::tcp_transport - About to write
2020-09-24 11:36:21.312 - DEBUG - opcua_client::comms::tcp_transport - Writer is about to send a CloseSecureChannelRequest which means it should close in a moment
2020-09-24 11:36:21.313 - DEBUG - opcua_client::message_queue - Request 3 was processed by the server
2020-09-24 11:36:21.313 - DEBUG - opcua_client::comms::tcp_transport - Writer is setting the connection state to finished(good)
2020-09-24 11:36:21.313 - DEBUG - opcua_client::comms::tcp_transport - Write bytes task received a close, so closing connection after this send
2020-09-24 11:36:21.313 - DEBUG - opcua_client::comms::tcp_transport - Writer loop is finished with an error
2020-09-24 11:36:21.313 - DEBUG - opcua_core::runtime - deregistering component write-task, 1
2020-09-24 11:36:21.313 - INFO - opcua_client::comms::tcp_transport - WriteState has dropped
2020-09-24 11:36:21.317 - DEBUG - tokio_reactor - dropping I/O source: 0
2020-09-24 11:36:21.317 - DEBUG - opcua_client::comms::tcp_transport - Read loop is terminating due to finished state
2020-09-24 11:36:21.318 - INFO - opcua_client::comms::tcp_transport - ReadState has dropped
2020-09-24 11:36:21.318 - DEBUG - opcua_client::comms::tcp_transport - Read loop ended with an error
2020-09-24 11:36:21.318 - DEBUG - opcua_core::runtime - deregistering component read-task, 1
2020-09-24 11:36:21.337 - DEBUG - opcua_client::comms::tcp_transport - finished monitor task detects finished state and has set a finished flag
2020-09-24 11:36:21.337 - INFO - opcua_client::comms::tcp_transport - Timer for finished is finished
2020-09-24 11:36:21.337 - DEBUG - opcua_core::runtime - deregistering component finished-monitor-task, 1
2020-09-24 11:36:21.338 - DEBUG - opcua_client::comms::tcp_transport - Client tokio tasks have stopped for connection
2020-09-24 11:36:21.338 - DEBUG - opcua_client::session_state - Session was closed with status = BadCommunicationError
2020-09-24 11:36:21.339 - DEBUG - opcua_core::runtime - deregistering component client-connection-thread-ThreadId(3)
2020-09-24 11:36:21.412 - DEBUG - opcua_client::comms::tcp_transport - Disconnected
2020-09-24 11:36:21.413 - INFO - opcua_client::session - Session has dropped
2020-09-24 11:36:21.413 - INFO - opcua_client::comms::tcp_transport - TcpTransport has dropped
2020-09-24 11:36:21.413 - INFO - opcua_client::subscription_timer - Timer receiver has terminated
2020-09-24 11:36:21.413 - INFO - opcua_client::session_state - SessionState has dropped
2020-09-24 11:36:21.414 - INFO - opcua_client::session - Connect
2020-09-24 11:36:21.415 - INFO - opcua_client::session - Security policy = None
2020-09-24 11:36:21.415 - INFO - opcua_client::session - Security mode = None
2020-09-24 11:36:21.416 - DEBUG - opcua_client::comms::tcp_transport - Connecting to "opc.tcp://br-automation:4840/"
2020-09-24 11:36:21.417 - DEBUG - opcua_client::comms::tcp_transport - Creating a connection task to connect to 192.168.1.100:4840 with url opc.tcp://br-automation:4840
2020-09-24 11:36:21.417 - DEBUG - opcua_core::runtime - deregistering component connection-task, 2
2020-09-24 11:36:21.418 - DEBUG - opcua_client::comms::tcp_transport - Waiting for a connect (or failure to connect)
2020-09-24 11:36:21.418 - DEBUG - opcua_client::comms::tcp_transport - Client tokio tasks are starting for connection
2020-09-24 11:36:21.418 - DEBUG - opcua_core::runtime - deregistering component client-connection-thread-ThreadId(11)
2020-09-24 11:36:21.421 - DEBUG - tokio_reactor - adding I/O source: 0
2020-09-24 11:36:21.421 - DEBUG - tokio_reactor::registration - scheduling Write for: 0
2020-09-24 11:36:21.422 - DEBUG - opcua_client::comms::tcp_transport - Sending HELLO
2020-09-24 11:36:21.423 - DEBUG - opcua_core::runtime - deregistering component finished-monitor-task, 2
2020-09-24 11:36:21.423 - DEBUG - opcua_core::runtime - deregistering component read-task, 2
2020-09-24 11:36:21.424 - DEBUG - opcua_core::runtime - deregistering component write-task, 2
2020-09-24 11:36:21.424 - DEBUG - opcua_core::runtime - deregistering component connection-task, 2
2020-09-24 11:36:21.425 - DEBUG - tokio_reactor::registration - scheduling Read for: 0
2020-09-24 11:36:21.429 - DEBUG - opcua_client::comms::tcp_transport - Reader got ack AcknowledgeMessage { message_header: MessageHeader { message_type: Acknowledge, message_size: 28 }, protocol_version: 0, receive_buffer_size: 65536, send_buffer_size: 65536, max_message_size: 16777216, max_chunk_count: 1 }
2020-09-24 11:36:21.430 - DEBUG - tokio_reactor::registration - scheduling Read for: 0
2020-09-24 11:36:21.518 - DEBUG - opcua_client::comms::tcp_transport - Connected
2020-09-24 11:36:21.518 - DEBUG - opcua_client::session - session:2 open_secure_channel
2020-09-24 11:36:21.519 - INFO - opcua_client::session_state - Making secure channel request
2020-09-24 11:36:21.519 - INFO - opcua_client::session_state - security_mode = None
2020-09-24 11:36:21.519 - INFO - opcua_client::session_state - security_policy = None
2020-09-24 11:36:21.519 - DEBUG - opcua_client::comms::tcp_transport - About to write
2020-09-24 11:36:21.519 - DEBUG - opcua_core::comms::secure_channel - AsymmetricSecurityHeader = AsymmetricSecurityHeader { security_policy_uri: UAString { value: Some("http://opcfoundation.org/UA/SecurityPolicy#None") }, sender_certificate: ByteString { value: None }, receiver_certificate_thumbprint: ByteString { value: None } }
2020-09-24 11:36:21.520 - DEBUG - opcua_client::message_queue - Request 1 was processed by the server
2020-09-24 11:36:21.526 - DEBUG - opcua_client::message_queue - Response to Request 1 has been stored
2020-09-24 11:36:21.526 - DEBUG - tokio_reactor::registration - scheduling Read for: 0
2020-09-24 11:36:21.569 - DEBUG - opcua_client::session_state - Setting transport's security token
2020-09-24 11:36:21.569 - INFO - opcua_client::session - Connect was successful
2020-09-24 11:36:21.570 - DEBUG - opcua_client::session - session:2 CreateSessionRequest = CreateSessionRequest { request_header: RequestHeader { authentication_token: NodeId { namespace: 0, identifier: Numeric(0) }, timestamp: DateTime { date_time: 2020-09-24T11:36:21.570578200Z }, request_handle: 2, return_diagnostics: (empty), audit_entry_id: UAString { value: None }, timeout_hint: 10000, additional_header: ExtensionObject { node_id: NodeId { namespace: 0, identifier: Numeric(0) }, body: None } }, client_description: ApplicationDescription { application_uri: UAString { value: Some("urn:MyFirstClient") }, product_uri: UAString { value: Some("") }, application_name: LocalizedText { locale: UAString { value: Some("") }, text: UAString { value: Some("My First Client") } }, application_type: Client, gateway_server_uri: UAString { value: None }, discovery_profile_uri: UAString { value: None }, discovery_urls: None }, server_uri: UAString { value: None }, endpoint_url: UAString { value: Some("opc.tcp://192.168.1.100:4840") }, session_name: UAString { value: Some("Rust OPCUA Client") }, client_nonce: ByteString { value: None }, client_certificate: ByteString { value: Some([ ### Shortened for brevity ### ]) }, requested_session_timeout: 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0, max_response_message_size: 0 }
2020-09-24 11:36:21.571 - DEBUG - opcua_client::comms::tcp_transport - About to write
2020-09-24 11:36:21.572 - DEBUG - opcua_client::message_queue - Request 2 was processed by the server
2020-09-24 11:36:21.587 - DEBUG - tokio_reactor::registration - scheduling Read for: 0
2020-09-24 11:36:21.588 - DEBUG - tokio_reactor::registration - scheduling Read for: 0
2020-09-24 11:36:21.591 - DEBUG - tokio_reactor::registration - scheduling Read for: 0
2020-09-24 11:36:21.593 - DEBUG - tokio_reactor::registration - scheduling Read for: 0
2020-09-24 11:36:21.597 - DEBUG - opcua_client::message_queue - Response to Request 2 has been stored
2020-09-24 11:36:21.598 - DEBUG - tokio_reactor::registration - scheduling Read for: 0
2020-09-24 11:36:21.621 - DEBUG - opcua_client::session - session:2 Revised session timeout is 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
2020-09-24 11:36:21.622 - DEBUG - opcua_client::session - session:2 spawn_session_activity_task(179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000)
thread 'main' panicked at 'attempt to multiply with overflow', /home/nss/.cargo/registry/src/github.com-1ecc6299db9ec823/opcua-client-0.7.0/src/session.rs:918:41
stack backtrace:
0: backtrace::backtrace::libunwind::trace
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/libunwind.rs:86
1: backtrace::backtrace::trace_unsynchronized
at /cargo/registry/src/github.com-1ecc6299db9ec823/backtrace-0.3.46/src/backtrace/mod.rs:66
2: std::sys_common::backtrace::_print_fmt
at src/libstd/sys_common/backtrace.rs:78
3: <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt
at src/libstd/sys_common/backtrace.rs:59
4: core::fmt::write
at src/libcore/fmt/mod.rs:1076
5: std::io::Write::write_fmt
at src/libstd/io/mod.rs:1537
6: std::sys_common::backtrace::_print
at src/libstd/sys_common/backtrace.rs:62
7: std::sys_common::backtrace::print
at src/libstd/sys_common/backtrace.rs:49
8: std::panicking::default_hook::{{closure}}
at src/libstd/panicking.rs:198
9: std::panicking::default_hook
at src/libstd/panicking.rs:217
10: std::panicking::rust_panic_with_hook
at src/libstd/panicking.rs:526
11: rust_begin_unwind
at src/libstd/panicking.rs:437
12: core::panicking::panic_fmt
at src/libcore/panicking.rs:85
13: core::panicking::panic
at src/libcore/panicking.rs:50
14: opcua_client::session::Session::spawn_session_activity_task
at /home/nss/.cargo/registry/src/github.com-1ecc6299db9ec823/opcua-client-0.7.0/src/session.rs:918
15: opcua_client::session::Session::create_session
16: opcua_client::session::Session::connect_and_activate
17: opcua_client::client::Client::connect_to_endpoint
at /home/nss/.cargo/registry/src/github.com-1ecc6299db9ec823/opcua-client-0.7.0/src/client.rs:236
18: client::main
at src/bin/client.rs:24
19: std::rt::lang_start::{{closure}}
at /home/nss/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/rt.rs:67
20: std::rt::lang_start_internal::{{closure}}
at src/libstd/rt.rs:52
21: std::panicking::try::do_call
at src/libstd/panicking.rs:348
22: std::panicking::try
at src/libstd/panicking.rs:325
23: std::panic::catch_unwind
at src/libstd/panic.rs:394
24: std::rt::lang_start_internal
at src/libstd/rt.rs:51
25: std::rt::lang_start
at /home/nss/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libstd/rt.rs:67
26: main
27: __libc_start_main
at /build/glibc-FUvrFr/glibc-2.28/csu/libc-start.c:308
note: Some details are omitted, run with RUST_BACKTRACE=full for a verbose backtrace.
2020-09-24 11:36:22.414 - INFO - opcua_client::session - Session has dropped
2020-09-24 11:36:22.414 - DEBUG - opcua_client::message_queue - Sending a quit to the message receiver
2020-09-24 11:36:22.414 - DEBUG - opcua_client::comms::tcp_transport - Waiting for a disconnect
2020-09-24 11:36:22.414 - DEBUG - opcua_client::comms::tcp_transport - About to write
2020-09-24 11:36:22.414 - DEBUG - opcua_client::comms::tcp_transport - Writer is about to send a CloseSecureChannelRequest which means it should close in a moment
2020-09-24 11:36:22.415 - DEBUG - opcua_client::message_queue - Request 3 was processed by the server
2020-09-24 11:36:22.415 - DEBUG - opcua_client::comms::tcp_transport - Writer is setting the connection state to finished(good)
2020-09-24 11:36:22.415 - DEBUG - opcua_client::comms::tcp_transport - Write bytes task received a close, so closing connection after this send
2020-09-24 11:36:22.415 - DEBUG - opcua_client::comms::tcp_transport - Writer loop is finished with an error
2020-09-24 11:36:22.415 - DEBUG - opcua_core::runtime - deregistering component write-task, 2
2020-09-24 11:36:22.415 - INFO - opcua_client::comms::tcp_transport - WriteState has dropped
2020-09-24 11:36:22.424 - DEBUG - opcua_client::comms::tcp_transport - finished monitor task detects finished state and has set a finished flag
2020-09-24 11:36:22.424 - INFO - opcua_client::comms::tcp_transport - Timer for finished is finished
2020-09-24 11:36:22.424 - DEBUG - opcua_core::runtime - deregistering component finished-monitor-task, 2
2020-09-24 11:36:22.476 - DEBUG - opcua_core::comms::tcp_codec - TcpCodec decode abort flag has been set and is terminating
2020-09-24 11:36:22.476 - ERROR - opcua_client::comms::tcp_transport - Read loop error Custom { kind: Other, error: "StatusCode BadOperationAbandoned" }
2020-09-24 11:36:22.476 - DEBUG - tokio_reactor - dropping I/O source: 0
2020-09-24 11:36:22.476 - INFO - opcua_client::comms::tcp_transport - ReadState has dropped
2020-09-24 11:36:22.476 - DEBUG - opcua_client::comms::tcp_transport - Read loop ended with an error
2020-09-24 11:36:22.476 - DEBUG - opcua_core::runtime - deregistering component read-task, 2
2020-09-24 11:36:22.477 - DEBUG - opcua_client::comms::tcp_transport - Client tokio tasks have stopped for connection
2020-09-24 11:36:22.477 - DEBUG - opcua_client::session_state - Session was closed with status = BadCommunicationError
2020-09-24 11:36:22.477 - DEBUG - opcua_core::runtime - deregistering component client-connection-thread-ThreadId(11)
2020-09-24 11:36:22.514 - DEBUG - opcua_client::comms::tcp_transport - Disconnected
2020-09-24 11:36:22.515 - INFO - opcua_client::comms::tcp_transport - TcpTransport has dropped
2020-09-24 11:36:22.515 - INFO - opcua_client::subscription_timer - Timer receiver has terminated
2020-09-24 11:36:22.515 - INFO - opcua_client::session_state - SessionState has dropped

`BadSessionIdInvalid` error on subscription with high publishing_interval

Hey there,
I believe this is somewhat more of a documentation topic, but I just noticed, that my subscription / session breaks, as soon as I choose a sufficiently high publishing_interval when creating a subscription. Working with 1f64 works fine, while choosing e.g. 1000f64 invalidates the session.

// changing the first arg to 1000f64 invalidates the code
let subscription_id = session.create_subscription(1f64, 10, 30, 0, 0, true, callback)?

As the method also takes in a lifetime_count and max_keep_alive_count argument, I was wondering whether I can solve this issue by setting these properly. In case this does the job, I'd post a PR for a more elaborate documentation of create_subscription.
Best,
D

Is version 0.7 a "stable" version that can be used (relatively) safely?

And how about (the work in progress) version 0.8? Would like to know your take on if these (or at least version 0.7) could be used in a production like setting? And also if it's save to use the client within a Tokio code base.

It looks like the async_run function is made to spawn a new dedicated OS thread and then does all the scheduling in that single thread. Is that correct? If so I guess it can be safely used as it will actually have it's own runtime in its own thread. But good to be sure and/or if there are any other caveats to take into account.

Thanks! And also thanks for this extensive crate!

Unable to connect to server anonymously

Split from #43


When attempting to connect to an OPC UA server configured with ServerConfig::load from a milo client, I am unable to connect to the server, and receive this error message: no anonymous token policy found.


I found one way to work around this issue, though I'm not entirely sure why it's happening.

I am able to connect to the root endpoint anonymously if I specify an additional endpoint in the server.conf.

Example:

  milo:
    path: /milo
    security_policy: None
    security_mode: None
    security_level: 1
    password_security_policy: ~
    user_token_ids:
      - ANONYMOUS
      - sample_password_user
      - sample_x509_user

To recap:
With the default server.conf, I am unable to connect to the opcua server anonymously, as the client cites it can't find any anonymous token policies.
However, if I specify seemingly any additional (i.e. not /) endpoints in the server.conf, I can then connect to the root endpoint anonymously.

Session breaks (MQTT Client Example)

I was trying the mqtt-client sample connected to a OPC UA Server (KEPServer EX6) however it throws some errors at the beginning but does not seem to affect because it starts gathering the data from the nodes, however after a while (maybe 10 minutes??) the session drops, is there any particular reason for this happening?

Branch: master
Rust Version: rustc 1.31.1 (b6c32da9b 2018-12-18)
Operating System: Linux Mint 19 (Ubuntu 18.04)

opc.tcp://192.168.15.26:49320 - None / None
opc.tcp://192.168.15.26:49320 - Basic128Rsa15 / Sign
opc.tcp://192.168.15.26:49320 - Basic128Rsa15 / SignAndEncrypt
opc.tcp://192.168.15.26:49320 - Basic256 / Sign
opc.tcp://192.168.15.26:49320 - Basic256 / SignAndEncrypt
2019-01-24 17:49:40.655 - ERROR - opcua_client::comms::tcp_transport - Read loop error Custom { kind: Other, error: StringError("StatusCode IS_ERROR | GoodClamped | GoodEntryInserted | GoodEntryReplaced | BadUnexpectedError | BadInternalError | BadOutOfMemory | BadTooManyOperations | BadDataTypeIdUnknown| BadCertificateInvalid | BadSecurityChecksFailed | BadIdentityTokenInvalid | BadIdentityTokenRejected | BadSecureChannelIdInvalid | BadInvalidTimestamp| BadNoCommunication | BadWaitingForInitialData | BadNodeIdInvalid | BadTcpMessageTooLarge | BadTcpNotEnoughResources | BadTcpInternalError | BadTcpEndpointUrlInvalid | BadNoEntryExists | BadTimestampNotSupported | BadEndOfStream | BadNoDataAvailable | BadWaitingForResponse | BadOperationAbandoned") }
2019-01-24 17:49:40.656 - ERROR - opcua_client::comms::tcp_transport - Read loop ended with an error ()
Creating subscription
Created a subscription with id = 57
Data change from server:
Publishing opcua-rust/mqtt-client/2/Simulation Examples.Functions.Ramp1 = Int32(39)
Data change from server:
Publishing opcua-rust/mqtt-client/2/Simulation Examples.Functions.Ramp1 = Int32(71)
...
After a while...
...
Data change from server:
Publishing opcua-rust/mqtt-client/2/Simulation Examples.Functions.Ramp1 = Int32(79)
Data change from server:
Publishing opcua-rust/mqtt-client/2/Simulation Examples.Functions.Ramp1 = Int32(43)
2019-01-24 17:59:03.913 - ERROR - opcua_client::comms::tcp_transport - Write IO error Os { code: 32, kind: BrokenPipe, message: "Broken pipe" }
2019-01-24 17:59:03.914 - ERROR - opcua_client::comms::tcp_transport - Write bytes task error
2019-01-24 17:59:03.914 - ERROR - opcua_client::comms::tcp_transport - Write loop is finished with an error ()

Is it possible to adjust the status in a Variable's DataValue?

We have been building a small OPC-UA server using this project as the basis, and have been viewing values with UaExpert. The software we're building communicates with devices through other protocols (primarily Modbus) and makes values available in the OPC-UA address space.

The software may not be connected to a physical device, but that doesn't prevent us from populating the address space with folders and null variables. The only "issue" is that the initial variables value (Variant::Empty) are not really valid values, so I figured I should set the DataValue.status to something other than StatusCode::Good. Initially, I just want to set it to StatusCode::IS_ERROR because this mirrors how other applications do it (we've been comparing to Kepware).

Is it possible to control a Variable's status? If not, would you be interested in a PR to implement such functionality?

pub struct Variable {
base: Base,
data_type: NodeId,
historizing: bool,
value_rank: i32,
value: DataValue,
access_level: u8,
user_access_level: u8,
array_dimensions: Option<Vec<u32>>,
minimum_sampling_interval: Option<f64>,
#[derivative(Debug = "ignore")]
value_setter: Option<Arc<Mutex<dyn AttributeSetter + Send>>>,
#[derivative(Debug = "ignore")]
value_getter: Option<Arc<Mutex<dyn AttributeGetter + Send>>>,
}

(I would label this issue as a "question")

Add serde serialization

Hey there,
are you planning on adding serde serialization support any time soon? Right now, I'm following the path described here, but this is really tedious, as there are multiple layers of composed structs 😢

simple-server example fails due WouldBlock Error, is then stuck in loop

Hi,

I tried to get started with the examples. However I had some problems with the encrypted endpoints at first. I could not connect with the opcua-commander, even if I set the securityPolicy and securityMode explicitly: opcua-commander -e opc.tcp://localhost:4855 -P=None -s=NONE.
There is also no error log after the simple server receives the CreateSessionRequest.
My guess was that this is due the exact same path (/) for each endpoint in the server.conf yaml.
So I removed all endpoints besides None,None from the server.conf.
Now the opcua-commander can connect and opens its gui. Securitymode and policy matches. But the session is immediately disconnect. Now the server seems to be stuck in a loop, where he receives a new connection but discards it immediately and so on.

I tracked this down to the TcpTransport::run function:
line: 153

// Try to read, using timeout as a polling mechanism
let bytes_read_result = stream.read(&mut in_buf);

This result is an WouldBlock error and yields in breaking the loop. This is the log msg:
2017-11-08 16:52:48.232 - DEBUG - opcua_server::comms::tcp_transport - Read error - kind = WouldBlock, Error { repr: Os { code: 35, message: "Resource temporarily unavailable" } }

The Session is now shutting down before the next session is created and discarded again...

Here is the log of one cycle:

2017-11-08 16:52:48.179 - INFO - opcua_server::server - Handling new connection Ok(TcpStream { addr: V4(127.0.0.1:4855), peer: V4(127.0.0.1:59838), fd: 4 })
2017-11-08 16:52:48.179 - INFO - opcua_server::comms::tcp_transport - Session started 2017-11-08 16:52:48.179447 UTC
2017-11-08 16:52:48.180 - INFO - opcua_server::server - Removing terminated session
2017-11-08 16:52:48.180 - DEBUG - opcua_server::comms::tcp_transport - Processing HELLO
2017-11-08 16:52:48.180 - DEBUG - opcua_server::comms::tcp_transport - Sending ACK
2017-11-08 16:52:48.181 - DEBUG - opcua_server::comms::tcp_transport - Processing message
2017-11-08 16:52:48.181 - DEBUG - opcua_server::comms::secure_channel_service - Message security mode == None
2017-11-08 16:52:48.232 - DEBUG - opcua_server::comms::tcp_transport - Read error - kind = WouldBlock, Error { repr: Os { code: 35, message: "Resource temporarily unavailable" } }
2017-11-08 16:52:48.232 - INFO - opcua_server::comms::tcp_transport - Session terminating normally, session_status_code = GOOD
2017-11-08 16:52:48.232 - INFO - opcua_server::comms::tcp_transport - Terminating socket
2017-11-08 16:52:48.232 - INFO - opcua_server::comms::tcp_transport - Session is finished Duration { secs: 0, nanos: 53278000 }
2017-11-08 16:52:48.232 - INFO - opcua_server::server - Session thread is terminated

Any Ideas?

Publish Request being sent every publish interval rather than after receiving response

I may be missing some configuration on my end. If that is the case, some guidance would be much appreciated.
The issue happens as publish request is being sent from client at subscribed publish interval rather than after receiving a response. This results in server complaining about too many publish requests.

    ServiceFault
        ResponseHeader: ResponseHeader
            Timestamp: May 24, 2020 18:47:49.946309200 PDT
            RequestHandle: 156
            ServiceResult: 0x80780000 [BadTooManyPublishRequests]
            ServiceDiagnostics: DiagnosticInfo
            StringTable: Array of String
            AdditionalHeader: ExtensionObject

arrays & strings are not enforcing size limits

The server config allows the server to set the string, byte string and array size limits but the info doesn't get down to the decode() functions of the respective types. The binary encoder API should pass limits as a parameter to decode() to allow implemenations to enforce limits if they wish.

How can I get the raw value out of a Variant?

I want to serialize the value of a changes monitored item as part of another struct that has a field of type serde_json::Value so that I can put all kinds of values in there. But if I give it a received value it serializes to something like this:

{"my_value":{"Double":7247.500215355554}}

While I would like to get something like this:

{"my_value": 7247.500215355554}

I tried using value.0 but (at least in my code/setup) the compiler doesn't allow that. So any idea how to achieve this? Thanks!

It takes too long time to send a request

reproduce step

  1. connect to an endpoint
  2. create a subscribtion
  3. add 1000 item to monitor
  4. session::run_async in the background
  5. sleep 5 seconds
  6. call Session::read to read any node
  7. get the value of the node.

session takes 3 or more seconds to send the ReadRequest ( use wireshark to capture).
it seems there are some locks doesn't release .

if step 6 and 7 is before step 4, the read returns very fast.

A response with request handle 0 doesn't belong to any request and will be ignored

I get a lot of these errors when using the OPC UA client:

2020-09-23 08:51:27.101 - ERROR - opcua_client::message_queue - A response with request handle 0 doesn't belong to any request and will be ignored, inflight requests = {(7, true), (11, true), (10, true), (12, true), (13, true), (14, true)}
2020-09-23 08:51:28.109 - ERROR - opcua_client::message_queue - A response with request handle 0 doesn't belong to any request and will be ignored, inflight requests = {(7, true), (11, true), (10, true), (12, true), (13, true), (14, true), (15, true)}
2020-09-23 08:51:29.112 - ERROR - opcua_client::message_queue - A response with request handle 0 doesn't belong to any request and will be ignored, inflight requests = {(14, true), (10, true), (13, true), (16, true), (7, true), (11, true), (12, true), (15, true)}
2020-09-23 08:51:30.101 - ERROR - opcua_client::message_queue - A response with request handle 0 doesn't belong to any request and will be ignored, inflight requests = {(14, true), (10, true), (13, true), (16, true), (17, true), (7, true), (11, true), (12, true), (15, true)}

I'm connecting to a 3rd party OPC UA server (well known brand) and do also get the expected item updates. Anything I can or should do to mitigate or investigate this?

I have a bit of a hard time understanding what this means or what causes these messages... Thanks!

How to connect to a pre configured endpoint

Hello!

Not sure if I'm using this wrong but when I try to create a session from a client I cannot get the program to connect to a custom endpoint I configured. Instead, it only allows me to connect to an endpoint that the server responds with.

For example, if I create a session via the ClientBuilder API like so:

let builder = ClientBuilder::new()
    .endpoint(
       "lab_plc",
       ClientEndpoint {
           url: String::from("opc.tcp://192.168.0.1:4840"),
           security_policy: String::from(SecurityPolicy::None.to_str()),
           security_mode: String::from(MessageSecurityMode::None),
           user_token_id: String::from("ANONYMOUS")
        },
    )
    ...

let mut client = builder.client().unwrap();
let session = client.connect_and_activate(Some("lab_plc")).unwrap();

the connect_and_activate method will not use the "lab_plc" endpoint like I expected it to. Instead that method calls Client.get_server_endpoints() to build an internal list of endpoints that it gets from asking the OPCUA server what endpoints exist. If the server doesn't respond with the endpoint that I want (for example, instead of listing opc.tcp://192.168.0.1:4840 as an endpoint url, the server responds with a hostname like opc.tcp://automation:4840 that doesn't resolve correctly on the network) then there is no alternative way for me to override that hostname with my custom url.

My "fix" was to clone the types crate and edit the endpoint_description.rs file so that the decode method returned a hardcoded value in the struct:

        Ok(EndpointDescription {
            // endpoint_url,
            endpoint_url: UAString::from("opc.tcp://192.168.0.1:4840"),
            server,
            server_certificate,
            security_mode,
            security_policy_uri,
            user_identity_tokens,
            transport_profile_uri,
            security_level,
        })

Am I using this API wrong? Is there a better API to use where I can send it the endpoint url I want?

Thanks!

Comparison of OPC UA implementations?

Hello @locka99

Have you done a comparison of this implementation with the Open62541 implementation of OPC UA?

I was just curious to know what's good, what's bad... Are you using this implementation of OPC-UA in production somewhere? I'm looking at different implementations.

The OPC foundation has a compliance testing section (https://industrial.softing.com/fileadmin/Downloads/FA_OPC_UA_Teil6_SPS_2012_07_EN.pdf). I don't know right now what that's supposed to be but from it's name, it might seem that customers/industries might be interested in it?? Any idea?

Thanks

Security Policy not included in GetEndpointsResponse message

First of all, thanks for a great library.

I may be missing some steps, but I am trying to add additional security policies to server without much luck. I have the following.

.endpoints(
            [
                ("none", endpoint_path, SecurityPolicy::None, MessageSecurityMode::None, &user_token_ids),
                ("basic128rsa15_sign", endpoint_path, SecurityPolicy::Basic128Rsa15, MessageSecurityMode::Sign, &user_token_ids),
                ("basic128rsa15_sign_encrypt", endpoint_path, SecurityPolicy::Basic128Rsa15, MessageSecurityMode::SignAndEncrypt, &user_token_ids),
                ("basic256_sign", endpoint_path, SecurityPolicy::Basic256, MessageSecurityMode::Sign, &user_token_ids),
                ("basic256_sign_encrypt", endpoint_path, SecurityPolicy::Basic256, MessageSecurityMode::SignAndEncrypt, &user_token_ids),
                ("basic256sha256_sign", endpoint_path, SecurityPolicy::Basic256Sha256, MessageSecurityMode::Sign, &user_token_ids),
                ("basic256sha256_sign_encrypt", endpoint_path, SecurityPolicy::Basic256Sha256, MessageSecurityMode::SignAndEncrypt, &user_token_ids),
            ].iter().map(|v| {
                (v.0.to_string(), ServerEndpoint::from((v.1, v.2, v.3, &v.4[..])))
            }).collect())
        .config();

But, when I see the GetEndpointsResponse message, I am only seeing a single endpoint with policy

http://opcfoundation.org/UA/SecurityPolicy#None

Wondering whether additional steps are required on top of defining them as above.

License & Copyright Header is missing in most files

Hi @locka99,

first of all thanks for your amazing work on this OPC UA implementation in rust.

Unfortunately I'm not feeling very well when using it due to the missing License & Copyright headers in most files.

Would you mind adding one to all files?
If you don't have the time I can also take care of it via a pull request.

If I should do it I propose the following format:

// opcua
// <file name>
// SPDX-License-Identifier: MPL-2.0
// Copyright (C) 2020 Adam Lock

...

Memory leak on each disconnected session

Something in the server is hanging onto memory when sessions are disconnected. Need to identify what this is. Most likely it is a reference counting issue with one of the tokio tasks associated with managing a session.

Failing to connect to server

Hello!

I am trying to evaluate this library, I started by trying the python client, which connects without much hassle. I was just trying out the samples found here: https://github.com/FreeOpcUa/python-opcua/blob/master/examples/client-minimal.py

I cannot however get this client to connect to the same server I am trying against. I am using this code:

fn main() {
    let mut client = ClientBuilder::new()
        .application_name("TestClient")
        .application_uri("urn:TestClient")
        .create_sample_keypair(false)
        .trust_server_certs(true)
        .session_retry_limit(3)
        .client()
        .unwrap();

    println!("Clientbuilder");

    // Create an endpoint. The EndpointDescription can be made from a tuple consisting of
    // the endpoint url, security policy, message security mode and user token policy.
    let endpoint: EndpointDescription = (
        format!("{}:{}", OPC_IP, OPC_PORT).as_str(),
        "None",
        MessageSecurityMode::None,
        UserTokenPolicy::anonymous(),
    )
        .into();

    println!("Endpoint");

    // Create the session
    match client.connect_to_endpoint(endpoint, IdentityToken::Anonymous) {
        Ok(session) => {
            println!("Connected");

            // Create a subscription and monitored items
            if subscribe_to_values(session.clone()).is_ok() {
                let _ = Session::run(session);
            } else {
                println!("Error creating subscription");
            }
        }
        Err(e) => {
            println!("{:?}", e);
        }
    }

    println!("exit");
}

But I keep getting this error:

thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', /home/krille/.cargo/registry/src/github.com-1ecc6299db9ec823/opcua-client-0.7.0/src/message_queue.rs:49:27
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Can't generate address space for EUROMAP schemas

I noticed that the EUROMAP OPC specifications are not among the schemas provided in this repository, so I figured I'd try to add them to the list of files to be generated locally, and see what happens.


Unfortunately, I am encountering plenty of errors, and the generators seem to be struggling to properly parse the XML files.

example:

error: expected expression, found `=`
   --> server/src/address_space/generated/nodeset_82_13.rs:321:34
    |
321 |     let node_id = NodeId::new(0, =1;i=7051);
    |                                  ^ expected expression

Enabling trace, I see ReferenceError: ns is not defined

No clue if supporting these schemas is within the scope of the current tools provided in this repo, but currently it's sort of impractical to interop with EUROMAP via OPC with this crate as the EUROMAP-specific properties must be explicitly defined.

Hopefully I'm just doing something dumb/wrong.
Currently I'm just running node gen_address_space.js, followed by cargo build.


It might be helpful to either include some examples in the tools/schema directory, have something in the docs, or at some point, maybe even a build.rs-type solution, so we don't have to manually do anything aside from dropping the files into a schema folder or etc.


Anyway! Right now my goal is simply to consume the EUROMAP OPC-UA schemas utilizing this crate.
Any help would be much appreciated!


Also happy to provide any additional information that might help.

Client browse ViewDescription timestamp

With OPC Factory Server (Schneider's OFS) browsing a NodeId different from root folder returns a BadViewIdUnknown error.
Looking the session browse method source code I saw that ViewDescription::timestamp is set to DateTime::now() session.rs.
Changing that row to DateTime::epoch() will fix the issue and the browse request is executed correctly.

cannot build on windows with nightly-x86_64-pc-windows-msvc

it depends on signal-hook-registry,but this library only works on unix.

 Compiling signal-hook-registry v1.0.1
error[E0432]: unresolved imports `libc::sigaction`, `libc::siginfo_t`, `libc::sigset_t`, `libc::SIG_BLOCK`, `libc::SIG_SETMASK`
  --> C:\Users\bai\.cargo\registry\src\github.com-1ecc6299db9ec823\signal-hook-registry-1.0.1\src\lib.rs:58:27
   |
58 | use libc::{c_int, c_void, sigaction, siginfo_t, sigset_t, SIG_BLOCK, SIG_SETMASK};
   |                           ^^^^^^^^^  ^^^^^^^^^  ^^^^^^^^  ^^^^^^^^^  ^^^^^^^^^^^ no `SIG_SETMASK` in the root
   |                           |          |          |         |
   |                           |          |          |         no `SIG_BLOCK` in the root
   |                           |          |          no `sigset_t` in the root
   |                           |          no `siginfo_t` in the root
   |                           no `sigaction` in the root

error[E0432]: unresolved imports `libc::SIGKILL`, `libc::SIGSTOP`
  --> C:\Users\bai\.cargo\registry\src\github.com-1ecc6299db9ec823\signal-hook-registry-1.0.1\src\lib.rs:60:28
   |
60 | use libc::{SIGFPE, SIGILL, SIGKILL, SIGSEGV, SIGSTOP};
   |                            ^^^^^^^           ^^^^^^^ no `SIGSTOP` in the root
   |                            |
   |                            no `SIGKILL` in the root
   |                            help: a similar name exists in the module: `SIGILL`

CTT

Is there a plan to work with CTT? We are starting to put the library through CTT, and finding some issues. So, wondering what the ideal strategy is for fixing issues related to CTT.

Trying to connect to a Basic256, SignAndEncrypt endpoint.

Hello,

From samples/simple_client, I'm trying to connect to a Basic256,SignAndEncrypt endpoint with X509 token and client.connect_to_endpoint_id returns

ERROR - opcua_client::comms::tcp_transport - Expecting a chunk, got an error message BadSecurityChecksFailed

I think that certificate is OK because I use it with an other application.

First connection without security policy/mode seems to work because it retrieves endpoint.
Error arrives when it wants to connect to the endpoint and sends a secure channel request.
On wireshark, viewable value in frame seems to be OK and corresponds to a frame sent with an other application.

Do you have any idea what I could look at to try to find the problem ?
Thank you very much for this library.

"nonce must be non-zero" when trying to connect to OPC UA server from milo

When attempting to connect to an OPC UA server configured with ServerConfig::load from a milo client, I am unable to connect to the server, and receive this error message: "nonce must be non-zero".

According to this comment, I need to set the nonce whether security is enabled or not?
From what I've found in the samples, this can be done in the code, but I'm unsure how I can achieve this from a server configuration file.

Am I missing something with my configuration? Or is there something I need to do on the rust side?

Current server.conf
---
application_name: OPC UA Sample Server
application_uri: "urn:OPC UA Sample Server"
product_uri: ""
pki_dir: "./pki"
create_sample_keypair: true
trust_client_certs: false
discovery_server_url: "opc.tcp://localhost:4840/UADiscovery"
tcp_config:
  hello_timeout: 5
  host: 0.0.0.0
  port: 4855
limits:
  clients_can_modify_address_space: false
  max_subscriptions: 100
  max_monitored_items_per_sub: 1000
  max_array_length: 1000
  max_string_length: 65536
  max_byte_string_length: 65536
  min_sampling_interval: 0.1
  min_publishing_interval: 0.1
user_tokens:
  sample_password_user:
    user: sample
    pass: sample1
  sample_x509_user:
    user: sample_x509
    x509: "./users/sample-x509.der"
  unused_user:
    user: unused
    pass: unused1
discovery_urls:
  - "opc.tcp://127.0.0.1:4855/"
endpoints:
  basic128rsa15_sign:
    path: /
    security_policy: Basic128Rsa15
    security_mode: Sign
    security_level: 2
    password_security_policy: ~
    user_token_ids:
      - ANONYMOUS
      - sample_password_user
      - sample_x509_user
  basic128rsa15_sign_encrypt:
    path: /
    security_policy: Basic128Rsa15
    security_mode: SignAndEncrypt
    security_level: 2
    password_security_policy: ~
    user_token_ids:
      - ANONYMOUS
      - sample_password_user
      - sample_x509_user
  basic256_sign:
    path: /
    security_policy: Basic256
    security_mode: Sign
    security_level: 3
    password_security_policy: ~
    user_token_ids:
      - ANONYMOUS
      - sample_password_user
      - sample_x509_user
  basic256_sign_encrypt:
    path: /
    security_policy: Basic256
    security_mode: SignAndEncrypt
    security_level: 3
    password_security_policy: ~
    user_token_ids:
      - ANONYMOUS
      - sample_password_user
      - sample_x509_user
  basic256sha256_sign:
    path: /
    security_policy: Basic256Sha256
    security_mode: Sign
    security_level: 4
    password_security_policy: ~
    user_token_ids:
      - ANONYMOUS
      - sample_password_user
      - sample_x509_user
  basic256sha256_sign_encrypt:
    path: /
    security_policy: Basic256Sha256
    security_mode: SignAndEncrypt
    security_level: 4
    password_security_policy: ~
    user_token_ids:
      - ANONYMOUS
      - sample_password_user
      - sample_x509_user
  no_access:
    path: /noaccess
    security_policy: None
    security_mode: None
    security_level: 1
    password_security_policy: ~
    user_token_ids: []
  none:
    path: /
    security_policy: None
    security_mode: None
    security_level: 1
    password_security_policy: ~
    user_token_ids:
      - ANONYMOUS
      - sample_password_user
      - sample_x509_user

Thanks!

Revised session timeout is not taken into account

When creating a new session and requesting a session timeout, the server automatically adjusts this timeout and reports it back to the client. The opcua-client crate picks it up as the revised_session_timeout variable in CreateSessionResponse, but doesn't do anything with it.
It neither starts a keepalive thread to prevent sessions from timing out (as e.g. python-opcua is doing), nor it propagates this value down to the caller to let it prevent timeouts itself.

The workaround from PR #26 easily solves this problem for us for the moment.
However, in the long term, opcua should be fixed to handle this issue reliably.

error: failed to run custom build command for `ring v0.12.1`

Operating System: Windows 10 Pro

Rust toolchain:
nightly-x86_64-pc-windows-msvc (default)
rustc 1.30.0-nightly (63c75d375 2018-09-21)

I am trying to compile and run the opc ua client but I am getting the following error:

Compiling ring v0.12.1 error: failed to run custom build command forring v0.12.1process didn't exit successfully:C:\Users\micha\Documents\Rust\Libraries\opcua\target\debug\build\ring-d150b23a3701555a\build-script-build (exit code: 101) --- stderr thread '<unnamed>' panicked at 'execution failed', C:\Users\micha\.cargo\registry\src\github.com-1ecc6299db9ec823\ring-0.12.1\build.rs:636:9 thread '<unnamed>' panicked at 'execution failed', C:\Users\micha\.cargo\registry\src\github.com-1ecc6299db9ec823\ring-0.12.1\build.rs:636:9

Regarding this issue the problem should be solved with ring-0.13.

I would appreciate any help.

Link related crates in generated docs

Hi,

of absolutely minor importance, but a nice to have.

What I mean by this is the linking between related crates (opcua-server, -types, -client, ...)

BR,
~lwk

User/Password authentification fails on SecurityPolicy#None

Hello,

I use your library, which is very good and reliable, as a client to connect to a opcua server.
Server endpoint is described as :

EndpointDescription
    EndpointUrl: opc.tcp://a.b.c.d:12345
    Server: ApplicationDescription
[...]
    MessageSecurityMode: None (0x00000001)
    SecurityPolicyUri: http://opcfoundation.org/UA/SecurityPolicy#None
    UserIdentityTokens: Array of UserTokenPolicy
        ArraySize: 1
        [0]: UserTokenPolicy
            PolicyId: UserName
            UserTokenType: UserName (0x00000001)
            IssuedTokenType: [OpcUa Null String]
            IssuerEndpointUrl: [OpcUa Null String]
            SecurityPolicyUri: http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15
    TransportProfileUri: http://opcfoundation.org/UA-Profile/Transport/uatcp-uasc-uabinary
    SecurityLevel: 16

So there is no signature or encryption for message but password token has to be sent in RsaPkcs because of token Basic128Rsa15. But authentification is rejected by the server with a BadIdentityTokenInvalid error at ActivateSessionRequest state.

Token policy

My first problem is I have to force the use of Basic128Rsa15 policy in make_user_name_identity_token function because the library seems to take the endpoint policy (None) instead of token policy resulting a clear password.

Is this a configuration problem on my side ?

Token content

My second problem is that authentication fails with the same error. In this case, the content of the token is incomplete before it is encrypted in legacy_password_encrypt. I noticed that the server_nonce is empty. In fact it is not set in set_remote_nonce_from_byte_string function because of endpoint None policy.

Is it a problem of endpoint/token mode of the server which is not possible in the opcua specifications or it is not managed by the library.

Thank you for your work

Argument encoding on methods is confusing

The generated node set code contanis code to encode InputArguments / OutputArguments data using ns=0;i=297 as directed. But that node id is Argument_Encoding_DefaultXml implying the encoding should be Xml when only binary encoding is supported by the implementation. i.e. the encoding is analogous to Argument_Encoding_DefaultBinary (ns=0;i=298).

The code might have to have a kludge Argument to encode as Xml for the benefit of the clients trying to read those values.

tokio task is not stopped on session disconnect

In our setup, we are experiencing unpredictable behaviour of the OPC server where sessions are dropped silently on server side, forcing us to close and reconnect as soon as a read out fails.
Our implementation involves dropping the current session and starting from scratch.
We also tried session.disconnect() and session.close_secure_channel()

If this happens a couple of times, we are running in to "Too many open files", because the connection_task run by Tokio is not terminated after a session is dropped.

Edit:
The problem remains if you call session.disconnect()

Compile to WebAssembly / wasm

Hey,

thank you for creating this library. 💯

I'm trying to use it inside the browser via WebAssembly. The basic idea is to have a WebSocket connection to a server, use the binary protocol for communication and handle serialization/deserialization of messages inside wasm. Within my JavaScript application I can use the wrapper which was automatically created by wasm-pack.

Here is a short demo with the code from one of the tests. It simply converts some bytes into a UAString.

extern crate wasm_bindgen;
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn convert(v: &[u8]) -> String {
    let mut stream = Cursor::new(v);
    let decoding_limits = DecodingLimits::default();
    return UAString::decode(&mut stream, &decoding_limits).unwrap().value.unwrap();
}

Compile this code (for Node.js so we don't have to set up a server and start the browser).

wasm-pack build --target nodejs

Call our convert function.

const opcua = require('./pkg/opcua_types')

console.log(opcua.convert([0x06, 0x00, 0x00, 0x00, 0xE6, 0xB0, 0xB4, 0x42, 0x6F, 0x79]))

This returns 水Boy as expected. That's already great 👍

Now I'm trying to use LocalizedText and I've got several problems. I'm pretty good at JS but not so good with Rust. Maybe you've got an idea.

I tried to add #[wasm_bindgen] to LocalizedText. This gives the error message

the trait string::wasm_bindgen::convert::IntoWasmAbi is not implemented for string::UAString

So I also added #[wasm_bindgen] to UAString. This gives the error message

the trait std::marker::Copy is not implemented for string::UAString

So I tried to add Copy to UAString.

#[derive(Eq, PartialEq, Debug, Clone, Hash, Serialize, Deserialize, Copy)]
pub struct UAString {
    pub value: Option<String>,
}

And finally the compiles tells me that

this field does not implement Copy

So I tried to find a solution for this and found What Is Ownership?. To me it looks like strings do not have a copy method and now I'm stuck.

Any hint you could give me? Thank you very much!

License?

The licensing is unclear (clear, but missing the LICENSE.md file) on this repo. Might be a good idea to put a LICENSE.md file at the root of the repo.


BTW, I don't know how I missed this, but thanks for the rust OPC UA implementation. Is there a Gitter or Slack channel where you guys discuss future stuff or dev topics?

Feature Request: example of writing to a variable

Hi! First of all, thanks for writing this library, I'm excited to see it work.

I'm having some trouble writing to variables in a server running on a PLC. I know it's on the client side because I can write to them just fine via UaExpert... but for the life of me I can't figure out how to write to it via this library. My code is

let mut client = ClientBuilder::new()
    .application_name("Vicarious RSI Driver")
    .application_uri("urn:vicarious/kuka/driver")
    .trust_server_certs(true)
    .session_retry_limit(3)
    .endpoint("only_endpoint", ClientEndpoint {
        url: String::from(url),
        security_policy: SecurityPolicy::None.to_string(),
        security_mode: MessageSecurityMode::None.to_string(),
        user_token_id: ANONYMOUS_USER_TOKEN_ID.to_string(),
    })
    .default_endpoint("only_endpoint")
    .client().ok_or("Couldn't build an OPC client???")?;
let session = client.connect_to_endpoint_id(Some("only_endpoint")).map_err(|e| e.to_string())?;

if let Ok(mut session) = session.write() { // locks the rw lock
    let request = NodeId::new(6, "::AsGlobalPV:IO.VicStack1.Dinp.blnEnableRq").into();
    println!("{:?}\n", session.read(&[request]));

    let request = WriteValue {
        node_id: NodeId::new(6, "::AsGlobalPV:IO.VicStack1.Dinp.blnEnableRq"),
        attribute_id: 13,
        index_range: UAString { value: None },
        value: DataValue::new(false),
    };
    println!("{:?}\n", session.write(&[request]));
}
let _ = Session::run(session);
println!("done");

and it yields:

Ok(Some([DataValue { value: Some(Boolean(true)), status: None, source_timestamp: None, source_picoseconds: None, server_timestamp: Some(DateTime { date_time: 2000-03-06T05:03:59.298Z }), server_picoseconds: None }]))

Ok(Some([IS_ERROR | GoodClamped | BadUnexpectedError | BadInternalError | BadOutOfMemory | BadTooManyOperations | BadDataTypeIdUnknown | BadCertificateInvalid | BadSecurityChecksFailed | BadIdentityTokenInvalid | BadIdentityTokenRejected | BadSecureChannelIdInvalid | BadInvalidTimestamp | BadNoCommunication | BadWaitingForInitialData | BadNodeIdInvalid | BadNotImplemented | BadMonitoringModeInvalid | BadMonitoredItemIdInvalid | BadMonitoredItemFilterInvalid | BadServerNameMissing | BadDiscoveryUrlMissing | BadSempahoreFileMissing | BadRequestTypeInvalid | BadBrowseNameInvalid | BadBrowseNameDuplicated | BadNodeAttributesInvalid | BadTypeDefinitionInvalid | BadMaxAgeInvalid | BadHistoryOperationInvalid | BadHistoryOperationUnsupported | BadWriteNotSupported]))

It seems unlikely that I'm really earning every possible error, and more likely that I'm botching something simple, but I'm not getting traction figuring out what. Could I persuade you to throw together a working example of a client updating a value on a server?

client connect_and_activate panics without server

Hello, firstly thanks for the tremendous work. I really appreciate it!

On the other hand I am really new with the OPC UA protocol as well as Rust itself. If the issue/question is a matter of my limited experience, sorry for that and feel free to close it any time.

But to the issue:
The sample client panics if no server is running (I would assume it should return an Err instead...)

Stacktrace:

"opc.tcp://127.0.0.1:4855/"
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', src/libcore/option.rs:345:21
stack backtrace:
   0: std::sys::unix::backtrace::tracing::imp::unwind_backtrace
             at src/libstd/sys/unix/backtrace/tracing/gcc_s.rs:39
   1: std::sys_common::backtrace::_print
             at src/libstd/sys_common/backtrace.rs:70
   2: std::panicking::default_hook::{{closure}}
             at src/libstd/sys_common/backtrace.rs:58
             at src/libstd/panicking.rs:200
   3: std::panicking::default_hook
             at src/libstd/panicking.rs:215
   4: std::panicking::rust_panic_with_hook
             at src/libstd/panicking.rs:478
   5: std::panicking::continue_panic_fmt
             at src/libstd/panicking.rs:385
   6: rust_begin_unwind
             at src/libstd/panicking.rs:312
   7: core::panicking::panic_fmt
             at src/libcore/panicking.rs:85
   8: core::panicking::panic
             at src/libcore/panicking.rs:49
   9: <core::option::Option<T>>::unwrap
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858/src/libcore/macros.rs:10
  10: opcua_client::message_queue::MessageQueue::add_request
             at /home/sergej/.cargo/registry/src/github.com-1ecc6299db9ec823/opcua-client-0.5.0/src/message_queue.rs:43
  11: opcua_client::session_state::SessionState::add_request
             at /home/sergej/.cargo/registry/src/github.com-1ecc6299db9ec823/opcua-client-0.5.0/src/session_state.rs:276
  12: opcua_client::session_state::SessionState::async_send_request
             at /home/sergej/.cargo/registry/src/github.com-1ecc6299db9ec823/opcua-client-0.5.0/src/session_state.rs:229
  13: opcua_client::session_state::SessionState::send_request
             at /home/sergej/.cargo/registry/src/github.com-1ecc6299db9ec823/opcua-client-0.5.0/src/session_state.rs:208
  14: opcua_client::session_state::SessionState::issue_or_renew_secure_channel
             at /home/sergej/.cargo/registry/src/github.com-1ecc6299db9ec823/opcua-client-0.5.0/src/session_state.rs:317
  15: opcua_client::session::Session::open_secure_channel
             at /home/sergej/.cargo/registry/src/github.com-1ecc6299db9ec823/opcua-client-0.5.0/src/session.rs:289
  16: opcua_client::session::Session::connect
             at /home/sergej/.cargo/registry/src/github.com-1ecc6299db9ec823/opcua-client-0.5.0/src/session.rs:260
  17: opcua_client::client::Client::get_server_endpoints_from_url
             at /home/sergej/.cargo/registry/src/github.com-1ecc6299db9ec823/opcua-client-0.5.0/src/client.rs:290
  18: opcua_client::client::Client::get_server_endpoints
             at /home/sergej/.cargo/registry/src/github.com-1ecc6299db9ec823/opcua-client-0.5.0/src/client.rs:256
  19: opcua_client::client::Client::connect_and_activate
             at /home/sergej/.cargo/registry/src/github.com-1ecc6299db9ec823/opcua-client-0.5.0/src/client.rs:131
  20: opcua_reader::run
             at src/lib.rs:35
  21: opcua_reader::main
             at src/main.rs:18
  22: std::rt::lang_start::{{closure}}
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858/src/libstd/rt.rs:64
  23: std::panicking::try::do_call
             at src/libstd/rt.rs:49
             at src/libstd/panicking.rs:297
  24: __rust_maybe_catch_panic
             at src/libpanic_unwind/lib.rs:92
  25: std::rt::lang_start_internal
             at src/libstd/panicking.rs:276
             at src/libstd/panic.rs:388
             at src/libstd/rt.rs:48
  26: std::rt::lang_start
             at /rustc/2aa4c46cfdd726e97360c2734835aa3515e8c858/src/libstd/rt.rs:64
  27: main
  28: __libc_start_main
  29: _start

Timeout when connecting to endpoint

Hi,

I've been successfully using your library on a past project, but on the current one I've been encountering some strange behaviour during connection:
the software manages to establish a connection to the server and list the available endpoints, but then fails to connect to the endpoint on a timeout.

There seems to be no response from the server past the endpoint listing. Unfortunately I do not have access to server logs, but its operator told me he could not see our connection attempt.

Do you have any clue on what might cause this issue? What information could I ask my client to help debugging?

Any help on this issue would be much appreciated.

The server uses a certificate authentication and the problem happens when I call the client.connect_to_endpoint_id function.

Here is my (redacted) configuration and the application logs

ClientConfig {
    application_name: "XXX",
    application_uri: "xxx",
    create_sample_keypair: false,
    trust_server_certs: true,
    product_uri: "",
    pki_dir: "/tmp/.tmpzeMRNC",
    preferred_locales: [],
    default_endpoint: "test",
    user_tokens: {
        "Foobar": ClientUserToken {
            user: "",
            password: None,
            cert_path: Some(
                "/tmp/.tmpzeMRNC/own/cert.der",
            ),
            private_key_path: Some(
                "/tmp/.tmpzeMRNC/private/private.pem",
            ),
        },
    },
    endpoints: {
        "test": ClientEndpoint {
            url: "opc.tcp://10.1.1.1:1234/DataAccessServer",
            security_policy: "Basic256",
            security_mode: "SignAndEncrypt",
            user_token_id: "Foobar",
        },
    },
    session_retry_limit: 10,
    session_retry_interval: 10000,
    session_timeout: 0,
}
13:40:07.18 [main] [opcua/client/src/session.rs:opcua_client::session] [INFO] Connect
13:40:07.18 [main] [opcua/client/src/session.rs:opcua_client::session] [INFO] Security policy = None
13:40:07.18 [main] [opcua/client/src/session.rs:opcua_client::session] [INFO] Security mode = None
13:40:07.38 [main] [opcua/client/src/session_state.rs:opcua_client::session_state] [INFO] Making secure channel request
13:40:07.38 [main] [opcua/client/src/session_state.rs:opcua_client::session_state] [INFO] security_mode = None
13:40:07.38 [main] [opcua/client/src/session_state.rs:opcua_client::session_state] [INFO] security_policy = None
13:40:07.53 [main] [opcua/client/src/session.rs:opcua_client::session] [INFO] Connect was successful
13:40:08.18 [tokio-runtime-worker-0] [opcua/client/src/comms/tcp_transport.rs:opcua_client::comms::tcp_transport] [INFO] WriteState has dropped
13:40:08.26 [tokio-runtime-worker-0] [opcua/client/src/comms/tcp_transport.rs:opcua_client::comms::tcp_transport] [INFO] ReadState has dropped
13:40:08.27 [tokio-runtime-worker-0] [opcua/client/src/comms/tcp_transport.rs:opcua_client::comms::tcp_transport] [INFO] Timer for finished is finished
13:40:08.28 [main] [opcua/client/src/session.rs:opcua_client::session] [INFO] Session has dropped
13:40:08.28 [main] [opcua/client/src/comms/tcp_transport.rs:opcua_client::comms::tcp_transport] [INFO] TcpTransport has dropped
13:40:08.28 [main] [opcua/client/src/client.rs:opcua_client::client] [INFO] Server has these endpoints:
13:40:08.28 [main] [opcua/client/src/client.rs:opcua_client::client] [INFO]   opc.tcp://10.1.1.1:1234/DataAccessServer - Basic256 / SignAndEncrypt
13:40:08.28 [tokio-runtime-worker-0] [opcua/client/src/subscription_timer.rs:opcua_client::subscription_timer] [INFO] Timer receiver has terminated
13:40:08.28 [tokio-runtime-worker-0] [opcua/client/src/session_state.rs:opcua_client::session_state] [INFO] SessionState has dropped
13:40:08.28 [main] [opcua/client/src/client.rs:opcua_client::client] [INFO] Creating a session for endpoint opc.tcp://10.1.1.1:1234/DataAccessServer, Basic256 / SignAndEncrypt
13:40:08.28 [main] [opcua/client/src/session.rs:opcua_client::session] [INFO] Connect
13:40:08.28 [main] [opcua/client/src/session.rs:opcua_client::session] [INFO] Security policy = Basic256
13:40:08.28 [main] [opcua/client/src/session.rs:opcua_client::session] [INFO] Security mode = SignAndEncrypt
13:40:08.48 [main] [opcua/client/src/session_state.rs:opcua_client::session_state] [INFO] Making secure channel request
13:40:08.48 [main] [opcua/client/src/session_state.rs:opcua_client::session_state] [INFO] security_mode = SignAndEncrypt
13:40:08.48 [main] [opcua/client/src/session_state.rs:opcua_client::session_state] [INFO] security_policy = Basic256

13:40:18.51 [main] [opcua/client/src/session_state.rs:opcua_client::session_state] [INFO] Timeout waiting for response from server
13:40:18.51 [main] [opcua/client/src/message_queue.rs:opcua_client::message_queue] [INFO] Request 1 has timed out and any response will be ignored
13:40:18.51 [main] [opcua/client/src/session.rs:opcua_client::session] [WARN] session:2 Connect was unsuccessful, error = BadTimeout, retries = 1
13:40:18.51 [main] [opcua/client/src/session_retry.rs:opcua_client::session_retry] [INFO] Retry retriggered by policy
13:40:18.51 [main] [opcua/client/src/session.rs:opcua_client::session] [INFO] Retrying to connect to server...
13:40:18.51 [main] [opcua/client/src/session.rs:opcua_client::session] [INFO] Connect
13:40:18.51 [main] [opcua/client/src/session.rs:opcua_client::session] [INFO] Security policy = Basic256
13:40:18.51 [main] [opcua/client/src/session.rs:opcua_client::session] [INFO] Security mode = SignAndEncrypt
thread 'main' panicked at 'Should not try to connect when already connected', opcua/client/src/comms/tcp_transport.rs:180:13
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
13:40:18.51 [main] [opcua/client/src/session.rs:opcua_client::session] [INFO] Session has dropped
thread 'tokio-runtime-worker-1' panicked at 'called `Option::unwrap()` on a `None` value', /rustc/5e1a799842ba6ed4a57e91f7ab9435947482f7d8/src/libcore/macros/mod.rs:15:40
13:40:18.51 [tokio-runtime-worker-1] [opcua/client/src/comms/tcp_transport.rs:opcua_client::comms::tcp_transport] [INFO] WriteState has dropped

gfx-client is not working

gfx-client is rendering values at the wrong screen offset and doesn't work on some platforms, particularly linux+wayland

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.