nrf_modem/
udp_socket.rs

1use crate::{
2    error::Error,
3    socket::{Socket, SocketFamily, SocketProtocol, SocketType, SplitSocketHandle},
4    CancellationToken, LteLink,
5};
6use core::net::SocketAddr;
7
8/// A socket that sends and receives UDP messages
9pub struct UdpSocket {
10    inner: Socket,
11}
12
13macro_rules! impl_receive_from {
14    () => {
15        /// Try to fill the given buffer with received data.
16        /// The part of the buffer that was filled is returned together with the address of the source of the message.
17        pub async fn receive_from<'buf>(
18            &self,
19            buf: &'buf mut [u8],
20        ) -> Result<(&'buf mut [u8], SocketAddr), Error> {
21            self.receive_from_with_cancellation(buf, &Default::default())
22                .await
23        }
24
25        /// Try to fill the given buffer with received data.
26        /// The part of the buffer that was filled is returned together with the address of the source of the message.
27        pub async fn receive_from_with_cancellation<'buf>(
28            &self,
29            buf: &'buf mut [u8],
30            token: &CancellationToken,
31        ) -> Result<(&'buf mut [u8], SocketAddr), Error> {
32            let (received_len, addr) = self
33                .socket()
34                .receive_from_with_cancellation(buf, token)
35                .await?;
36            Ok((&mut buf[..received_len], addr))
37        }
38    };
39}
40
41macro_rules! impl_send_to {
42    () => {
43        /// Send the given buffer to the given address
44        pub async fn send_to(&self, buf: &[u8], addr: SocketAddr) -> Result<(), Error> {
45            self.send_to_with_cancellation(buf, addr, &Default::default())
46                .await
47        }
48
49        /// Send the given buffer to the given address
50        pub async fn send_to_with_cancellation(
51            &self,
52            buf: &[u8],
53            addr: SocketAddr,
54            token: &CancellationToken,
55        ) -> Result<(), Error> {
56            self.socket()
57                .send_to_with_cancellation(buf, addr, token)
58                .await
59                .map(|_| ())
60        }
61    };
62}
63
64impl UdpSocket {
65    /// Bind a new socket to the given address
66    pub async fn bind(addr: SocketAddr) -> Result<Self, Error> {
67        Self::bind_with_cancellation(addr, &Default::default()).await
68    }
69
70    /// Bind a new socket to the given address
71    pub async fn bind_with_cancellation(
72        addr: SocketAddr,
73        token: &CancellationToken,
74    ) -> Result<Self, Error> {
75        let lte_link = LteLink::new().await?;
76
77        token.as_result()?;
78
79        let family = match addr {
80            SocketAddr::V4(_) => SocketFamily::Ipv4,
81            SocketAddr::V6(_) => SocketFamily::Ipv6,
82        };
83
84        let socket = Socket::create(family, SocketType::Datagram, SocketProtocol::Udp).await?;
85
86        match unsafe { socket.bind_with_cancellation(addr, token).await } {
87            Ok(_) => {
88                lte_link.deactivate().await?;
89                Ok(UdpSocket { inner: socket })
90            }
91            Err(e) => {
92                lte_link.deactivate().await?;
93                socket.deactivate().await?;
94                Err(e)
95            }
96        }
97    }
98
99    /// Get the raw underlying file descriptor
100    pub fn as_raw_fd(&self) -> i32 {
101        self.inner.as_raw_fd()
102    }
103
104    fn socket(&self) -> &Socket {
105        &self.inner
106    }
107
108    /// Split the socket into an owned read and write half
109    pub async fn split_owned(self) -> Result<(OwnedUdpReceiveSocket, OwnedUdpSendSocket), Error> {
110        let (read_split, write_split) = self.inner.split().await?;
111
112        Ok((
113            OwnedUdpReceiveSocket { socket: read_split },
114            OwnedUdpSendSocket {
115                socket: write_split,
116            },
117        ))
118    }
119
120    /// Split the socket into a borrowed read and write half
121    pub fn split(&self) -> (UdpReceiveSocket<'_>, UdpSendSocket<'_>) {
122        (
123            UdpReceiveSocket { socket: self },
124            UdpSendSocket { socket: self },
125        )
126    }
127
128    impl_receive_from!();
129    impl_send_to!();
130
131    /// Deactivates the socket and the LTE link.
132    /// A normal drop will do the same thing, but blocking.
133    pub async fn deactivate(self) -> Result<(), Error> {
134        self.inner.deactivate().await?;
135        Ok(())
136    }
137}
138
139/// A borrowed receive half of a udp socket
140pub struct UdpReceiveSocket<'a> {
141    socket: &'a UdpSocket,
142}
143
144impl UdpReceiveSocket<'_> {
145    fn socket(&self) -> &Socket {
146        &self.socket.inner
147    }
148
149    impl_receive_from!();
150}
151
152/// A borrowed send half of a udp socket
153pub struct UdpSendSocket<'a> {
154    socket: &'a UdpSocket,
155}
156
157impl UdpSendSocket<'_> {
158    fn socket(&self) -> &Socket {
159        &self.socket.inner
160    }
161
162    impl_send_to!();
163}
164
165/// An owned receive half of a udp socket
166pub struct OwnedUdpReceiveSocket {
167    socket: SplitSocketHandle,
168}
169
170impl OwnedUdpReceiveSocket {
171    fn socket(&self) -> &Socket {
172        &self.socket
173    }
174
175    impl_receive_from!();
176
177    /// Deactivates the socket and the LTE link.
178    /// A normal drop will do the same thing, but blocking.
179    pub async fn deactivate(self) -> Result<(), Error> {
180        self.socket.deactivate().await?;
181        Ok(())
182    }
183}
184
185/// An owned send half of a udp socket
186pub struct OwnedUdpSendSocket {
187    socket: SplitSocketHandle,
188}
189
190impl OwnedUdpSendSocket {
191    fn socket(&self) -> &Socket {
192        &self.socket
193    }
194
195    impl_send_to!();
196
197    /// Deactivates the socket and the LTE link.
198    /// A normal drop will do the same thing, but blocking.
199    pub async fn deactivate(self) -> Result<(), Error> {
200        self.socket.deactivate().await?;
201        Ok(())
202    }
203}