1use super::LOSE_NET_STACK;
2use super::NET_DEVICE;
3use super::net_interrupt_handler;
4use super::socket::{add_socket, pop_data, remove_socket};
5use crate::fs::File;
6use alloc::vec;
7use lose_net_stack::IPv4;
8use lose_net_stack::MacAddress;
9use lose_net_stack::packets::udp::UDPPacket;
10
11pub struct UDP {
12 pub target: IPv4,
13 pub sport: u16,
14 pub dport: u16,
15 pub socket_index: usize,
16}
17
18impl UDP {
19 pub fn new(target: IPv4, sport: u16, dport: u16) -> Self {
20 let index = add_socket(target, sport, dport).expect("can't add socket");
21
22 Self {
23 target,
24 sport,
25 dport,
26 socket_index: index,
27 }
28 }
29}
30
31impl File for UDP {
32 fn readable(&self) -> bool {
33 true
34 }
35
36 fn writable(&self) -> bool {
37 true
38 }
39
40 fn read(&self, mut buf: crate::mm::UserBuffer) -> usize {
41 loop {
42 if let Some(data) = pop_data(self.socket_index) {
43 let data_len = data.len();
44 let mut left = 0;
45 for i in 0..buf.buffers.len() {
46 let buffer_i_len = buf.buffers[i].len().min(data_len - left);
47
48 buf.buffers[i][..buffer_i_len]
49 .copy_from_slice(&data[left..(left + buffer_i_len)]);
50
51 left += buffer_i_len;
52 if left == data_len {
53 break;
54 }
55 }
56 return left;
57 } else {
58 net_interrupt_handler();
59 }
60 }
61 }
62
63 fn write(&self, buf: crate::mm::UserBuffer) -> usize {
64 let lose_net_stack = LOSE_NET_STACK.0.exclusive_access();
65
66 let mut data = vec![0u8; buf.len()];
67
68 let mut left = 0;
69 for i in 0..buf.buffers.len() {
70 data[left..(left + buf.buffers[i].len())].copy_from_slice(buf.buffers[i]);
71 left += buf.buffers[i].len();
72 }
73
74 let len = data.len();
75
76 let udp_packet = UDPPacket::new(
77 lose_net_stack.ip,
78 lose_net_stack.mac,
79 self.sport,
80 self.target,
81 MacAddress::new([0xff, 0xff, 0xff, 0xff, 0xff, 0xff]),
82 self.dport,
83 len,
84 data.as_ref(),
85 );
86 NET_DEVICE.transmit(&udp_packet.build_data());
87 len
88 }
89}
90
91impl Drop for UDP {
92 fn drop(&mut self) {
93 remove_socket(self.socket_index)
94 }
95}