aboutsummaryrefslogtreecommitdiff
path: root/embassy-net/src/lib.rs
diff options
context:
space:
mode:
authorPaweł Jan Czochański <[email protected]>2023-01-18 10:10:33 +0100
committerDario Nieuwenhuis <[email protected]>2023-01-19 14:44:01 +0100
commit8f4fae9b36f017a8ab65491ef49b72499a9486dc (patch)
treed5bd2b0df691d7602507093426c3ee5a498c8c5f /embassy-net/src/lib.rs
parent2eae12b7f1cbe38d850ebf30f23a776323815af6 (diff)
Add smoltcp dhcp socket configuration
Diffstat (limited to 'embassy-net/src/lib.rs')
-rw-r--r--embassy-net/src/lib.rs72
1 files changed, 52 insertions, 20 deletions
diff --git a/embassy-net/src/lib.rs b/embassy-net/src/lib.rs
index 757d3e27d..c419ec1f9 100644
--- a/embassy-net/src/lib.rs
+++ b/embassy-net/src/lib.rs
@@ -30,6 +30,8 @@ use smoltcp::iface::SocketHandle;
30use smoltcp::iface::{Interface, InterfaceBuilder, SocketSet, SocketStorage}; 30use smoltcp::iface::{Interface, InterfaceBuilder, SocketSet, SocketStorage};
31#[cfg(feature = "dhcpv4")] 31#[cfg(feature = "dhcpv4")]
32use smoltcp::socket::dhcpv4; 32use smoltcp::socket::dhcpv4;
33use smoltcp::socket::dhcpv4::RetryConfig;
34use smoltcp::time::Duration;
33// smoltcp reexports 35// smoltcp reexports
34pub use smoltcp::time::{Duration as SmolDuration, Instant as SmolInstant}; 36pub use smoltcp::time::{Duration as SmolDuration, Instant as SmolInstant};
35#[cfg(feature = "medium-ethernet")] 37#[cfg(feature = "medium-ethernet")]
@@ -45,31 +47,53 @@ use crate::device::DriverAdapter;
45const LOCAL_PORT_MIN: u16 = 1025; 47const LOCAL_PORT_MIN: u16 = 1025;
46const LOCAL_PORT_MAX: u16 = 65535; 48const LOCAL_PORT_MAX: u16 = 65535;
47 49
48pub struct StackResources<const SOCK: usize, const NEIGHBOR: usize> { 50pub struct StackResources<const SOCK: usize> {
49 addresses: [IpCidr; 5],
50 sockets: [SocketStorage<'static>; SOCK], 51 sockets: [SocketStorage<'static>; SOCK],
51} 52}
52 53
53impl<const SOCK: usize, const NEIGHBOR: usize> StackResources<SOCK, NEIGHBOR> { 54impl<const SOCK: usize> StackResources<SOCK> {
54 pub fn new() -> Self { 55 pub fn new() -> Self {
55 Self { 56 Self {
56 addresses: [IpCidr::new(Ipv4Address::UNSPECIFIED.into(), 32); 5],
57 sockets: [SocketStorage::EMPTY; SOCK], 57 sockets: [SocketStorage::EMPTY; SOCK],
58 } 58 }
59 } 59 }
60} 60}
61 61
62#[derive(Debug, Clone, PartialEq, Eq)] 62#[derive(Debug, Clone, PartialEq, Eq)]
63pub struct Config { 63pub struct StaticConfig {
64 pub address: Ipv4Cidr, 64 pub address: Ipv4Cidr,
65 pub gateway: Option<Ipv4Address>, 65 pub gateway: Option<Ipv4Address>,
66 pub dns_servers: Vec<Ipv4Address, 3>, 66 pub dns_servers: Vec<Ipv4Address, 3>,
67} 67}
68 68
69pub enum ConfigStrategy { 69#[derive(Debug, Clone, PartialEq, Eq)]
70 Static(Config), 70pub struct DhcpConfig {
71 pub max_lease_duration: Option<Duration>,
72 pub retry_config: RetryConfig,
73 /// Ignore NAKs.
74 pub ignore_naks: bool,
75 /// Server port config
76 pub server_port: u16,
77 /// Client port config
78 pub client_port: u16,
79}
80
81impl Default for DhcpConfig {
82 fn default() -> Self {
83 Self {
84 max_lease_duration: Default::default(),
85 retry_config: Default::default(),
86 ignore_naks: Default::default(),
87 server_port: smoltcp::wire::DHCP_SERVER_PORT,
88 client_port: smoltcp::wire::DHCP_CLIENT_PORT,
89 }
90 }
91}
92
93pub enum Config {
94 Static(StaticConfig),
71 #[cfg(feature = "dhcpv4")] 95 #[cfg(feature = "dhcpv4")]
72 Dhcp, 96 Dhcp(DhcpConfig),
73} 97}
74 98
75pub struct Stack<D: Driver> { 99pub struct Stack<D: Driver> {
@@ -80,7 +104,7 @@ pub struct Stack<D: Driver> {
80struct Inner<D: Driver> { 104struct Inner<D: Driver> {
81 device: D, 105 device: D,
82 link_up: bool, 106 link_up: bool,
83 config: Option<Config>, 107 config: Option<StaticConfig>,
84 #[cfg(feature = "dhcpv4")] 108 #[cfg(feature = "dhcpv4")]
85 dhcp_socket: Option<SocketHandle>, 109 dhcp_socket: Option<SocketHandle>,
86} 110}
@@ -93,17 +117,16 @@ pub(crate) struct SocketStack {
93} 117}
94 118
95impl<D: Driver + 'static> Stack<D> { 119impl<D: Driver + 'static> Stack<D> {
96 pub fn new<const ADDR: usize, const SOCK: usize, const NEIGH: usize>( 120 pub fn new<const SOCK: usize>(
97 mut device: D, 121 mut device: D,
98 config: ConfigStrategy, 122 config: Config,
99 resources: &'static mut StackResources<SOCK, NEIGH>, 123 resources: &'static mut StackResources<SOCK>,
100 random_seed: u64, 124 random_seed: u64,
101 ) -> Self { 125 ) -> Self {
102 #[cfg(feature = "medium-ethernet")] 126 #[cfg(feature = "medium-ethernet")]
103 let medium = device.capabilities().medium; 127 let medium = device.capabilities().medium;
104 128
105 let mut b = InterfaceBuilder::new(); 129 let mut b = InterfaceBuilder::new();
106 b = b.ip_addrs(Vec::<IpCidr, 5>::from_iter(resources.addresses));
107 b = b.random_seed(random_seed); 130 b = b.random_seed(random_seed);
108 131
109 #[cfg(feature = "medium-ethernet")] 132 #[cfg(feature = "medium-ethernet")]
@@ -136,10 +159,12 @@ impl<D: Driver + 'static> Stack<D> {
136 }; 159 };
137 160
138 match config { 161 match config {
139 ConfigStrategy::Static(config) => inner.apply_config(&mut socket, config), 162 Config::Static(config) => inner.apply_config(&mut socket, config),
140 #[cfg(feature = "dhcpv4")] 163 #[cfg(feature = "dhcpv4")]
141 ConfigStrategy::Dhcp => { 164 Config::Dhcp(config) => {
142 let handle = socket.sockets.add(smoltcp::socket::dhcpv4::Socket::new()); 165 let mut dhcp_socket = smoltcp::socket::dhcpv4::Socket::new();
166 inner.apply_dhcp_config(&mut dhcp_socket, config);
167 let handle = socket.sockets.add(dhcp_socket);
143 inner.dhcp_socket = Some(handle); 168 inner.dhcp_socket = Some(handle);
144 } 169 }
145 } 170 }
@@ -170,7 +195,7 @@ impl<D: Driver + 'static> Stack<D> {
170 self.with(|_s, i| i.config.is_some()) 195 self.with(|_s, i| i.config.is_some())
171 } 196 }
172 197
173 pub fn config(&self) -> Option<Config> { 198 pub fn config(&self) -> Option<StaticConfig> {
174 self.with(|_s, i| i.config.clone()) 199 self.with(|_s, i| i.config.clone())
175 } 200 }
176 201
@@ -185,7 +210,7 @@ impl<D: Driver + 'static> Stack<D> {
185} 210}
186 211
187impl SocketStack { 212impl SocketStack {
188 #[allow(clippy::absurd_extreme_comparisons)] 213 #[allow(clippy::absurd_extreme_comparisons, dead_code)]
189 pub fn get_local_port(&mut self) -> u16 { 214 pub fn get_local_port(&mut self) -> u16 {
190 let res = self.next_local_port; 215 let res = self.next_local_port;
191 self.next_local_port = if res >= LOCAL_PORT_MAX { LOCAL_PORT_MIN } else { res + 1 }; 216 self.next_local_port = if res >= LOCAL_PORT_MAX { LOCAL_PORT_MIN } else { res + 1 };
@@ -194,7 +219,7 @@ impl SocketStack {
194} 219}
195 220
196impl<D: Driver + 'static> Inner<D> { 221impl<D: Driver + 'static> Inner<D> {
197 fn apply_config(&mut self, s: &mut SocketStack, config: Config) { 222 fn apply_config(&mut self, s: &mut SocketStack, config: StaticConfig) {
198 #[cfg(feature = "medium-ethernet")] 223 #[cfg(feature = "medium-ethernet")]
199 let medium = self.device.capabilities().medium; 224 let medium = self.device.capabilities().medium;
200 225
@@ -220,6 +245,13 @@ impl<D: Driver + 'static> Inner<D> {
220 self.config = Some(config) 245 self.config = Some(config)
221 } 246 }
222 247
248 fn apply_dhcp_config(&self, socket: &mut smoltcp::socket::dhcpv4::Socket, config: DhcpConfig) {
249 socket.set_ignore_naks(config.ignore_naks);
250 socket.set_max_lease_duration(config.max_lease_duration);
251 socket.set_ports(config.server_port, config.client_port);
252 socket.set_retry_config(config.retry_config);
253 }
254
223 #[allow(unused)] // used only with dhcp 255 #[allow(unused)] // used only with dhcp
224 fn unapply_config(&mut self, s: &mut SocketStack) { 256 fn unapply_config(&mut self, s: &mut SocketStack) {
225 #[cfg(feature = "medium-ethernet")] 257 #[cfg(feature = "medium-ethernet")]
@@ -280,7 +312,7 @@ impl<D: Driver + 'static> Inner<D> {
280 None => {} 312 None => {}
281 Some(dhcpv4::Event::Deconfigured) => self.unapply_config(s), 313 Some(dhcpv4::Event::Deconfigured) => self.unapply_config(s),
282 Some(dhcpv4::Event::Configured(config)) => { 314 Some(dhcpv4::Event::Configured(config)) => {
283 let config = Config { 315 let config = StaticConfig {
284 address: config.address, 316 address: config.address,
285 gateway: config.router, 317 gateway: config.router,
286 dns_servers: config.dns_servers, 318 dns_servers: config.dns_servers,