Skip to content

Commit

Permalink
Merge pull request #215 from quartiq/rs/issue-60/dhcp-support
Browse files Browse the repository at this point in the history
Adding DHCP support
  • Loading branch information
ryan-summers authored Apr 19, 2022
2 parents d8cbf0d + 0c5187c commit a6a635d
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 132 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Added
* The W5500 now operates as an external MAC, and smoltcp is used as the network stack.
* DHCP support has been added, `netmask`, `ip-address`, and `gateway` settings have been removed.
Settings are backwards compatible with previous Booster releases.

## [0.3.0]

Expand Down
28 changes: 6 additions & 22 deletions src/hardware/net_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ impl NetStorage {
const fn new() -> Self {
NetStorage {
// Placeholder for the real IP address, which is initialized at runtime.
ip_addrs: [smoltcp::wire::IpCidr::Ipv6(
smoltcp::wire::Ipv6Cidr::SOLICITED_NODE_PREFIX,
)],
ip_addrs: [smoltcp::wire::IpCidr::Ipv4(smoltcp::wire::Ipv4Cidr::new(
smoltcp::wire::Ipv4Address::UNSPECIFIED,
24,
))],
neighbor_cache: [None; 8],
routes_cache: [None; 8],
sockets: [smoltcp::iface::SocketStorage::EMPTY; NUM_TCP_SOCKETS + 1],
Expand Down Expand Up @@ -76,23 +77,7 @@ pub fn setup(
let net_store = unsafe { &mut NETWORK_STORAGE };

let mut interface = {
net_store.ip_addrs[0] = {
let ip = settings.ip().octets();
let subnet = settings.subnet().octets();
smoltcp::wire::IpCidr::new(
smoltcp::wire::IpAddress::from(smoltcp::wire::Ipv4Address::from_bytes(&ip)),
smoltcp::wire::IpAddress::from(smoltcp::wire::Ipv4Address::from_bytes(&subnet))
.prefix_len()
.unwrap(),
)
};

let routes = {
let gateway = smoltcp::wire::Ipv4Address::from_bytes(&settings.gateway().octets());
let mut routes = smoltcp::iface::Routes::new(&mut net_store.routes_cache[..]);
routes.add_default_ipv4_route(gateway).unwrap();
routes
};
let routes = smoltcp::iface::Routes::new(&mut net_store.routes_cache[..]);

let neighbor_cache = smoltcp::iface::NeighborCache::new(&mut net_store.neighbor_cache[..]);

Expand All @@ -117,8 +102,7 @@ pub fn setup(
interface.add_socket(tcp_socket);
}

// TODO: Enable after we remove static IP configurations.
//interface.add_socket(smoltcp::socket::Dhcpv4Socket::new());
interface.add_socket(smoltcp::socket::Dhcpv4Socket::new());

interface
}
10 changes: 9 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ mod app {
}) {
Ok(true) => update_settings::spawn().unwrap(),
Ok(false) => {}
Err(miniconf::minimq::Error::Network(smoltcp_nal::NetworkError::NoIpAddress)) => {}
other => log::warn!("Miniconf update failure: {:?}", other),
}

Expand All @@ -317,8 +318,15 @@ mod app {
c.shared
.net_devices
.lock(|net| {
net.control
match net
.control
.poll(|handler, topic, data| main_bus.lock(|bus| handler(bus, topic, data)))
{
Err(minireq::Error::Mqtt(minimq::Error::Network(
smoltcp_nal::NetworkError::NoIpAddress,
))) => Ok(()),
other => other,
}
})
.unwrap();

Expand Down
36 changes: 6 additions & 30 deletions src/serial_terminal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,6 @@ enum Token {
#[token("id")]
Identifier,

#[token("netmask")]
Netmask,

#[token("gateway")]
Gateway,

#[token("ip-address")]
SelfAddress,

#[token("broker-address")]
BrokerAddress,

Expand All @@ -72,10 +63,7 @@ enum Token {
#[derive(PartialEq)]
pub enum Property {
Mac,
SelfAddress,
BrokerAddress,
Netmask,
Gateway,
Identifier,
}

Expand All @@ -94,10 +82,7 @@ fn get_property_string(prop: Property, settings: &BoosterSettings) -> String<128
match prop {
Property::Identifier => writeln!(&mut msg, "{}", settings.id()).unwrap(),
Property::Mac => writeln!(&mut msg, "{}", settings.mac()).unwrap(),
Property::SelfAddress => writeln!(&mut msg, "{}", settings.ip()).unwrap(),
Property::BrokerAddress => writeln!(&mut msg, "{}", settings.broker()).unwrap(),
Property::Netmask => writeln!(&mut msg, "{}", settings.subnet()).unwrap(),
Property::Gateway => writeln!(&mut msg, "{}", settings.gateway()).unwrap(),
};
msg
}
Expand Down Expand Up @@ -253,10 +238,7 @@ impl SerialTerminal {
}

Request::WriteIpAddress(prop, addr) => match prop {
Property::SelfAddress => self.settings.set_ip_address(addr),
Property::BrokerAddress => self.settings.set_broker(addr),
Property::Gateway => self.settings.set_gateway(addr),
Property::Netmask => self.settings.set_netmask(addr),
_ => self.write("Invalid property write\n".as_bytes()),
},

Expand Down Expand Up @@ -399,20 +381,20 @@ impl SerialTerminal {

fn print_help(&mut self) {
self.write(
"\n
"\n
+----------------------+
| Booster Command Help :
+----------------------+
* `reset` - Resets the device
* `dfu` - Resets the device to DFU mode
* `read <PROP>` - Reads the value of PROP. PROP may be [ip-address, broker-address, mac, id, \
gateway, netmask]
* `write <PROP> <IP>` - Writes the value of <IP> to <PROP>. <PROP> may be [ip-address, broker-address, \
netmask, gateway] and <IP> must be an IP address (e.g. 192.168.1.1)
* `read <PROP>` - Reads the value of <PROP>. <PROP> may be [broker-address, mac, id]
* `write broker-address <IP>` - Writes the value of <IP> to the broker address.
<IP> must be an IP address (e.g. 192.168.1.1)
* `write id <ID>` - Write the MQTT client ID of the device. <ID> must be 23 or less ASCII \
characters.
* `service` - Read the service information. Service infromation clears once read.
".as_bytes(),
"
.as_bytes(),
);
}

Expand Down Expand Up @@ -443,10 +425,7 @@ characters.
// Check that the property is acceptable for a read.
let property = match property_token {
Token::Mac => Property::Mac,
Token::SelfAddress => Property::SelfAddress,
Token::BrokerAddress => Property::BrokerAddress,
Token::Gateway => Property::Gateway,
Token::Netmask => Property::Netmask,
Token::Identifier => Property::Identifier,
_ => return Err("Invalid property read"),
};
Expand All @@ -459,10 +438,7 @@ characters.

// Check that the property is acceptable for a read.
let property = match property_token {
Token::SelfAddress => Property::SelfAddress,
Token::BrokerAddress => Property::BrokerAddress,
Token::Gateway => Property::Gateway,
Token::Netmask => Property::Netmask,
Token::Identifier => Property::Identifier,
_ => return Err("Invalid property write"),
};
Expand Down
89 changes: 10 additions & 79 deletions src/settings/global_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,13 @@ fn identifier_is_valid(id: &str) -> bool {
#[derive(Serialize, Deserialize)]
struct BoosterMainBoardData {
version: SemVersion,
ip_address: [u8; 4],

// Note: The IP address, gateway, and netmask are unused, but left here to maintain backwards compatibility with
// settings version v1.0.0
_unused_ip_address: [u8; 4],
broker_address: [u8; 4],
gateway_address: [u8; 4],
netmask: [u8; 4],
_unused_gateway_address: [u8; 4],
_unused_netmask: [u8; 4],
identifier: [u8; 23],
id_size: usize,
}
Expand All @@ -66,10 +69,10 @@ impl BoosterMainBoardData {

Self {
version: EXPECTED_VERSION,
ip_address: [10, 0, 0, 1],
_unused_ip_address: [10, 0, 0, 1],
broker_address: [10, 0, 0, 2],
gateway_address: [10, 0, 0, 0],
netmask: [255, 255, 255, 0],
_unused_gateway_address: [10, 0, 0, 0],
_unused_netmask: [255, 255, 255, 0],
identifier: id,
id_size: name.len(),
}
Expand Down Expand Up @@ -110,26 +113,11 @@ impl BoosterMainBoardData {
config.board_data[..serialized.len()].copy_from_slice(serialized);
}

/// Get the IP address of the Booster.
pub fn ip(&self) -> Ipv4Addr {
array_to_addr(&self.ip_address)
}

/// Get the MQTT broker address of Booster.
pub fn broker(&self) -> Ipv4Addr {
array_to_addr(&self.broker_address)
}

/// Get the gateway address of Booster.
pub fn gateway(&self) -> Ipv4Addr {
array_to_addr(&self.gateway_address)
}

/// Get the subnet mask of Booster.
pub fn subnet(&self) -> Ipv4Addr {
array_to_addr(&self.netmask)
}

/// Get the MQTT identifier of Booster.
pub fn id(&self) -> &[u8] {
&self.identifier[..self.id_size]
Expand Down Expand Up @@ -160,21 +148,6 @@ impl BoosterMainBoardData {
pub fn set_broker(&mut self, addr: Ipv4Addr) {
self.broker_address = addr.octets();
}

/// Update the IP address of Booster.
pub fn set_ip_address(&mut self, addr: Ipv4Addr) {
self.ip_address = addr.octets();
}

/// Update the IP address of the gateway.
pub fn set_gateway(&mut self, addr: Ipv4Addr) {
self.gateway_address = addr.octets();
}

/// Update the subnet mask of Booster.
pub fn set_netmask(&mut self, addr: Ipv4Addr) {
self.netmask = addr.octets();
}
}

/// Booster device-wide configurable settings.
Expand Down Expand Up @@ -261,35 +234,14 @@ impl BoosterSettings {

/// Get the Booster MAC address.
pub fn mac(&self) -> MacAddress {
#[cfg(feature = "phy_w5500")]
{
MacAddress { octets: self.eui48 }
}

#[cfg(feature = "phy_enc424j600")]
MacAddress::from_bytes(&self.eui48)
}

/// Get the Booster IP address.
pub fn ip(&self) -> Ipv4Addr {
self.board_data.ip()
MacAddress { octets: self.eui48 }
}

/// Get the MQTT broker IP address.
pub fn broker(&self) -> Ipv4Addr {
self.board_data.broker()
}

/// Get the network gateway.
pub fn gateway(&self) -> Ipv4Addr {
self.board_data.gateway()
}

/// Get the network subnet.
pub fn subnet(&self) -> Ipv4Addr {
self.board_data.subnet()
}

/// Check if current settings differ from active (executing) settings.
pub fn are_dirty(&self) -> bool {
self.dirty
Expand All @@ -302,27 +254,6 @@ impl BoosterSettings {
self.save();
}

/// Update the Booster IP address.
pub fn set_ip_address(&mut self, addr: Ipv4Addr) {
self.dirty = true;
self.board_data.set_ip_address(addr);
self.save();
}

/// Update the booster gateway.
pub fn set_gateway(&mut self, addr: Ipv4Addr) {
self.dirty = true;
self.board_data.set_gateway(addr);
self.save();
}

/// Update the booster net mask.
pub fn set_netmask(&mut self, addr: Ipv4Addr) {
self.dirty = true;
self.board_data.set_netmask(addr);
self.save();
}

/// Update the booster MQTT client identifier.
pub fn set_id(&mut self, id: &str) -> Result<(), Error> {
self.board_data.set_id(id).map(|_| {
Expand Down

0 comments on commit a6a635d

Please sign in to comment.