gwr_models/
ethernet_frame.rs1use std::fmt::Display;
6use std::rc::Rc;
7
8use gwr_engine::traits::{Routable, SimObject, TotalBytes};
9use gwr_engine::types::AccessType;
10use gwr_track::entity::Entity;
11use gwr_track::id::Unique;
12use gwr_track::{Id, create_id, track_create_object};
13
14pub const PREAMBLE_BYTES: usize = 7;
15pub const SFD_BYTES: usize = 1;
16pub const DEST_MAC_BYTES: usize = 6;
17pub const SRC_MAC_BYTES: usize = 6;
18pub const FRAME_OVERHEAD_BYTES: usize = PREAMBLE_BYTES + SFD_BYTES + DEST_MAC_BYTES + SRC_MAC_BYTES;
19
20#[must_use]
21pub fn mac_to_u64(mac: &[u8; DEST_MAC_BYTES]) -> u64 {
22 ((mac[5] as u64) << (8 * 5))
23 | ((mac[4] as u64) << (8 * 4))
24 | ((mac[3] as u64) << (8 * 3))
25 | ((mac[2] as u64) << (8 * 2))
26 | ((mac[1] as u64) << 8)
27 | (mac[0] as u64)
28}
29
30#[must_use]
31pub fn u64_to_mac(value: u64) -> [u8; DEST_MAC_BYTES] {
32 let mut mac = [0_u8; DEST_MAC_BYTES];
33 mac[0] = (value & 0xff) as u8;
34 mac[1] = ((value >> 8) & 0xff) as u8;
35 mac[2] = ((value >> (8 * 2)) & 0xff) as u8;
36 mac[3] = ((value >> (8 * 3)) & 0xff) as u8;
37 mac[4] = ((value >> (8 * 4)) & 0xff) as u8;
38 mac[5] = ((value >> (8 * 5)) & 0xff) as u8;
39 mac
40}
41
42#[derive(Clone, Debug, PartialEq)]
43pub struct EthernetFrame {
44 id: Id,
45
46 dst_mac: [u8; DEST_MAC_BYTES],
48 src_mac: [u8; SRC_MAC_BYTES],
49
50 payload_size_bytes: usize,
52}
53
54impl EthernetFrame {
55 #[must_use]
56 pub fn new(created_by: &Rc<Entity>, payload_size_bytes: usize) -> Self {
57 let frame = Self {
58 id: create_id!(created_by),
59 dst_mac: [0; DEST_MAC_BYTES],
60 src_mac: [0; DEST_MAC_BYTES],
61 payload_size_bytes,
62 };
63 track_create_object!(
65 created_by;
66 frame.id,
67 frame.total_bytes(),
68 "bytes",
69 frame.access_type() as u8,
70 "EthernetFrame: {frame}"
71 );
72 frame
73 }
74
75 #[must_use]
76 pub fn set_dest(mut self, dst_mac: [u8; DEST_MAC_BYTES]) -> Self {
77 self.dst_mac = dst_mac;
78 self
79 }
80
81 #[must_use]
82 pub fn set_src(mut self, src_mac: [u8; SRC_MAC_BYTES]) -> Self {
83 self.src_mac = src_mac;
84 self
85 }
86
87 #[must_use]
88 pub fn get_dst(&self) -> u64 {
89 mac_to_u64(&self.dst_mac)
90 }
91
92 #[must_use]
93 pub fn get_src(&self) -> u64 {
94 mac_to_u64(&self.src_mac)
95 }
96}
97
98impl SimObject for EthernetFrame {}
99
100impl Display for EthernetFrame {
101 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
102 write!(
103 f,
104 "{:?} -> {:?} ({} bytes)",
105 self.src_mac, self.dst_mac, self.payload_size_bytes
106 )
107 }
108}
109
110impl TotalBytes for EthernetFrame {
111 fn total_bytes(&self) -> usize {
112 self.payload_size_bytes + PREAMBLE_BYTES + SFD_BYTES + DEST_MAC_BYTES + SRC_MAC_BYTES
113 }
114}
115
116impl Unique for EthernetFrame {
117 fn id(&self) -> Id {
118 self.id
119 }
120}
121
122impl Routable for EthernetFrame {
123 fn destination(&self) -> u64 {
124 self.get_dst()
125 }
126
127 fn access_type(&self) -> AccessType {
128 AccessType::Control
130 }
131}
132
133impl SimObject for Box<EthernetFrame> {}
135
136impl TotalBytes for Box<EthernetFrame> {
137 fn total_bytes(&self) -> usize {
138 self.as_ref().total_bytes()
139 }
140}
141
142impl Unique for Box<EthernetFrame> {
143 fn id(&self) -> gwr_track::Id {
144 self.as_ref().id()
145 }
146}
147
148impl Routable for Box<EthernetFrame> {
149 fn destination(&self) -> u64 {
150 self.as_ref().destination()
151 }
152 fn access_type(&self) -> AccessType {
153 self.as_ref().access_type()
154 }
155}