Skip to content

Commit

Permalink
(WIP) Embassy support
Browse files Browse the repository at this point in the history
  • Loading branch information
ivmarkov committed Mar 25, 2024
1 parent d499bc6 commit eaa4e89
Show file tree
Hide file tree
Showing 16 changed files with 675 additions and 52 deletions.
7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ rust-version = "1.77"

[features]
default = ["io", "std"]
std = ["io", "edge-captive/std", "edge-dhcp/std", "edge-http/std", "edge-mdns/std", "edge-raw/std", "edge-mqtt", "edge-ws/std", "edge-nal-std"]
std = ["io", "edge-captive/std", "edge-dhcp/std", "edge-http/std", "edge-mdns/std", "edge-raw/std", "edge-mqtt", "edge-ws/std", "edge-nal-std", "edge-nal-embassy"]
io = ["edge-captive/io", "edge-dhcp/io", "edge-http/io", "edge-mdns/io", "edge-raw/io", "edge-ws/io", "edge-nal"]
nightly = []
embedded-svc = ["edge-http/embedded-svc", "edge-mqtt/embedded-svc", "edge-ws/embedded-svc"]
Expand All @@ -28,6 +28,7 @@ edge-nal = { workspace = true, optional = true }
edge-raw = { workspace = true }
edge-ws = { workspace = true }
edge-nal-std = { workspace = true, optional = true }
edge-nal-embassy = { workspace = true, optional = true }

[dev-dependencies]
log = "0.4"
Expand Down Expand Up @@ -94,7 +95,8 @@ members = [
"edge-nal",
"edge-raw",
"edge-ws",
"edge-nal-std"
"edge-nal-std",
"edge-nal-embassy"
]

[workspace.dependencies]
Expand All @@ -117,3 +119,4 @@ edge-nal = { version = "0.2.0", path = "edge-nal", default-features = false }
edge-raw = { version = "0.2.0", path = "edge-raw", default-features = false }
edge-ws = { version = "0.2.0", path = "edge-ws", default-features = false }
edge-nal-std = { version = "0.2.0", path = "edge-nal-std", default-features = false }
edge-nal-embassy = { version = "0.2.0", path = "edge-nal-embassy", default-features = false }
4 changes: 2 additions & 2 deletions edge-captive/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use core::fmt;
use core::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
use core::time::Duration;

use edge_nal::{UdpReceive, UdpSend, UdpStack};
use edge_nal::{UdpBind, UdpReceive, UdpSend};

use log::*;

Expand Down Expand Up @@ -48,7 +48,7 @@ pub async fn run<S>(
ttl: Duration,
) -> Result<(), DnsIoError<S::Error>>
where
S: UdpStack,
S: UdpBind,
{
let (_, mut udp) = stack.bind(local_addr).await.map_err(DnsIoError::IoError)?;

Expand Down
4 changes: 2 additions & 2 deletions edge-mdns/src/io.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use embassy_sync::blocking_mutex::raw::{NoopRawMutex, RawMutex};
use embassy_sync::mutex::Mutex;
use embassy_time::{Duration, Timer};

use edge_nal::{Multicast, UdpReceive, UdpSend, UdpSplit, UdpStack};
use edge_nal::{Multicast, UdpBind, UdpReceive, UdpSend, UdpSplit};

use log::{info, warn};

Expand Down Expand Up @@ -76,7 +76,7 @@ pub async fn run<'s, T, S>(
) -> Result<(), MdnsIoError<S::Error>>
where
T: IntoIterator<Item = Service<'s>> + Clone,
S: UdpStack,
S: UdpBind,
for<'a> S::Socket<'a>: Multicast<Error = S::Error>,
{
let (local_addr, mut udp) = stack.bind(socket).await.map_err(MdnsIoError::IoError)?;
Expand Down
6 changes: 6 additions & 0 deletions edge-nal-embassy/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
21 changes: 21 additions & 0 deletions edge-nal-embassy/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "edge-nal-embassy"
version = "0.2.0"
edition = "2021"
rust-version = "1.77"
description = "Am implementation of edge-nal based on `embassy-net`"
repository = "https://github.com/ivmarkov/edge-net"
readme = "README.md"
license = "MIT OR Apache-2.0"
categories = [
"embedded",
"no-std",
"asynchronous",
"networking"
]

[dependencies]
embedded-io-async = { workspace = true }
edge-nal = { workspace = true }
heapless = { workspace = true }
embassy-net = { version = "0.4", features = ["tcp", "udp", "dns", "proto-ipv6", "medium-ethernet", "proto-ipv4"] }
7 changes: 7 additions & 0 deletions edge-nal-embassy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# edge-nal-embassy

[![CI](https://github.com/ivmarkov/edge-net/actions/workflows/ci.yml/badge.svg)](https://github.com/ivmarkov/edge-net/actions/workflows/ci.yml)
![crates.io](https://img.shields.io/crates/v/edge-net.svg)
[![Documentation](https://docs.rs/edge-net/badge.svg)](https://docs.rs/edge-net)

A bare-metal implementation of `edge-nal` based on [embassy-net]().
103 changes: 103 additions & 0 deletions edge-nal-embassy/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#![no_std]
#![allow(async_fn_in_trait)]
#![warn(clippy::large_futures)]

use core::cell::{Cell, UnsafeCell};
use core::mem::MaybeUninit;
use core::net::{IpAddr, Ipv6Addr, SocketAddr};
use core::ptr::NonNull;

use embassy_net::{IpAddress, IpEndpoint, IpListenEndpoint};

pub use tcp::*;
pub use udp::*;

mod tcp;
mod udp;

pub(crate) struct Pool<T, const N: usize> {
used: [Cell<bool>; N],
data: [UnsafeCell<MaybeUninit<T>>; N],
}

impl<T, const N: usize> Pool<T, N> {
const VALUE: Cell<bool> = Cell::new(false);
const UNINIT: UnsafeCell<MaybeUninit<T>> = UnsafeCell::new(MaybeUninit::uninit());

const fn new() -> Self {
Self {
used: [Self::VALUE; N],
data: [Self::UNINIT; N],
}
}
}

impl<T, const N: usize> Pool<T, N> {
fn alloc(&self) -> Option<NonNull<T>> {
for n in 0..N {
// this can't race because Pool is not Sync.
if !self.used[n].get() {
self.used[n].set(true);
let p = self.data[n].get() as *mut T;
return Some(unsafe { NonNull::new_unchecked(p) });
}
}
None
}

/// safety: p must be a pointer obtained from self.alloc that hasn't been freed yet.
unsafe fn free(&self, p: NonNull<T>) {
let origin = self.data.as_ptr() as *mut T;
let n = p.as_ptr().offset_from(origin);
assert!(n >= 0);
assert!((n as usize) < N);
self.used[n as usize].set(false);
}
}

pub(crate) fn to_net_socket(socket: IpEndpoint) -> SocketAddr {
SocketAddr::new(to_net_addr(socket.addr), socket.port)
}

pub(crate) fn to_net_socket2(socket: IpListenEndpoint) -> SocketAddr {
SocketAddr::new(
socket
.addr
.map(to_net_addr)
.unwrap_or(IpAddr::V6(Ipv6Addr::UNSPECIFIED)),
socket.port,
)
}

pub(crate) fn to_emb_socket(socket: SocketAddr) -> IpEndpoint {
IpEndpoint {
addr: to_emb_addr(socket.ip()),
port: socket.port(),
}
}

pub(crate) fn to_net_addr(addr: IpAddress) -> IpAddr {
match addr {
//#[cfg(feature = "proto-ipv4")]
IpAddress::Ipv4(addr) => addr.0.into(),
// #[cfg(not(feature = "proto-ipv4"))]
// IpAddr::V4(_) => panic!("ipv4 support not enabled"),
//#[cfg(feature = "proto-ipv6")]
IpAddress::Ipv6(addr) => addr.0.into(),
// #[cfg(not(feature = "proto-ipv6"))]
// IpAddr::V6(_) => panic!("ipv6 support not enabled"),
}
}

pub(crate) fn to_emb_addr(addr: IpAddr) -> IpAddress {
match addr {
//#[cfg(feature = "proto-ipv4")]
IpAddr::V4(addr) => IpAddress::Ipv4(embassy_net::Ipv4Address::from_bytes(&addr.octets())),
// #[cfg(not(feature = "proto-ipv4"))]
// IpAddr::V4(_) => panic!("ipv4 support not enabled"),
//#[cfg(feature = "proto-ipv6")]
IpAddr::V6(addr) => IpAddress::Ipv6(embassy_net::Ipv6Address::from_bytes(&addr.octets())),
// #[cfg(not(feature = "proto-ipv6"))]
// IpAddr::V6(_) => panic!("ipv6 support not enabled"),
}
}
Loading

0 comments on commit eaa4e89

Please sign in to comment.