use crate::{
error::Error,
socket::{Socket, SocketFamily, SocketProtocol, SocketType, SplitSocketHandle},
CancellationToken, LteLink,
};
use no_std_net::{SocketAddr, ToSocketAddrs};
pub struct UdpSocket {
inner: Socket,
}
macro_rules! impl_receive_from {
() => {
pub async fn receive_from<'buf>(
&self,
buf: &'buf mut [u8],
) -> Result<(&'buf mut [u8], SocketAddr), Error> {
self.receive_from_with_cancellation(buf, &Default::default())
.await
}
pub async fn receive_from_with_cancellation<'buf>(
&self,
buf: &'buf mut [u8],
token: &CancellationToken,
) -> Result<(&'buf mut [u8], SocketAddr), Error> {
let (received_len, addr) = self.socket().receive_from(buf, token).await?;
Ok((&mut buf[..received_len], addr))
}
};
}
macro_rules! impl_send_to {
() => {
pub async fn send_to(&self, buf: &[u8], addr: SocketAddr) -> Result<(), Error> {
self.send_to_with_cancellation(buf, addr, &Default::default())
.await
}
pub async fn send_to_with_cancellation(
&self,
buf: &[u8],
addr: SocketAddr,
token: &CancellationToken,
) -> Result<(), Error> {
self.socket().send_to(buf, addr, token).await.map(|_| ())
}
};
}
impl UdpSocket {
pub async fn bind(addr: impl ToSocketAddrs) -> Result<Self, Error> {
Self::bind_with_cancellation(addr, &Default::default()).await
}
pub async fn bind_with_cancellation(
addr: impl ToSocketAddrs,
token: &CancellationToken,
) -> Result<Self, Error> {
let mut last_error = None;
let lte_link = LteLink::new().await?;
let addrs = addr.to_socket_addrs().unwrap();
for addr in addrs {
token.as_result()?;
let family = match addr {
no_std_net::SocketAddr::V4(_) => SocketFamily::Ipv4,
no_std_net::SocketAddr::V6(_) => SocketFamily::Ipv6,
};
let socket = Socket::create(family, SocketType::Datagram, SocketProtocol::Udp).await?;
match unsafe { socket.bind(addr, token).await } {
Ok(_) => {
lte_link.deactivate().await?;
return Ok(UdpSocket { inner: socket });
}
Err(e) => {
last_error = Some(e);
socket.deactivate().await?;
}
}
}
lte_link.deactivate().await?;
Err(last_error.take().unwrap())
}
pub fn as_raw_fd(&self) -> i32 {
self.inner.as_raw_fd()
}
fn socket(&self) -> &Socket {
&self.inner
}
pub async fn split_owned(self) -> Result<(OwnedUdpReceiveSocket, OwnedUdpSendSocket), Error> {
let (read_split, write_split) = self.inner.split().await?;
Ok((
OwnedUdpReceiveSocket { socket: read_split },
OwnedUdpSendSocket {
socket: write_split,
},
))
}
pub fn split(&self) -> (UdpReceiveSocket<'_>, UdpSendSocket<'_>) {
(
UdpReceiveSocket { socket: self },
UdpSendSocket { socket: self },
)
}
impl_receive_from!();
impl_send_to!();
pub async fn deactivate(self) -> Result<(), Error> {
self.inner.deactivate().await?;
Ok(())
}
}
pub struct UdpReceiveSocket<'a> {
socket: &'a UdpSocket,
}
impl<'a> UdpReceiveSocket<'a> {
fn socket(&self) -> &Socket {
&self.socket.inner
}
impl_receive_from!();
}
pub struct UdpSendSocket<'a> {
socket: &'a UdpSocket,
}
impl<'a> UdpSendSocket<'a> {
fn socket(&self) -> &Socket {
&self.socket.inner
}
impl_send_to!();
}
pub struct OwnedUdpReceiveSocket {
socket: SplitSocketHandle,
}
impl OwnedUdpReceiveSocket {
fn socket(&self) -> &Socket {
&self.socket
}
impl_receive_from!();
pub async fn deactivate(self) -> Result<(), Error> {
self.socket.deactivate().await?;
Ok(())
}
}
pub struct OwnedUdpSendSocket {
socket: SplitSocketHandle,
}
impl OwnedUdpSendSocket {
fn socket(&self) -> &Socket {
&self.socket
}
impl_send_to!();
pub async fn deactivate(self) -> Result<(), Error> {
self.socket.deactivate().await?;
Ok(())
}
}