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