Serial
Use the Outstation::CreateSerialSession2 method in the bindings, or spawn_outstation_serial_2 in Rust, to create an outstation bound to a serial port. In addition to the common components, this method requires
the following serial port parameters:
- Path of the serial device (e.g.,
COM3on Windows or/dev/ttyS3on Linux) SerialSettingsstruct:- Baud rate
- Data bits
- Stop bits
- Parity
- Flow control
- How long to wait before retrying the serial port if it cannot be opened or fails because it is removed from the OS: a fixed delay in the bindings, a
RetryStrategyin Rust.
The method returns immediately and opens the port in the background, retrying as needed. The returned Outstation class behaves identically to other transport types.
The LinkErrorMode is internally set to Discard for serial communication channels since serial ports do not provide data integrity.
- Rust
- C
- C++
- Java
- C#
// Setup serial settings with values from Clap
let settings = SerialSettings {
baud_rate,
data_bits: data_bits.into(),
stop_bits: stop_bits.into(),
parity: parity.into(),
flow_control: flow_control.into(),
};
let outstation = spawn_outstation_serial_2(
port,
settings,
get_outstation_config_from_cli(cli),
RetryStrategy::new(Duration::from_secs(1), Duration::from_secs(60)),
// customizable trait that controls outstation behavior
Box::new(ExampleOutstationApplication::new()),
// customizable trait to receive events about what the outstation is doing
Box::new(ExampleOutstationInformation),
// customizable trait to process control requests from the master
Box::new(ExampleControlHandler),
LogListener::create("port"),
);
dnp3_outstation_t *outstation = NULL;
dnp3_param_error_t err = dnp3_outstation_create_serial_session_2(
runtime,
port,
dnp3_serial_settings_init(), // 9600 8N1, no flow control
1000, // retry opening the port every second
get_outstation_config(),
get_outstation_application(),
get_outstation_information(),
get_control_handler(),
get_port_state_listener(),
&outstation
);
// check error
auto outstation = Outstation::create_serial_session_2(
runtime,
port,
SerialSettings(), // 9600 8N1, no flow control
std::chrono::seconds(1), // retry opening the port every second
get_outstation_config(),
create_outstation_application(),
create_outstation_information(),
create_control_handler(),
port_state_listener([](PortState state) { std::cout << "port state: " << to_string(state) << std::endl; })
);
Outstation outstation = Outstation.createSerialSession2(
runtime,
port,
new SerialSettings(), // 9600 baud, 8 data bits, 1 stop bit, no parity, no flow control
Duration.ofSeconds(1), // try to open the port every second
getOutstationConfig(),
new ExampleOutstationApplication(),
new ExampleOutstationInformation(),
new ExampleControlHandler(),
state -> System.out.println("port state: " + state)
);
var outstation = Outstation.CreateSerialSession2(
runtime,
port,
new SerialSettings(), // 9600 8N1, no flow control
TimeSpan.FromSeconds(1), // try to open the port every second
GetOutstationConfig(),
// customizable interface that controls outstation behavior
new ExampleOutstationApplication(),
// customizable interface to receive events about what the outstation is doing
new ExampleOutstationInformation(),
// customizable interface to process control requests from the master
new ExampleControlHandler(),
new LogListener("port")
);
There is also an Outstation::CreateSerialSession method which opens the port on the calling thread and fails if it is not immediately available. The task spawned
by this thread will also shut down if the serial port is removed from the OS, e.g. if a USB to serial adapter is physically unplugged.
The fault-tolerant variant was added in the 1.1.0 release and is the preferred way of spawning a serial outstation. The non-fault tolerant version will be
removed in the next MAJOR release.