use crate::app::{Listener, MaybeAsync, RetryStrategy};
use tracing::Instrument;
use crate::link::reader::LinkModes;
use crate::outstation::task::OutstationTask;
use crate::outstation::{
ControlHandler, OutstationApplication, OutstationConfig, OutstationHandle,
OutstationInformation,
};
use crate::serial::task::SerialTask;
use crate::serial::{PortState, SerialSettings};
use crate::util::phys::{PhysAddr, PhysLayer};
use crate::util::session::{Enabled, Session};
pub fn spawn_outstation_serial(
path: &str,
settings: SerialSettings,
config: OutstationConfig,
application: Box<dyn OutstationApplication>,
information: Box<dyn OutstationInformation>,
control_handler: Box<dyn ControlHandler>,
) -> std::io::Result<OutstationHandle> {
let serial = crate::serial::open(path, settings)?;
let (mut task, handle) = OutstationTask::create(
Enabled::Yes,
LinkModes::serial(),
config,
PhysAddr::None,
application,
information,
control_handler,
);
let log_path = path.to_owned();
let future = async move {
let mut io = PhysLayer::Serial(serial);
let _ = task
.run(&mut io)
.instrument(tracing::info_span!("dnp3-outstation-serial", "port" = ?log_path))
.await;
};
tokio::spawn(future);
Ok(handle)
}
struct NullListener;
impl Listener<PortState> for NullListener {
fn update(&mut self, _: PortState) -> MaybeAsync<()> {
MaybeAsync::ready(())
}
}
#[allow(clippy::too_many_arguments)]
pub fn spawn_outstation_serial_2(
path: &str,
settings: SerialSettings,
config: OutstationConfig,
retry: RetryStrategy,
application: Box<dyn OutstationApplication>,
information: Box<dyn OutstationInformation>,
control_handler: Box<dyn ControlHandler>,
listener: Box<dyn Listener<PortState>>,
) -> OutstationHandle {
let (task, handle) = OutstationTask::create(
Enabled::Yes,
LinkModes::serial(),
config,
PhysAddr::None,
application,
information,
control_handler,
);
let mut serial = SerialTask::new(path, settings, Session::outstation(task), retry, listener);
let log_path = path.to_owned();
let future = async move {
serial
.run()
.instrument(tracing::info_span!("dnp3-outstation-serial", "port" = ?log_path))
.await;
};
tokio::spawn(future);
handle
}
pub fn spawn_outstation_serial_fault_tolerant(
path: &str,
settings: SerialSettings,
config: OutstationConfig,
retry: RetryStrategy,
application: Box<dyn OutstationApplication>,
information: Box<dyn OutstationInformation>,
control_handler: Box<dyn ControlHandler>,
) -> OutstationHandle {
spawn_outstation_serial_2(
path,
settings,
config,
retry,
application,
information,
control_handler,
Box::new(NullListener),
)
}