proto_lab/ether_simulator.rs
1use std::sync::{Arc, Mutex};
2
3use crate::{device::IODriverSimulator, WirelessModemFake};
4
5pub struct EtherSimulator {
6 name: String,
7 devices: Arc<Mutex<Vec<WirelessModemFake>>>,
8}
9
10impl EtherSimulator {
11 pub fn new(name: &str) -> Self {
12 Self {
13 name: String::from(name),
14 devices: Arc::new(Mutex::new(vec![])),
15 }
16 }
17
18 /// Gets the name of the ether
19 /// ```
20 /// use network_simulator::EtherSimulator;
21 /// let mut ether = EtherSimulator::new("my_ether");
22 /// assert_eq!(ether.get_name(), "my_ether");
23 /// ```
24 pub fn get_name(&self) -> &str {
25 &self.name
26 }
27
28 /// Registers a new device (driver / modem)
29 /// ```
30 /// use network_simulator::EtherSimulator;
31 /// use network_simulator::WirelessModemFake;
32 /// use network_simulator::IODriverSimulator;
33 ///
34 /// let mut ether = EtherSimulator::new("my_ether");
35 /// ether.register_driver(WirelessModemFake::new("my_modem"));
36 /// assert_eq!(ether.get_driver("my_modem").unwrap().get_name(), "my_modem");
37 /// ```
38 pub fn register_driver(&mut self, driver: WirelessModemFake) {
39 let mut devices = self.devices.lock().expect("Fail to get lock on devices");
40 devices.push(WirelessModemFake::clone(&driver));
41 }
42
43 /// Unregisters a device
44 /// ```
45 /// use network_simulator::EtherSimulator;
46 /// use network_simulator::WirelessModemFake;
47 /// use network_simulator::IODriverSimulator;
48 ///
49 /// let mut ether = EtherSimulator::new("my_ether");
50 /// ether.register_driver(WirelessModemFake::new("my_modem"));
51 /// ether.unregister_driver("my_modem");
52 /// assert!(ether.get_driver("my_modem").is_none());
53 /// ```
54 pub fn unregister_driver(&mut self, name: &str) {
55 let mut devices = self.devices.lock().expect("Fail to get lock on devices");
56
57 loop {
58 let mut index_to_remove: Option<_> = None;
59
60 for (i, device) in devices.iter_mut().enumerate() {
61 if device.get_name() == name {
62 index_to_remove.replace(i);
63 }
64 }
65
66 match index_to_remove {
67 Some(i) => devices.remove(i),
68 None => break,
69 };
70 }
71 }
72
73 /// Gets a registered device
74 /// ```
75 /// use network_simulator::EtherSimulator;
76 /// use network_simulator::WirelessModemFake;
77 /// use network_simulator::IODriverSimulator;
78 ///
79 /// let mut ether = EtherSimulator::new("my_ether");
80 /// assert!(ether.get_driver("my_modem").is_none());
81 /// ether.register_driver(WirelessModemFake::new("my_modem"));
82 /// assert_eq!(ether.get_driver("my_modem").unwrap().get_name(), "my_modem");
83 /// ```
84 pub fn get_driver(&self, name: &str) -> Option<WirelessModemFake> {
85 let devices = self.devices.lock().expect("Fail to get lock on devices");
86
87 for device in devices.iter() {
88 if device.get_name() == name {
89 return Some(WirelessModemFake::clone(&device));
90 }
91 }
92 None
93 }
94
95 /// Gets the broadcasted byte from latest broadasting device.
96 /// That is the place where the data collision is possible.
97 fn get_current_byte(&self) -> Option<u8> {
98 let mut result: Option<u8> = None;
99 let devices = self.devices.lock().expect("Fail to get lock on devices");
100
101 for device in devices.iter() {
102 if let Some(byte) = device.get_from_device_network_side() {
103 result = Some(byte);
104 }
105 }
106
107 result
108 }
109
110 /// Prepares all the registered devices for starting of simulation during tick.
111 pub fn start_tick(&self) {
112 let devices = self.devices.lock().expect("Fail to get lock on devices");
113 for device in devices.iter() {
114 device.start_tick();
115 }
116 }
117
118 /// Prepares all the registered devices for ending of simulation during tick.
119 pub fn end_tick(&self) {
120 let devices = self.devices.lock().expect("Fail to get lock on devices");
121 for device in devices.iter() {
122 device.end_tick();
123 }
124 }
125
126 /// This operation shall be called only during tick is active.
127 pub fn simulate(&self) {
128 let current_byte = self.get_current_byte();
129
130 let devices = self.devices.lock().expect("Fail to get lock on devices");
131
132 if let Some(current_byte) = current_byte {
133 for device in devices.iter() {
134 device.put_to_device_network_side(current_byte);
135 }
136 }
137 }
138
139 /// Clones itself.
140 /// Also makes all internal data shared to be able to use from multiple threads.
141 /// ```
142 /// use network_simulator::EtherSimulator;
143 /// use network_simulator::WirelessModemFake;
144 /// use network_simulator::IODriverSimulator;
145 ///
146 /// let mut ether = EtherSimulator::new("my_ether");
147 /// let ether_clone = ether.clone();
148 ///
149 /// assert_eq!(ether.get_name(), ether_clone.get_name());
150 pub fn clone(&self) -> EtherSimulator {
151 EtherSimulator {
152 name: String::from(&self.name),
153 devices: Arc::clone(&self.devices),
154 }
155 }
156}