1use secgate::TwzError;
2use smoltcp::phy::{DeviceCapabilities, Medium, RxToken, TxToken};
3use twizzler::object::{MapFlags, Object, RawObject};
4use twizzler_abi::syscall::ThreadSyncSleep;
5use twizzler_io::packet::PacketObject;
6use twizzler_queue::{Queue, QueueBase};
7
8use crate::{
9 ClientMsg, ClientMsgKind, ClientRet, INVALID_PACKET, PacketNum, PacketSet, ServerMsg,
10 ServerMsgKind, ServerRet, client::NetClientOpenInfo, endpoint::Pair,
11};
12
13pub struct NetServer {
14 client_tx: Pair<ClientMsg, ServerRet>,
15 client_rx: Pair<ServerMsg, ClientRet>,
16 pending_client_tx: PacketSet,
17 pending_client_id: Option<u32>,
18}
19
20impl NetServer {
21 pub fn client_tx_packet_object(&self) -> &PacketObject {
22 self.client_tx.packet_object()
23 }
24
25 pub fn rx_waiter(&self) -> ThreadSyncSleep {
26 self.client_tx.rx_waiter()
27 }
28
29 pub fn completions_waiter(&self) -> ThreadSyncSleep {
30 self.client_rx.comp_waiters()
31 }
32
33 pub fn has_pending_msg_from_client(&self) -> bool {
34 self.client_tx.has_pending_msg()
35 || self
36 .pending_client_tx
37 .0
38 .iter()
39 .any(|p| *p != INVALID_PACKET)
40 }
41
42 pub fn open(info: &NetClientOpenInfo) -> Result<Self, TwzError> {
43 let tx_queue = Object::<QueueBase<ClientMsg, ServerRet>>::map(
44 info.tx_queue,
45 MapFlags::READ | MapFlags::WRITE,
46 )?;
47 let rx_queue = Object::<QueueBase<ServerMsg, ClientRet>>::map(
48 info.rx_queue,
49 MapFlags::READ | MapFlags::WRITE,
50 )?;
51 let tx = Pair::new(
52 PacketObject::from(Object::map(info.tx_buf, MapFlags::READ | MapFlags::WRITE)?),
53 Queue::from(tx_queue.handle().clone()),
54 );
55 let rx = Pair::new(
56 PacketObject::from(Object::map(info.rx_buf, MapFlags::READ | MapFlags::WRITE)?),
57 Queue::from(rx_queue.handle().clone()),
58 );
59 Ok(Self {
60 client_tx: tx,
61 client_rx: rx,
62 pending_client_id: None,
63 pending_client_tx: PacketSet::new(),
64 })
65 }
66}
67
68impl smoltcp::phy::Device for NetServer {
69 type RxToken<'a>
70 = NetServerRxToken<'a>
71 where
72 Self: 'a;
73
74 type TxToken<'a>
75 = NetServerTxToken<'a>
76 where
77 Self: 'a;
78
79 fn receive(
80 &mut self,
81 timestamp: smoltcp::time::Instant,
82 ) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> {
83 let idx = self
84 .pending_client_tx
85 .0
86 .iter()
87 .position(|x| *x != INVALID_PACKET);
88 if let Some(idx) = idx {
89 let next = self.pending_client_tx.0[idx];
90 self.pending_client_tx.0[idx] = INVALID_PACKET;
91 self.client_rx.check_completions();
92
93 return Some((
94 NetServerRxToken {
95 ns: self,
96 packet: next,
97 },
98 NetServerTxToken {
99 ns: self,
100 packet: self.client_rx.allocate_packet().unwrap(),
101 consumed: false,
102 },
103 ));
104 }
105
106 if let Some(pending_id) = self.pending_client_id.take() {
107 self.client_tx.complete(pending_id, ServerRet {});
108 }
109
110 let (id, msg) = self.client_tx.recv_msg()?;
111 self.pending_client_id = Some(id);
112 match msg.kind {
113 ClientMsgKind::Tx(packet_set) => {
114 self.pending_client_tx = packet_set;
115 }
116 }
117 self.receive(timestamp)
118 }
119
120 fn transmit(&mut self, _timestamp: smoltcp::time::Instant) -> Option<Self::TxToken<'_>> {
121 self.client_rx.check_completions();
122 let packet = self.client_rx.allocate_packet()?;
123 Some(NetServerTxToken {
124 ns: self,
125 packet,
126 consumed: false,
127 })
128 }
129
130 fn capabilities(&self) -> DeviceCapabilities {
131 let mut cap = DeviceCapabilities::default();
132 cap.medium = Medium::Ethernet;
133 cap.max_transmission_unit = 1514;
134 cap.max_burst_size = Some(1);
135 cap
136 }
137}
138
139pub struct NetServerTxToken<'a> {
140 ns: &'a NetServer,
141 pub packet: PacketNum,
142 consumed: bool,
143}
144
145pub struct NetServerRxToken<'a> {
146 ns: &'a NetServer,
147 pub packet: PacketNum,
148}
149
150impl TxToken for NetServerTxToken<'_> {
151 fn consume<R, F>(mut self, len: usize, f: F) -> R
152 where
153 F: FnOnce(&mut [u8]) -> R,
154 {
155 if len > self.ns.client_rx.packet_size() {
156 panic!(
157 "packet size exceeded ({} {})",
158 len,
159 self.ns.client_rx.packet_size()
160 );
161 }
162 let mem = self.ns.client_rx.packet_mem_mut(self.packet);
163 let ret = f(&mut mem[0..len]);
164 self.consumed = true;
165
166 self.ns
167 .client_rx
168 .send_packets(&[self.packet], |s| ServerMsg {
169 kind: ServerMsgKind::Tx(s),
170 })
171 .expect("failed to send packet");
172
173 ret
174 }
175}
176
177impl RxToken for NetServerRxToken<'_> {
178 fn consume<R, F>(self, f: F) -> R
179 where
180 F: FnOnce(&mut [u8]) -> R,
181 {
182 let mem = self.ns.client_tx.packet_mem_mut(self.packet);
183 f(mem)
184 }
185}
186
187impl Drop for NetServerTxToken<'_> {
188 fn drop(&mut self) {
189 if !self.consumed {
190 self.ns.client_rx.release_packet(self.packet);
191 }
192 }
193}