Skip to content

Commit

Permalink
revise network integration and add support of futures
Browse files Browse the repository at this point in the history
smoltcp 0.7 provides async/await waker support (smoltcp-rs/smoltcp#394).
I followed the example implementation https://github.com/embassy-rs/embassy/tree/net/embassy-net
to add waker support in hermit-sys.

However, hermit-sys can be used in a multi-threaded applications.
Consequently, the implementation must be thread safed. In addition,
we still have an "network thread", which is wakeup by an interrupt.
The thread wakeups all waiting future. If no future is available,
the thread calls directly the IP stack.
  • Loading branch information
stlankes committed Mar 22, 2021
1 parent 98162b3 commit 57f39bd
Show file tree
Hide file tree
Showing 5 changed files with 574 additions and 424 deletions.
132 changes: 132 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions hermit-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ llvm-tools = { version = "0.1" }

[dependencies]
log = { version = "0.4", default-features = false }
lazy_static = "1.4.0"
libm = { version = "0.2.1", default-features = false }
futures = { version = "0.3.5" }
futures-util = { version = "0.3.12" }
lazy_static = "1.4"

[target.'cfg(target_arch = "x86_64")'.dependencies.x86]
version = "0.*"
Expand All @@ -49,9 +51,9 @@ default-features = false
version = "0.7.0"
optional = true
default-features = false
features = ["std", "ethernet", "socket-udp", "socket-tcp", "proto-ipv4", "proto-ipv6"]
features = ["std", "ethernet", "socket-udp", "socket-tcp", "proto-ipv4", "proto-ipv6", "async"]
# to increase the output the features log and verbose should be enabled
#features = ["log", "verbose", "std", "ethernet", "socket-udp", "socket-tcp", "proto-ipv4", "proto-ipv6"]
#features = ["log", "verbose", "std", "ethernet", "socket-udp", "socket-tcp", "proto-ipv4", "proto-ipv6", "async"]

[dependencies.rftrace]
version = "0.1.0"
Expand Down
27 changes: 13 additions & 14 deletions hermit-sys/src/net/device.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use std::convert::TryInto;
#[cfg(not(feature = "dhcpv4"))]
use std::net::Ipv4Addr;
use std::slice;
use std::sync::Mutex;

#[cfg(feature = "dhcpv4")]
use smoltcp::dhcp::Dhcpv4Client;
Expand All @@ -24,7 +25,7 @@ use smoltcp::wire::IpAddress;
use smoltcp::wire::Ipv4Cidr;
use smoltcp::wire::{EthernetAddress, IpCidr, Ipv4Address};

use crate::net::NetworkInterface;
use crate::net::{NetworkInterface, NetworkState};

extern "Rust" {
fn sys_get_mac_address() -> Result<[u8; 6], ()>;
Expand All @@ -44,18 +45,18 @@ pub struct HermitNet {
}

impl HermitNet {
pub fn new(mtu: u16) -> Self {
pub const fn new(mtu: u16) -> Self {
Self { mtu }
}
}

impl NetworkInterface<HermitNet> {
#[cfg(feature = "dhcpv4")]
pub fn new() -> Option<Self> {
pub fn new() -> NetworkState {
let mtu = match unsafe { sys_get_mtu() } {
Ok(mtu) => mtu,
Err(_) => {
return None;
return NetworkState::InitializationFailed;
}
};
let device = HermitNet::new(mtu);
Expand All @@ -67,7 +68,7 @@ impl NetworkInterface<HermitNet> {
let mac: [u8; 6] = match unsafe { sys_get_mac_address() } {
Ok(mac) => mac,
Err(_) => {
return None;
return NetworkState::InitializationFailed;
}
};

Expand All @@ -92,21 +93,20 @@ impl NetworkInterface<HermitNet> {
.routes(routes)
.finalize();

Some(Self {
NetworkState::Initialized(Mutex::new(Self {
iface,
sockets: sockets,
wait_for: BTreeMap::new(),
dhcp,
prev_cidr,
})
}))
}

#[cfg(not(feature = "dhcpv4"))]
pub fn new() -> Option<Self> {
pub fn new() -> NetworkState {
let mtu = match unsafe { sys_get_mtu() } {
Ok(mtu) => mtu,
Err(_) => {
return None;
return NetworkState::InitializationFailed;
}
};
let device = HermitNet::new(mtu);
Expand All @@ -118,7 +118,7 @@ impl NetworkInterface<HermitNet> {
let mac: [u8; 6] = match unsafe { sys_get_mac_address() } {
Ok(mac) => mac,
Err(_) => {
return None;
return NetworkState::InitializationFailed;
}
};
let myip: Ipv4Addr = HERMIT_IP.parse().expect("Unable to parse IPv4 address");
Expand Down Expand Up @@ -166,11 +166,10 @@ impl NetworkInterface<HermitNet> {
.routes(routes)
.finalize();

Some(Self {
NetworkState::Initialized(Mutex::new(Self {
iface,
sockets: SocketSet::new(vec![]),
wait_for: BTreeMap::new(),
})
}))
}
}

Expand Down
Loading

0 comments on commit 57f39bd

Please sign in to comment.