gwr_models/
ethernet_link.rs1use std::rc::Rc;
14
15use async_trait::async_trait;
16use gwr_components::delay::Delay;
17use gwr_components::flow_controls::limiter::Limiter;
18use gwr_components::{connect_port, rc_limiter};
19use gwr_engine::engine::Engine;
20use gwr_engine::port::PortStateResult;
21use gwr_engine::time::clock::Clock;
22use gwr_engine::traits::SimObject;
23use gwr_engine::types::{SimError, SimResult};
24use gwr_model_builder::{EntityDisplay, EntityGet, Runnable};
25use gwr_track::build_aka;
26use gwr_track::entity::Entity;
27use gwr_track::tracker::aka::Aka;
28
29pub const DELAY_TICKS: usize = 500;
31pub const BITS_PER_TICK: usize = 100;
32
33#[derive(EntityGet, EntityDisplay, Runnable)]
34pub struct EthernetLink<T>
35where
36 T: SimObject,
37{
38 entity: Rc<Entity>,
39 limiter_a: Rc<Limiter<T>>,
40 delay_a: Rc<Delay<T>>,
41 limiter_b: Rc<Limiter<T>>,
42 delay_b: Rc<Delay<T>>,
43}
44
45impl<T> EthernetLink<T>
46where
47 T: SimObject,
48{
49 pub fn new_and_register_with_renames(
50 engine: &Engine,
51 clock: &Clock,
52 parent: &Rc<Entity>,
53 name: &str,
54 aka: Option<&Aka>,
55 ) -> Result<Rc<Self>, SimError> {
56 let entity = Rc::new(Entity::new(parent, name));
57 let limiter = rc_limiter!(clock, BITS_PER_TICK);
58 let limiter_a_aka = build_aka!(aka, &entity, &[("rx_a", "rx")]);
59 let limiter_a = Limiter::new_and_register_with_renames(
60 engine,
61 clock,
62 &entity,
63 "limit_a",
64 Some(&limiter_a_aka),
65 limiter.clone(),
66 );
67 let delay_a_aka = build_aka!(aka, &entity, &[("tx_a", "tx")]);
68 let delay_a = Delay::new_and_register_with_renames(
69 engine,
70 clock,
71 &entity,
72 "a",
73 Some(&delay_a_aka),
74 DELAY_TICKS,
75 );
76 connect_port!(limiter_a, tx => delay_a, rx)
77 .expect("Internal ports should connect without error");
78
79 let limiter_b_aka = build_aka!(aka, &entity, &[("rx_b", "rx")]);
80 let limiter_b: Rc<Limiter<_>> = Limiter::new_and_register_with_renames(
81 engine,
82 clock,
83 &entity,
84 "limit_b",
85 Some(&limiter_b_aka),
86 limiter.clone(),
87 );
88 let delay_b_aka = build_aka!(aka, &entity, &[("tx_b", "tx")]);
89 let delay_b = Delay::new_and_register_with_renames(
90 engine,
91 clock,
92 &entity,
93 "b",
94 Some(&delay_b_aka),
95 DELAY_TICKS,
96 );
97 connect_port!(limiter_b, tx => delay_b, rx)
98 .expect("Internal ports should connect without error");
99
100 let rc_self = Rc::new(Self {
101 entity: entity.clone(),
102 limiter_a,
103 delay_a,
104 limiter_b,
105 delay_b,
106 });
107 engine.register(rc_self.clone());
108 Ok(rc_self)
109 }
110
111 pub fn new_and_register(
112 engine: &Engine,
113 clock: &Clock,
114 parent: &Rc<Entity>,
115 name: &str,
116 ) -> Result<Rc<Self>, SimError> {
117 Self::new_and_register_with_renames(engine, clock, parent, name, None)
118 }
119
120 pub fn set_delay(&self, delay: usize) -> SimResult {
123 self.delay_a.set_delay(delay)?;
124 self.delay_b.set_delay(delay)
125 }
126
127 pub fn connect_port_tx_a(&self, port_state: PortStateResult<T>) -> SimResult {
128 self.delay_a.connect_port_tx(port_state)
129 }
130
131 pub fn connect_port_tx_b(&self, port_state: PortStateResult<T>) -> SimResult {
132 self.delay_b.connect_port_tx(port_state)
133 }
134
135 pub fn port_rx_a(&self) -> PortStateResult<T> {
136 self.limiter_a.port_rx()
137 }
138
139 pub fn port_rx_b(&self) -> PortStateResult<T> {
140 self.limiter_b.port_rx()
141 }
142}