fuchsia_bluetooth/types/channel/
socket.rs1use fidl_fuchsia_bluetooth_bredr as bredr;
6use fuchsia_async as fasync;
7use futures::sink::Sink;
8use futures::stream::Stream;
9use futures::{Future, TryFutureExt, ready};
10use log::error;
11use std::collections::VecDeque;
12use std::pin::Pin;
13use std::task::{Context, Poll};
14use zx_status_ext::IoErrorKindExt;
15
16use super::{Connection, ConnectionBackendType};
17
18#[derive(Debug)]
20pub struct SocketConnection {
21 socket: fasync::Socket,
22 send_buffer: VecDeque<Vec<u8>>,
23}
24
25impl SocketConnection {
26 const MAX_QUEUED_PACKETS: usize = 32;
27
28 pub fn new(socket: zx::Socket) -> Self {
29 Self {
30 socket: fasync::Socket::from_socket(socket),
31 send_buffer: VecDeque::with_capacity(Self::MAX_QUEUED_PACKETS),
32 }
33 }
34
35 pub fn into_zx_socket(self) -> zx::Socket {
36 self.socket.into_zx_socket()
37 }
38}
39
40impl Connection for SocketConnection {
41 fn closed(&self) -> Pin<Box<dyn Future<Output = Result<(), zx::Status>> + Send + 'static>> {
42 let handle = match self.socket.as_ref().duplicate_handle(zx::Rights::SAME_RIGHTS) {
43 Ok(h) => h,
44 Err(e) => return Box::pin(futures::future::ready(Err(e))),
45 };
46 Box::pin(async move {
47 let wait = fasync::OnSignals::new(handle, zx::Signals::SOCKET_PEER_CLOSED);
48 wait.map_ok(|_| ()).await
49 })
50 }
51
52 fn connection_type(&self) -> ConnectionBackendType {
53 ConnectionBackendType::Socket
54 }
55
56 fn write(&self, bytes: &[u8]) -> Result<usize, zx::Status> {
57 self.socket.as_ref().write(bytes)
58 }
59
60 fn is_closed(&self) -> bool {
61 self.socket.is_closed()
62 }
63
64 fn into_fidl_channel(self: Box<Self>) -> Result<bredr::Channel, zx::Status> {
65 let socket = self.into_zx_socket();
66 Ok(bredr::Channel { socket: Some(socket), ..Default::default() })
67 }
68}
69
70impl Stream for SocketConnection {
71 type Item = Result<Vec<u8>, zx::Status>;
72
73 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
74 let mut res = Vec::<u8>::new();
75 loop {
76 break match self.socket.poll_datagram(cx, &mut res) {
77 Poll::Ready(Ok(0)) => continue,
78 Poll::Ready(Ok(_size)) => Poll::Ready(Some(Ok(res))),
79 Poll::Ready(Err(zx::Status::PEER_CLOSED)) => Poll::Ready(None),
80 Poll::Ready(Err(e)) => Poll::Ready(Some(Err(e))),
81 Poll::Pending => Poll::Pending,
82 };
83 }
84 }
85}
86
87impl Sink<Vec<u8>> for SocketConnection {
88 type Error = zx::Status;
89
90 fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
91 let _ = Sink::poll_flush(self.as_mut(), cx)?;
92
93 if self.send_buffer.len() >= SocketConnection::MAX_QUEUED_PACKETS {
94 return Poll::Pending;
95 }
96 Poll::Ready(Ok(()))
97 }
98
99 fn start_send(self: Pin<&mut Self>, item: Vec<u8>) -> Result<(), Self::Error> {
100 self.get_mut().send_buffer.push_back(item);
101 Ok(())
102 }
103
104 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
105 let this = self.get_mut();
106 use futures::io::AsyncWrite;
107 while let Some(item) = this.send_buffer.front() {
108 let res =
109 Pin::new(&mut this.socket).poll_write(cx, item).map_err(|e| e.kind().to_status());
110 match res {
111 Poll::Ready(Ok(size)) => {
112 if size == item.len() {
113 let _ = this.send_buffer.pop_front();
114 } else {
115 error!(
116 "Partial write in SocketConnection::Sink::poll_flush: wrote {} bytes of {} byte packet.",
117 size,
118 item.len()
119 );
120 let item = this.send_buffer.front_mut().unwrap();
121 *item = item.split_off(size);
122 }
123 }
124 Poll::Ready(Err(e)) => return Poll::Ready(Err(e)),
125 Poll::Pending => return Poll::Pending,
126 }
127 }
128 Pin::new(&mut this.socket).poll_flush(cx).map_err(|e| e.kind().to_status())
129 }
130
131 fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
132 ready!(Sink::poll_flush(self.as_mut(), cx))?;
133 let this = self.get_mut();
134 use futures::io::AsyncWrite as _;
135 Pin::new(&mut this.socket).poll_close(cx).map_err(|e| e.kind().to_status())
136 }
137}
138
139#[cfg(test)]
140mod tests {
141 use super::*;
142 use crate::types::Channel;
143 use futures::stream::FusedStream;
144 use futures::{SinkExt, StreamExt};
145 use std::pin::pin;
146
147 #[test]
148 fn channel_sync_write() {
149 let mut exec = fasync::TestExecutor::new();
150 let (mut recv, send) = Channel::create_socket_pair();
151
152 let heart: &[u8] = &[0xF0, 0x9F, 0x92, 0x96];
153 let size = send.write(heart).expect("write to succeed");
154 assert_eq!(size, heart.len());
155
156 let mut recv_fut = recv.next();
157 match exec.run_until_stalled(&mut recv_fut) {
158 Poll::Ready(Some(Ok(bytes))) => {
159 assert_eq!(heart, &bytes);
160 }
161 x => panic!("Expected Some(Ok(bytes)) from the stream, got {x:?}"),
162 };
163 }
164
165 #[test]
166 fn channel_into_fidl() {
167 let _exec = fasync::TestExecutor::new();
168 let (remote, _local) = zx::Socket::create_datagram();
169 let conn = SocketConnection::new(remote);
170
171 let fidl_channel =
172 Box::new(conn).into_fidl_channel().expect("into_fidl_channel to succeed");
173 assert!(fidl_channel.socket.is_some());
174 assert!(fidl_channel.connection.is_none());
175 }
176
177 #[test]
178 fn channel_closed() {
179 let mut exec = fasync::TestExecutor::new();
180
181 let (recv, send) = Channel::create_socket_pair();
182
183 let closed_fut = recv.closed();
184 let mut closed_fut = pin!(closed_fut);
185
186 assert!(exec.run_until_stalled(&mut closed_fut).is_pending());
187 assert!(!recv.is_closed());
188
189 drop(send);
190
191 assert!(exec.run_until_stalled(&mut closed_fut).is_ready());
192 assert!(recv.is_closed());
193 }
194
195 #[test]
196 fn channel_sink() {
197 let mut exec = fasync::TestExecutor::new();
198 let (mut recv, mut send) = Channel::create_socket_pair();
199
200 let data = vec![0x01, 0x02, 0x03, 0x04];
201 let mut send_fut = send.send(data.clone());
202
203 match exec.run_until_stalled(&mut send_fut) {
205 Poll::Ready(Ok(())) => {}
206 x => panic!("Expected Ready(Ok(())), got {:?}", x),
207 }
208
209 let mut recv_fut = recv.next();
210 match exec.run_until_stalled(&mut recv_fut) {
211 Poll::Ready(Some(Ok(bytes))) => assert_eq!(data, bytes),
212 x => panic!("Expected successful read, got {x:?}"),
213 }
214 }
215
216 #[test]
217 fn channel_stream() {
218 let mut exec = fasync::TestExecutor::new();
219 let (remote, local) = zx::Socket::create_datagram();
220 let mut recv = Channel::from_socket(remote, Channel::DEFAULT_MAX_TX).unwrap();
221 let send = local;
222
223 let mut stream_fut = recv.next();
224
225 assert!(exec.run_until_stalled(&mut stream_fut).is_pending());
226
227 let heart: &[u8] = &[0xF0, 0x9F, 0x92, 0x96];
228 let _ = send.write(heart).expect("should write successfully");
229
230 match exec.run_until_stalled(&mut stream_fut) {
231 Poll::Ready(Some(Ok(bytes))) => {
232 assert_eq!(heart.to_vec(), bytes);
233 }
234 x => panic!("Expected Some(Ok(bytes)) from the stream, got {x:?}"),
235 }
236
237 drop(send);
239
240 let mut stream_fut = recv.next();
241 match exec.run_until_stalled(&mut stream_fut) {
242 Poll::Ready(None) => {}
243 x => panic!("Expected None from the stream after close, got {x:?}"),
244 }
245
246 assert!(recv.is_terminated());
248 }
249}