use crate::{
epath::{EPath, PortSegment, Segment},
MessageReply, MessageReplyInterface, Status,
};
use bytes::Bytes;
use rand::Rng;
use rseip_core::Either;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ConnectionType {
Null = 0,
Multicast = 1,
P2P = 2,
}
impl Default for ConnectionType {
fn default() -> Self {
Self::Null
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Priority {
Low = 0,
High = 1,
Scheduled = 2,
Urgent = 3,
}
impl Default for Priority {
fn default() -> Self {
Self::Scheduled
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Direction {
Client = 0,
Server = 1,
}
impl Default for Direction {
fn default() -> Self {
Self::Client
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TriggerType {
Cyclic = 0,
ChangeOfState = 1,
Application = 2,
}
impl Default for TriggerType {
fn default() -> Self {
Self::Cyclic
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TransportClass {
Class0 = 0,
Class1 = 1,
Class2 = 2,
Class3 = 3,
Class4 = 4,
Class5 = 5,
Class6 = 6,
}
impl Default for TransportClass {
fn default() -> Self {
Self::Class0
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum VariableLength {
Fixed = 0,
Variable = 1,
}
impl Default for VariableLength {
fn default() -> Self {
Self::Fixed
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ReadlTimeFormat {
Modeless = 0,
ZeroLength = 1,
Heartbeat = 3,
Header32Bit = 4,
}
impl Default for ReadlTimeFormat {
fn default() -> Self {
Self::Modeless
}
}
#[derive(Debug, Clone)]
pub struct ConnectionParameters {
pub redundant_owner: bool,
pub connection_type: ConnectionType,
pub variable_length: VariableLength,
pub priority: Priority,
pub connection_size: u16,
}
impl Default for ConnectionParameters {
fn default() -> Self {
Self {
redundant_owner: false,
connection_type: ConnectionType::P2P,
variable_length: VariableLength::Fixed,
priority: Priority::High,
connection_size: 504,
}
}
}
pub struct ForwardOpenReply(pub MessageReply<Either<ForwardOpenSuccess, ForwardRequestFail>>);
impl MessageReplyInterface for ForwardOpenReply {
type Value = Either<ForwardOpenSuccess, ForwardRequestFail>;
fn reply_service(&self) -> u8 {
self.0.reply_service
}
fn status(&self) -> &Status {
&self.0.status
}
fn value(&self) -> &Self::Value {
&self.0.data
}
fn into_value(self) -> Self::Value {
self.0.data
}
}
#[derive(Debug, Default)]
pub struct ForwardOpenSuccess {
pub o_t_connection_id: u32,
pub t_o_connection_id: u32,
pub connection_serial_number: u16,
pub originator_vendor_id: u16,
pub originator_serial_number: u32,
pub o_t_api: u32,
pub t_o_api: u32,
pub app_data: Bytes, }
#[derive(Debug, Default)]
pub struct ForwardRequestFail {
pub connection_serial_number: u16,
pub originator_vendor_id: u16,
pub originator_serial_number: u32,
pub remaining_path_size: Option<u8>,
}
#[derive(Debug, Default)]
pub struct ForwardCloseRequest<P> {
pub priority_time_ticks: u8,
pub timeout_ticks: u8,
pub connection_serial_number: u16,
pub originator_vendor_id: u16,
pub originator_serial_number: u32,
pub connection_path: P,
}
pub struct ForwardCloseReply(pub MessageReply<Either<ForwardCloseSuccess, ForwardRequestFail>>);
impl MessageReplyInterface for ForwardCloseReply {
type Value = Either<ForwardCloseSuccess, ForwardRequestFail>;
fn reply_service(&self) -> u8 {
self.0.reply_service
}
fn status(&self) -> &Status {
&self.0.status
}
fn value(&self) -> &Self::Value {
&self.0.data
}
fn into_value(self) -> Self::Value {
self.0.data
}
}
#[derive(Debug, Default)]
pub struct ForwardCloseSuccess {
pub connection_serial_number: u16,
pub originator_vendor_id: u16,
pub originator_serial_number: u32,
pub app_data: Bytes, }
#[derive(Debug, Clone)]
pub struct OpenOptions<P = EPath> {
pub o_t_connection_id: u32,
pub t_o_connection_id: u32,
pub priority_tick_time: u8,
pub timeout_ticks: u8,
pub connection_serial_number: u16,
pub vendor_id: u16,
pub originator_serial_number: u32,
pub o_t_rpi: u32,
pub t_o_rpi: u32,
pub timeout_multiplier: u8,
pub connection_path: P,
pub o_t_params: ConnectionParameters,
pub t_o_params: ConnectionParameters,
pub transport_direction: Direction,
pub transport_class: TransportClass,
pub transport_trigger: TriggerType,
pub large_open: bool,
}
impl<P> OpenOptions<P> {
#[inline]
pub fn o_t_connection_id(mut self, val: u32) -> Self {
self.o_t_connection_id = val;
self
}
#[inline]
pub fn t_o_connection_id(mut self, val: u32) -> Self {
self.t_o_connection_id = val;
self
}
#[inline]
pub fn priority_tick_time(mut self, val: u8) -> Self {
self.priority_tick_time = val & 0xF; self
}
#[inline]
pub fn timeout_ticks(mut self, val: u8) -> Self {
self.timeout_ticks = val;
self
}
#[inline]
pub fn connection_serial_number(mut self, val: u16) -> Self {
self.connection_serial_number = val;
self
}
#[inline]
pub fn originator_vendor_id(mut self, val: u16) -> Self {
self.vendor_id = val;
self
}
#[inline]
pub fn originator_serial_number(mut self, val: u32) -> Self {
self.originator_serial_number = val;
self
}
#[inline]
pub fn o_t_rpi(mut self, val: u32) -> Self {
self.o_t_rpi = val;
self
}
#[inline]
pub fn t_o_rpi(mut self, val: u32) -> Self {
self.t_o_rpi = val;
self
}
#[inline]
pub fn timeout_multiplier(mut self, val: u8) -> Self {
self.timeout_multiplier = val;
self
}
#[inline]
pub fn connection_size(mut self, val: u16) -> Self {
self.o_t_params.connection_size = val;
self.t_o_params.connection_size = val;
self
}
#[inline]
pub fn connection_path(mut self, path: P) -> Self {
self.connection_path = path;
self
}
#[inline]
pub fn o_t_priority(mut self, val: Priority) -> Self {
self.o_t_params.priority = val;
self
}
#[inline]
pub fn t_o_priority(mut self, val: Priority) -> Self {
self.t_o_params.priority = val;
self
}
#[inline]
pub fn o_t_variable_length(mut self, val: VariableLength) -> Self {
self.o_t_params.variable_length = val;
self
}
#[inline]
pub fn t_o_variable_length(mut self, val: VariableLength) -> Self {
self.t_o_params.variable_length = val;
self
}
#[inline]
pub fn t_o_connection_type(mut self, val: ConnectionType) -> Self {
self.t_o_params.connection_type = val;
self
}
#[inline]
pub fn o_t_connection_type(mut self, val: ConnectionType) -> Self {
self.o_t_params.connection_type = val;
self
}
#[inline]
pub fn o_t_redundant_owner(mut self, val: bool) -> Self {
self.o_t_params.redundant_owner = val;
self
}
#[inline]
pub fn t_o_redundant_owner(mut self, val: bool) -> Self {
self.t_o_params.redundant_owner = val;
self
}
#[inline]
pub fn transport_direction(mut self, val: Direction) -> Self {
self.transport_direction = val;
self
}
#[inline]
pub fn transport_class(mut self, val: TransportClass) -> Self {
self.transport_class = val;
self
}
#[inline]
pub fn transport_trigger(mut self, val: TriggerType) -> Self {
self.transport_trigger = val;
self
}
#[inline]
pub fn large_open(mut self, val: bool) -> Self {
self.large_open = val;
self
}
#[inline]
pub(crate) fn transport_class_trigger(&self) -> u8 {
let dir = self.transport_direction as u8;
let trigger = self.transport_trigger as u8;
let class = self.transport_class as u8;
(dir << 7) | (trigger << 4) | class
}
}
impl Default for OpenOptions<EPath> {
#[inline]
fn default() -> Self {
let connection_path = EPath::from(vec![
Segment::Port(PortSegment::default()),
Segment::Class(2),
Segment::Instance(1),
]);
let connection_serial_number: u16 = rand::thread_rng().gen_range(1..0xFFFF);
Self {
o_t_connection_id: 0,
t_o_connection_id: 0,
priority_tick_time: 0x03,
timeout_ticks: 0xfa,
connection_serial_number,
vendor_id: 0xFF,
originator_serial_number: 0xFFFFFFFF,
o_t_rpi: 0x4240,
t_o_rpi: 0x4240,
timeout_multiplier: 3,
connection_path,
o_t_params: Default::default(),
t_o_params: Default::default(),
transport_direction: Direction::Server,
transport_class: TransportClass::Class3,
transport_trigger: TriggerType::Application,
large_open: false,
}
}
}