1 //! Implementation of the Socket API (IBluetoothSocketManager).
2
3 use bt_topshim::btif::{BluetoothInterface, BtStatus, RawAddress, Uuid};
4 use bt_topshim::profiles::socket;
5 use log;
6 use nix::sys::socket::{recvmsg, ControlMessageOwned};
7 use nix::sys::uio::IoVec;
8 use std::collections::HashMap;
9 use std::convert::TryFrom;
10 use std::fmt;
11 use std::os::unix;
12 use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
13 use std::sync::{Arc, Mutex};
14 use std::time::Duration;
15 use tokio::net::UnixStream;
16 use tokio::runtime::{Builder, Runtime};
17 use tokio::sync::mpsc::{channel, Receiver, Sender};
18 use tokio::task::JoinHandle;
19 use tokio::time;
20
21 use crate::bluetooth::BluetoothDevice;
22 use crate::bluetooth_admin::{BluetoothAdmin, IBluetoothAdmin};
23 use crate::callbacks::Callbacks;
24 use crate::uuid::UuidHelper;
25 use crate::Message;
26 use crate::RPCProxy;
27
28 /// Type for unique identifier for each opened socket.
29 pub type SocketId = u64;
30
31 /// Type for callback identification.
32 pub type CallbackId = u32;
33
34 /// The underlying connection type for a socket.
35 pub type SocketType = socket::SocketType;
36
37 /// Result type for calls in `IBluetoothSocketManager`.
38 pub struct SocketResult {
39 pub status: BtStatus,
40 pub id: u64,
41 }
42
43 impl SocketResult {
new(status: BtStatus, id: u64) -> Self44 fn new(status: BtStatus, id: u64) -> Self {
45 SocketResult { status, id }
46 }
47 }
48
49 /// Use this to select a dynamic PSM when creating socket.
50 pub const DYNAMIC_PSM_NO_SDP: i32 = -2;
51
52 /// Use this to select a dynamic channel when creating socket.
53 pub const DYNAMIC_CHANNEL: i32 = -1;
54
55 /// Socket ids are unsigned so make zero an invalid value.
56 pub const INVALID_SOCKET_ID: SocketId = 0;
57
58 /// Represents a listening socket.
59 #[derive(Clone)]
60 pub struct BluetoothServerSocket {
61 pub id: SocketId,
62 pub sock_type: SocketType,
63 pub flags: i32,
64 pub psm: Option<i32>,
65 pub channel: Option<i32>,
66 pub name: Option<String>,
67 pub uuid: Option<Uuid>,
68 }
69
70 impl Default for BluetoothServerSocket {
default() -> Self71 fn default() -> Self {
72 BluetoothServerSocket::new()
73 }
74 }
75
76 impl BluetoothServerSocket {
new() -> Self77 fn new() -> Self {
78 BluetoothServerSocket {
79 id: 0,
80 sock_type: SocketType::Unknown,
81 flags: 0,
82 psm: None,
83 channel: None,
84 name: None,
85 uuid: None,
86 }
87 }
88
make_l2cap_channel(flags: i32, is_le: bool) -> Self89 fn make_l2cap_channel(flags: i32, is_le: bool) -> Self {
90 BluetoothServerSocket {
91 id: 0,
92 sock_type: match is_le {
93 true => SocketType::L2capLe,
94 false => SocketType::L2cap,
95 },
96 flags: flags | socket::SOCK_FLAG_NO_SDP,
97 psm: Some(DYNAMIC_PSM_NO_SDP),
98 channel: None,
99 name: None,
100 uuid: None,
101 }
102 }
103
make_rfcomm_channel( flags: i32, name: Option<String>, channel: Option<i32>, uuid: Option<Uuid>, ) -> Self104 fn make_rfcomm_channel(
105 flags: i32,
106 name: Option<String>,
107 channel: Option<i32>,
108 uuid: Option<Uuid>,
109 ) -> Self {
110 BluetoothServerSocket {
111 id: 0,
112 sock_type: SocketType::Rfcomm,
113 flags,
114 psm: None,
115 channel: channel,
116 name: name,
117 uuid: uuid,
118 }
119 }
120
make_default_rfcomm_channel(flags: i32, name: String, uuid: Uuid) -> Self121 fn make_default_rfcomm_channel(flags: i32, name: String, uuid: Uuid) -> Self {
122 BluetoothServerSocket {
123 id: 0,
124 sock_type: SocketType::Rfcomm,
125 flags,
126 psm: None,
127 channel: Some(DYNAMIC_CHANNEL),
128 name: Some(name),
129 uuid: Some(uuid),
130 }
131 }
132
133 /// Creates a new BluetoothSocket using a connection complete event and the incoming file
134 /// descriptor. The connected socket inherits the id of the listening socket.
to_connecting_socket( &self, conn: socket::ConnectionComplete, sockfd: Option<RawFd>, ) -> BluetoothSocket135 fn to_connecting_socket(
136 &self,
137 conn: socket::ConnectionComplete,
138 sockfd: Option<RawFd>,
139 ) -> BluetoothSocket {
140 let mut sock = BluetoothSocket::new();
141
142 // Data from server socket.
143 sock.id = self.id;
144 sock.sock_type = self.sock_type.clone();
145 sock.flags = self.flags;
146 sock.uuid = self.uuid.clone();
147
148 // Data from connection.
149 sock.remote_device = BluetoothDevice::new(conn.addr.to_string(), "".into());
150 sock.port = conn.channel;
151 sock.max_rx_size = conn.max_rx_packet_size.into();
152 sock.max_tx_size = conn.max_tx_packet_size.into();
153 sock.fd = match socket::try_from_fd(sockfd.unwrap_or(-1)) {
154 Ok(v) => Some(v),
155 Err(_) => None,
156 };
157
158 sock
159 }
160 }
161
162 impl fmt::Display for BluetoothServerSocket {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result163 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
164 write!(
165 f,
166 "port={}, type={:?}, name={}, uuid={}",
167 match (self.psm, self.channel) {
168 (Some(psm), Some(cn)) => format!("psm {} | cn {}", psm, cn),
169 (None, Some(cn)) => format!("cn {}", cn),
170 (Some(psm), None) => format!("psm {}", psm),
171 (None, None) => format!("none"),
172 },
173 self.sock_type,
174 self.name.as_ref().unwrap_or(&String::new()),
175 match self.uuid {
176 Some(u) => UuidHelper::to_string(&u.uu),
177 None => "".to_string(),
178 }
179 )
180 }
181 }
182
183 /// Represents a connected socket.
184 pub struct BluetoothSocket {
185 pub id: SocketId,
186 pub remote_device: BluetoothDevice,
187 pub sock_type: SocketType,
188 pub flags: i32,
189 pub fd: Option<std::fs::File>,
190 pub port: i32,
191 pub uuid: Option<Uuid>,
192 pub max_rx_size: i32,
193 pub max_tx_size: i32,
194 }
195
196 impl Default for BluetoothSocket {
default() -> Self197 fn default() -> Self {
198 BluetoothSocket::new()
199 }
200 }
201
202 impl BluetoothSocket {
new() -> Self203 fn new() -> Self {
204 BluetoothSocket {
205 id: 0,
206 remote_device: BluetoothDevice::new(String::new(), String::new()),
207 sock_type: SocketType::Unknown,
208 flags: 0,
209 fd: None,
210 port: 0,
211 uuid: None,
212 max_rx_size: 0,
213 max_tx_size: 0,
214 }
215 }
216
make_l2cap_channel(flags: i32, device: BluetoothDevice, psm: i32, is_le: bool) -> Self217 fn make_l2cap_channel(flags: i32, device: BluetoothDevice, psm: i32, is_le: bool) -> Self {
218 BluetoothSocket {
219 id: 0,
220 remote_device: device,
221 sock_type: match is_le {
222 true => SocketType::L2capLe,
223 false => SocketType::L2cap,
224 },
225 flags,
226 fd: None,
227 port: psm,
228 uuid: None,
229 max_rx_size: -1,
230 max_tx_size: -1,
231 }
232 }
233
make_rfcomm_channel(flags: i32, device: BluetoothDevice, uuid: Uuid) -> Self234 fn make_rfcomm_channel(flags: i32, device: BluetoothDevice, uuid: Uuid) -> Self {
235 BluetoothSocket {
236 id: 0,
237 remote_device: device,
238 sock_type: SocketType::Rfcomm,
239 flags,
240 fd: None,
241 port: -1,
242 uuid: Some(uuid),
243 max_rx_size: -1,
244 max_tx_size: -1,
245 }
246 }
247 }
248
249 impl fmt::Display for BluetoothSocket {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result250 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
251 write!(
252 f,
253 "[{}]:{} (type: {:?}) (uuid: {})",
254 self.remote_device.address,
255 self.port,
256 self.sock_type,
257 match self.uuid {
258 Some(u) => UuidHelper::to_string(&u.uu),
259 None => "".to_string(),
260 }
261 )
262 }
263 }
264
265 pub trait IBluetoothSocketManagerCallbacks: RPCProxy {
266 /// Listening socket is ready to listen. This is sent each time a listening socket
267 /// transitions to a non-listening state (i.e. a new listener opened or accept timed-out). The
268 /// client must re-run accept each time this event is sent to accept additional connections.
on_incoming_socket_ready(&mut self, socket: BluetoothServerSocket, status: BtStatus)269 fn on_incoming_socket_ready(&mut self, socket: BluetoothServerSocket, status: BtStatus);
270
271 /// Listening socket is closed. Reason is given in BtStatus.
on_incoming_socket_closed(&mut self, listener_id: SocketId, reason: BtStatus)272 fn on_incoming_socket_closed(&mut self, listener_id: SocketId, reason: BtStatus);
273
274 /// After listening on a socket, a connection is established. The socket is
275 /// now owned by the caller and the caller is responsible for closing the
276 /// socket.
on_handle_incoming_connection(&mut self, listener_id: SocketId, connection: BluetoothSocket)277 fn on_handle_incoming_connection(&mut self, listener_id: SocketId, connection: BluetoothSocket);
278
279 /// Result of an outgoing socket connection. The actual socket is given only
280 /// when the connection is successful.
on_outgoing_connection_result( &mut self, connecting_id: SocketId, result: BtStatus, socket: Option<BluetoothSocket>, )281 fn on_outgoing_connection_result(
282 &mut self,
283 connecting_id: SocketId,
284 result: BtStatus,
285 socket: Option<BluetoothSocket>,
286 );
287 }
288
289 pub trait IBluetoothSocketManager {
290 /// Register for socket callbacks. This must be called before calling any of
291 /// the apis below or they will always fail (because a socket id will be
292 /// associated with a specific callback).
register_callback( &mut self, callback: Box<dyn IBluetoothSocketManagerCallbacks + Send>, ) -> CallbackId293 fn register_callback(
294 &mut self,
295 callback: Box<dyn IBluetoothSocketManagerCallbacks + Send>,
296 ) -> CallbackId;
297
298 /// Create an insecure listening L2CAP socket. PSM is dynamically assigned.
listen_using_insecure_l2cap_channel(&mut self, callback: CallbackId) -> SocketResult299 fn listen_using_insecure_l2cap_channel(&mut self, callback: CallbackId) -> SocketResult;
300
301 /// Create an insecure listening L2CAP LE socket. PSM is dynamically assigned.
listen_using_insecure_l2cap_le_channel(&mut self, callback: CallbackId) -> SocketResult302 fn listen_using_insecure_l2cap_le_channel(&mut self, callback: CallbackId) -> SocketResult;
303
304 /// Create an insecure listening RFCOMM socket. Channel is dynamically assigned.
listen_using_insecure_rfcomm_with_service_record( &mut self, callback: CallbackId, name: String, uuid: Uuid, ) -> SocketResult305 fn listen_using_insecure_rfcomm_with_service_record(
306 &mut self,
307 callback: CallbackId,
308 name: String,
309 uuid: Uuid,
310 ) -> SocketResult;
311
312 /// Create a secure listening L2CAP socket. PSM is dynamically assigned.
listen_using_l2cap_channel(&mut self, callback: CallbackId) -> SocketResult313 fn listen_using_l2cap_channel(&mut self, callback: CallbackId) -> SocketResult;
314
315 /// Create a secure listening L2CAP LE socket. PSM is dynamically assigned.
listen_using_l2cap_le_channel(&mut self, callback: CallbackId) -> SocketResult316 fn listen_using_l2cap_le_channel(&mut self, callback: CallbackId) -> SocketResult;
317
318 /// Create a secure listening RFCOMM socket. Channel is dynamically assigned.
listen_using_rfcomm_with_service_record( &mut self, callback: CallbackId, name: String, uuid: Uuid, ) -> SocketResult319 fn listen_using_rfcomm_with_service_record(
320 &mut self,
321 callback: CallbackId,
322 name: String,
323 uuid: Uuid,
324 ) -> SocketResult;
325
326 /// Generic method for setting up an RFCOMM listening socket. Prefer to use one of the other
327 /// RFCOMM listen methods when possible as they reflect the more preferred RFCOMM flows, but
328 /// this method exposes all of the options that the stack supports.
listen_using_rfcomm( &mut self, callback: CallbackId, channel: Option<i32>, application_uuid: Option<Uuid>, name: Option<String>, flags: Option<i32>, ) -> SocketResult329 fn listen_using_rfcomm(
330 &mut self,
331 callback: CallbackId,
332 channel: Option<i32>,
333 application_uuid: Option<Uuid>,
334 name: Option<String>,
335 flags: Option<i32>,
336 ) -> SocketResult;
337
338 /// Create an insecure L2CAP connection.
create_insecure_l2cap_channel( &mut self, callback: CallbackId, device: BluetoothDevice, psm: i32, ) -> SocketResult339 fn create_insecure_l2cap_channel(
340 &mut self,
341 callback: CallbackId,
342 device: BluetoothDevice,
343 psm: i32,
344 ) -> SocketResult;
345
346 /// Create an insecure L2CAP LE connection.
create_insecure_l2cap_le_channel( &mut self, callback: CallbackId, device: BluetoothDevice, psm: i32, ) -> SocketResult347 fn create_insecure_l2cap_le_channel(
348 &mut self,
349 callback: CallbackId,
350 device: BluetoothDevice,
351 psm: i32,
352 ) -> SocketResult;
353
354 /// Create an insecure RFCOMM connection.
create_insecure_rfcomm_socket_to_service_record( &mut self, callback: CallbackId, device: BluetoothDevice, uuid: Uuid, ) -> SocketResult355 fn create_insecure_rfcomm_socket_to_service_record(
356 &mut self,
357 callback: CallbackId,
358 device: BluetoothDevice,
359 uuid: Uuid,
360 ) -> SocketResult;
361
362 /// Create a secure L2CAP connection.
create_l2cap_channel( &mut self, callback: CallbackId, device: BluetoothDevice, psm: i32, ) -> SocketResult363 fn create_l2cap_channel(
364 &mut self,
365 callback: CallbackId,
366 device: BluetoothDevice,
367 psm: i32,
368 ) -> SocketResult;
369
370 /// Create a secure L2CAP LE connection.
create_l2cap_le_channel( &mut self, callback: CallbackId, device: BluetoothDevice, psm: i32, ) -> SocketResult371 fn create_l2cap_le_channel(
372 &mut self,
373 callback: CallbackId,
374 device: BluetoothDevice,
375 psm: i32,
376 ) -> SocketResult;
377
378 /// Create an insecure RFCOMM connection.
create_rfcomm_socket_to_service_record( &mut self, callback: CallbackId, device: BluetoothDevice, uuid: Uuid, ) -> SocketResult379 fn create_rfcomm_socket_to_service_record(
380 &mut self,
381 callback: CallbackId,
382 device: BluetoothDevice,
383 uuid: Uuid,
384 ) -> SocketResult;
385
386 /// Start accepting connections on a listening socket.
accept(&mut self, callback: CallbackId, id: SocketId, timeout_ms: Option<u32>) -> BtStatus387 fn accept(&mut self, callback: CallbackId, id: SocketId, timeout_ms: Option<u32>) -> BtStatus;
388
389 /// Close a listening socket.
close(&mut self, callback: CallbackId, id: SocketId) -> BtStatus390 fn close(&mut self, callback: CallbackId, id: SocketId) -> BtStatus;
391 }
392
393 /// Internal listening socket data.
394 struct InternalListeningSocket {
395 _callback_id: CallbackId,
396 socket_id: SocketId,
397
398 /// Channel to future that listens for `accept` and `close` signals.
399 tx: Sender<SocketRunnerActions>,
400
401 /// Used by admin
402 uuid: Option<Uuid>,
403 }
404
405 impl InternalListeningSocket {
new( _callback_id: CallbackId, socket_id: SocketId, tx: Sender<SocketRunnerActions>, uuid: Option<Uuid>, ) -> Self406 fn new(
407 _callback_id: CallbackId,
408 socket_id: SocketId,
409 tx: Sender<SocketRunnerActions>,
410 uuid: Option<Uuid>,
411 ) -> Self {
412 InternalListeningSocket { _callback_id, socket_id, tx, uuid }
413 }
414 }
415
416 /// Internal connecting socket data.
417 struct InternalConnectingSocket {
418 _callback_id: CallbackId,
419 socket_info: BluetoothSocket,
420 stream: Option<UnixStream>,
421 }
422
423 impl InternalConnectingSocket {
new(_callback_id: CallbackId, socket_info: BluetoothSocket, fd: std::fs::File) -> Self424 fn new(_callback_id: CallbackId, socket_info: BluetoothSocket, fd: std::fs::File) -> Self {
425 let stream = file_to_unixstream(fd);
426 InternalConnectingSocket { _callback_id, socket_info, stream }
427 }
428 }
429
430 // This is a safe operation in an unsafe wrapper. Since a unix stream must have
431 // an open and valid file to operate on, converting to file via RawFd is just
432 // boilerplate.
unixstream_to_file(stream: UnixStream) -> std::fs::File433 fn unixstream_to_file(stream: UnixStream) -> std::fs::File {
434 unsafe {
435 std::fs::File::from_raw_fd(
436 stream.into_std().expect("Failed to convert tokio unixstream").into_raw_fd(),
437 )
438 }
439 }
440
441 // This is a safe operation in an unsafe wrapper. A file is already open and owned
442 // so the only way this should fail is via a safe `from_std` call in tokio's
443 // UnixStream.
file_to_unixstream(fd: std::fs::File) -> Option<UnixStream>444 fn file_to_unixstream(fd: std::fs::File) -> Option<UnixStream> {
445 let raw_stream = unsafe { unix::net::UnixStream::from_raw_fd(fd.into_raw_fd()) };
446 match UnixStream::from_std(raw_stream) {
447 Ok(v) => Some(v),
448 Err(e) => {
449 log::error!("Failed to convert file to unixstream: {}", e);
450 None
451 }
452 }
453 }
454
455 /// Time to wait for a socket to connect before timing out.
456 /// TODO(abps) - Should this be configurable?
457 const CONNECT_COMPLETE_TIMEOUT_MS: u64 = 10000;
458
459 /// Actions to take on the socket in the socket runner.
460 pub(crate) enum SocketRunnerActions {
461 /// Accept connections on a listening socket with an optional timeout.
462 AcceptTimeout(SocketId, Option<Duration>),
463
464 /// Close a listening socket.
465 Close(SocketId),
466 }
467
468 /// Actions to take in message handler runner (RPC context). Many of these match
469 /// `IBluetoothSocketManagerCallbacks` so check there for documentation as well.
470 pub enum SocketActions {
471 // First 3 events are for listening sockets.
472 OnIncomingSocketReady(CallbackId, BluetoothServerSocket, BtStatus),
473 OnIncomingSocketClosed(CallbackId, SocketId, BtStatus),
474 OnHandleIncomingConnection(CallbackId, SocketId, BluetoothSocket),
475
476 // Last event is for connecting socket.
477 OnOutgoingConnectionResult(CallbackId, SocketId, BtStatus, Option<BluetoothSocket>),
478 }
479
480 /// Implementation of the `IBluetoothSocketManager` api.
481 pub struct BluetoothSocketManager {
482 /// Callbacks registered against the socket manager.
483 callbacks: Callbacks<dyn IBluetoothSocketManagerCallbacks + Send>,
484
485 /// List of listening sockets.
486 listening: HashMap<CallbackId, Vec<InternalListeningSocket>>,
487
488 /// Current futures mapped by callback id (so we can drop if callback disconnects).
489 futures: HashMap<CallbackId, Vec<JoinHandle<()>>>,
490
491 /// Separate runtime for socket listeners (so they're not dependent on the
492 /// same runtime as RPC).
493 runtime: Arc<Runtime>,
494
495 /// Topshim interface for socket. Must call initialize for this to be valid.
496 sock: Option<socket::BtSocket>,
497
498 /// Monotonically increasing counter for socket id. Always access using
499 /// `next_socket_id`.
500 socket_counter: SocketId,
501
502 /// Channel TX for the mainloop for topstack.
503 tx: Sender<Message>,
504
505 /// Admin
506 admin: Arc<Mutex<Box<BluetoothAdmin>>>,
507 }
508
509 impl BluetoothSocketManager {
510 /// Constructs the IBluetooth implementation.
new(tx: Sender<Message>, admin: Arc<Mutex<Box<BluetoothAdmin>>>) -> Self511 pub fn new(tx: Sender<Message>, admin: Arc<Mutex<Box<BluetoothAdmin>>>) -> Self {
512 let callbacks = Callbacks::new(tx.clone(), Message::SocketManagerCallbackDisconnected);
513 let socket_counter: u64 = 1000;
514 let futures = HashMap::new();
515 let listening = HashMap::new();
516 let runtime = Arc::new(
517 Builder::new_multi_thread()
518 .worker_threads(1)
519 .max_blocking_threads(1)
520 .enable_all()
521 .build()
522 .expect("Failed to make socket runtime."),
523 );
524
525 BluetoothSocketManager {
526 callbacks,
527 futures,
528 listening,
529 runtime,
530 sock: None,
531 socket_counter,
532 tx,
533 admin,
534 }
535 }
536
537 /// In order to access the underlying socket apis, we must initialize after
538 /// the btif layer has initialized. Thus, this must be called after intf is
539 /// init.
initialize(&mut self, intf: Arc<Mutex<BluetoothInterface>>)540 pub fn initialize(&mut self, intf: Arc<Mutex<BluetoothInterface>>) {
541 self.sock = Some(socket::BtSocket::new(&intf.lock().unwrap()));
542 }
543
544 // TODO(abps) - We need to save information about who the caller is so that
545 // we can pipe it down to the lower levels. This needs to be
546 // provided by the projection layer and is currently missing.
get_caller_uid(&self) -> i32547 fn get_caller_uid(&self) -> i32 {
548 0
549 }
550
551 /// Get the next available socket id.
next_socket_id(&mut self) -> SocketId552 fn next_socket_id(&mut self) -> SocketId {
553 let next = self.socket_counter;
554 self.socket_counter = next + 1;
555
556 next
557 }
558
559 /// Common handler for |sock->listen| call.
socket_listen( &mut self, mut socket_info: BluetoothServerSocket, cbid: CallbackId, ) -> SocketResult560 fn socket_listen(
561 &mut self,
562 mut socket_info: BluetoothServerSocket,
563 cbid: CallbackId,
564 ) -> SocketResult {
565 if let Some(uuid) = socket_info.uuid {
566 if !self.admin.lock().unwrap().is_service_allowed(uuid.into()) {
567 log::debug!("service {} is blocked by admin policy", uuid);
568 return SocketResult::new(BtStatus::AuthRejected, INVALID_SOCKET_ID);
569 }
570 }
571
572 // Create listener socket pair
573 let (mut status, result) =
574 self.sock.as_ref().expect("Socket Manager not initialized").listen(
575 socket_info.sock_type.clone(),
576 socket_info.name.as_ref().unwrap_or(&String::new()).clone(),
577 match socket_info.uuid {
578 Some(u) => Some(u.uu.clone()),
579 None => None,
580 },
581 match socket_info.sock_type {
582 SocketType::Rfcomm => socket_info.channel.unwrap_or(DYNAMIC_CHANNEL),
583 SocketType::L2cap | SocketType::L2capLe => {
584 socket_info.psm.unwrap_or(DYNAMIC_PSM_NO_SDP)
585 }
586 _ => 0,
587 },
588 socket_info.flags,
589 self.get_caller_uid(),
590 );
591
592 // Put socket into listening list and return result.
593 match result {
594 Ok(file) => {
595 // Push new socket into listeners.
596 let id = self.next_socket_id();
597 socket_info.id = id;
598 let (runner_tx, runner_rx) = channel::<SocketRunnerActions>(10);
599
600 // Keep track of active listener sockets.
601 let listener = InternalListeningSocket::new(cbid, id, runner_tx, socket_info.uuid);
602 self.listening.entry(cbid).or_default().push(listener);
603
604 // Push a listening task to local runtime to wait for device to
605 // start accepting or get closed.
606 let rpc_tx = self.tx.clone();
607
608 // If the stream can't be converted to filestream, fail early.
609 let stream = match file_to_unixstream(file) {
610 Some(v) => v,
611 None => {
612 log::debug!("Converting from file to unixstream failed");
613 return SocketResult::new(BtStatus::Fail, INVALID_SOCKET_ID);
614 }
615 };
616
617 // We only send socket ready after we've read the channel out.
618 let listen_status = status.clone();
619 let joinhandle = self.runtime.spawn(async move {
620 BluetoothSocketManager::listening_task(
621 cbid,
622 listen_status,
623 runner_rx,
624 socket_info,
625 stream,
626 rpc_tx,
627 )
628 .await;
629 });
630
631 self.futures.entry(cbid).or_default().push(joinhandle);
632
633 SocketResult::new(status, id)
634 }
635 Err(_) => {
636 // Bad file descriptor but underlying api says success.
637 if status == BtStatus::Success {
638 log::error!("Invalid socketpair but listen api succeeded.");
639 status = BtStatus::Fail;
640 }
641
642 log::error!("Failed to listen on {}. Status={:?}", socket_info, status);
643
644 SocketResult::new(status, INVALID_SOCKET_ID)
645 }
646 }
647 }
648
649 /// Common handler for |sock->connect| call.
socket_connect( &mut self, mut socket_info: BluetoothSocket, cbid: CallbackId, ) -> SocketResult650 fn socket_connect(
651 &mut self,
652 mut socket_info: BluetoothSocket,
653 cbid: CallbackId,
654 ) -> SocketResult {
655 if let Some(uuid) = socket_info.uuid {
656 if !self.admin.lock().unwrap().is_service_allowed(uuid.into()) {
657 log::debug!("service {} is blocked by admin policy", uuid);
658 return SocketResult::new(BtStatus::AuthRejected, INVALID_SOCKET_ID);
659 }
660 }
661
662 let addr = match RawAddress::from_string(socket_info.remote_device.address.clone()) {
663 Some(v) => v,
664 None => {
665 log::warn!(
666 "Invalid address during socket connection: {}",
667 socket_info.remote_device.address.clone()
668 );
669 return SocketResult::new(BtStatus::InvalidParam, INVALID_SOCKET_ID);
670 }
671 };
672
673 // Create connecting socket pair.
674 let (mut status, result) =
675 self.sock.as_ref().expect("Socket manager not initialized").connect(
676 addr,
677 socket_info.sock_type.clone(),
678 match socket_info.uuid {
679 Some(u) => Some(u.uu.clone()),
680 None => None,
681 },
682 socket_info.port,
683 socket_info.flags,
684 self.get_caller_uid(),
685 );
686
687 // Put socket into connecting list and return result. Connecting sockets
688 // need to be listening for a completion event at which point they will
689 // send the ready signal.
690 match result {
691 Ok(file) => {
692 // Push new socket into connectors. These will wait until the
693 // connection complete event is seen and then emit an event for
694 // callbacks.
695 let id = self.next_socket_id();
696 socket_info.id = id;
697 let connector = InternalConnectingSocket::new(cbid, socket_info, file);
698
699 // Push a connecting task to local runtime to wait for connection
700 // completion.
701 let tx = self.tx.clone();
702 let joinhandle = self.runtime.spawn(async move {
703 BluetoothSocketManager::connecting_task(
704 cbid,
705 id,
706 tx,
707 connector,
708 Duration::from_millis(CONNECT_COMPLETE_TIMEOUT_MS),
709 )
710 .await;
711 });
712
713 // Keep track of these futures in case they need to be cancelled due to callback
714 // disconnecting.
715 self.futures.entry(cbid).or_default().push(joinhandle);
716
717 SocketResult::new(status, id)
718 }
719 Err(_) => {
720 if status == BtStatus::Success {
721 log::error!("Invalid socketpair but connect api succeeded.");
722 status = BtStatus::Fail;
723 }
724
725 log::error!("Failed to connect to {}. Status={:?}", socket_info, status);
726
727 SocketResult::new(status, INVALID_SOCKET_ID)
728 }
729 }
730 }
731
listening_task( cbid: CallbackId, listen_status: BtStatus, mut runner_rx: Receiver<SocketRunnerActions>, mut socket_info: BluetoothServerSocket, stream: UnixStream, rpc_tx: Sender<Message>, )732 async fn listening_task(
733 cbid: CallbackId,
734 listen_status: BtStatus,
735 mut runner_rx: Receiver<SocketRunnerActions>,
736 mut socket_info: BluetoothServerSocket,
737 stream: UnixStream,
738 rpc_tx: Sender<Message>,
739 ) {
740 let mut accepting: Option<JoinHandle<()>> = None;
741 let stream = Arc::new(stream);
742
743 let connection_timeout = Duration::from_millis(CONNECT_COMPLETE_TIMEOUT_MS);
744 // Wait for stream to be readable, then read channel. This is the first thing that must
745 // happen in the listening channel. If this fails, close the channel.
746 let mut channel_bytes = [0 as u8; 4];
747 let mut status =
748 Self::wait_and_read_stream(connection_timeout, &stream, &mut channel_bytes).await;
749 let channel = i32::from_ne_bytes(channel_bytes);
750 if channel <= 0 {
751 status = BtStatus::Fail;
752 }
753
754 // If we don't get a valid channel, consider the socket as closed.
755 if status != BtStatus::Success {
756 // First send the incoming socket ready signal and then closed. If we
757 // are unable to read the channel, the client needs to consider the
758 // socket as closed.
759 let _ = rpc_tx
760 .send(Message::SocketManagerActions(SocketActions::OnIncomingSocketReady(
761 cbid,
762 socket_info.clone(),
763 status,
764 )))
765 .await;
766 let _ = rpc_tx
767 .send(Message::SocketManagerActions(SocketActions::OnIncomingSocketClosed(
768 cbid,
769 socket_info.id,
770 BtStatus::Success,
771 )))
772 .await;
773
774 return;
775 }
776
777 match socket_info.sock_type {
778 SocketType::Rfcomm => socket_info.channel = Some(channel),
779 SocketType::L2cap | SocketType::L2capLe => socket_info.psm = Some(channel),
780
781 // Don't care about other types. We don't support them in this path.
782 _ => (),
783 };
784 // Notify via callbacks that this socket is ready to be listened to since we have the
785 // channel available now.
786 let (forwarded_socket, forwarded_status) = (socket_info.clone(), listen_status.clone());
787 let _ = rpc_tx
788 .send(Message::SocketManagerActions(SocketActions::OnIncomingSocketReady(
789 cbid,
790 forwarded_socket,
791 forwarded_status,
792 )))
793 .await;
794
795 loop {
796 let m = match runner_rx.recv().await {
797 Some(v) => v,
798 None => {
799 break;
800 }
801 };
802
803 match m {
804 SocketRunnerActions::AcceptTimeout(socket_id, may_timeout) => {
805 // If the given socket id doesn't match, ignore the call.
806 if &socket_id != &socket_info.id {
807 continue;
808 }
809
810 // Cancel the previous future before continuing.
811 if let Some(ref handle) = accepting {
812 handle.abort();
813 }
814
815 let tx = rpc_tx.clone();
816 let cloned_socket_info = socket_info.clone();
817 let cstream = stream.clone();
818
819 // Replace the previous joinhandle.
820 accepting = Some(tokio::spawn(async move {
821 loop {
822 let readable = if let Some(timeout) = may_timeout {
823 match time::timeout(timeout, cstream.readable()).await {
824 // Result ok means ready to read.
825 Ok(r) => r.is_ok(),
826 // Timeout means we exit this future after sending.
827 Err(_) => false,
828 }
829 } else {
830 cstream.readable().await.is_ok()
831 };
832
833 // Anytime the readable future completes but isn't readable,
834 // we send a socket ready with a failed status message (you
835 // can try accepting again).
836 if !readable {
837 let _ = tx
838 .send(Message::SocketManagerActions(
839 SocketActions::OnIncomingSocketReady(
840 cbid,
841 cloned_socket_info,
842 BtStatus::Fail,
843 ),
844 ))
845 .await;
846 break;
847 }
848
849 // Read the accepted socket information and use
850 // CMSG to grab the sockets also transferred over
851 // this socket.
852 let rawfd = cstream.as_raw_fd();
853 let socket_info_inner = cloned_socket_info.clone();
854 let sock: std::io::Result<Option<BluetoothSocket>> =
855 cstream.try_io(tokio::io::Interest::READABLE, || {
856 let mut data = [0; socket::CONNECT_COMPLETE_SIZE];
857 let iov = [IoVec::from_mut_slice(&mut data)];
858 let mut cspace = nix::cmsg_space!(RawFd);
859 let maybe_sock = match recvmsg(
860 rawfd,
861 &iov,
862 Some(&mut cspace),
863 nix::sys::socket::MsgFlags::MSG_DONTWAIT,
864 ) {
865 Ok(recv) => {
866 let fd = match recv.cmsgs().next() {
867 Some(ControlMessageOwned::ScmRights(fds)) => {
868 if fds.len() == 1 {
869 Some(fds[0])
870 } else {
871 log::error!(
872 "Unexpected number of fds given: {}",
873 fds.len()
874 );
875 None
876 }
877 }
878 _ => {
879 log::error!(
880 "Ancillary fds not found in connection."
881 );
882 None
883 }
884 };
885
886 return match socket::ConnectionComplete::try_from(
887 &data[0..socket::CONNECT_COMPLETE_SIZE],
888 ) {
889 Ok(cc) => {
890 let status = BtStatus::from(cc.status as u32);
891 let sock = socket_info_inner
892 .to_connecting_socket(cc, fd);
893
894 if status == BtStatus::Success
895 && sock.fd.is_some()
896 {
897 Ok(Some(sock))
898 } else {
899 Ok(None)
900 }
901 }
902 Err(e) => Ok(None),
903 };
904 }
905
906 Err(e) => {
907 if e == nix::errno::Errno::EAGAIN {
908 Err(std::io::Error::new(
909 std::io::ErrorKind::WouldBlock,
910 "Recvfrom is readable but would block on read",
911 ))
912 } else {
913 Ok(None)
914 }
915 }
916 };
917
918 maybe_sock
919 });
920
921 // If we returned an error for the above socket, then the recv failed.
922 // Just continue this loop.
923 if !sock.is_ok() {
924 continue;
925 }
926
927 match sock.unwrap_or(None) {
928 Some(s) => {
929 let _ = tx
930 .send(Message::SocketManagerActions(
931 SocketActions::OnHandleIncomingConnection(
932 cbid, s.id, s,
933 ),
934 ))
935 .await;
936 }
937 // Exit out of the accepting state here.
938 None => {
939 log::error!(
940 "Incoming connection failed to recv: {}",
941 cloned_socket_info
942 );
943
944 let _ = tx
945 .send(Message::SocketManagerActions(
946 SocketActions::OnIncomingSocketReady(
947 cbid,
948 cloned_socket_info,
949 BtStatus::Fail,
950 ),
951 ))
952 .await;
953
954 break;
955 }
956 }
957 }
958 }));
959 }
960 SocketRunnerActions::Close(socket_id) => {
961 // Ignore requests where socket id doesn't match.
962 if &socket_id != &socket_info.id {
963 continue;
964 }
965
966 // First close any active accepting handle.
967 if let Some(ref handle) = accepting {
968 handle.abort();
969 }
970
971 // Notify RPC that we're closing.
972 let _ = rpc_tx
973 .send(Message::SocketManagerActions(SocketActions::OnIncomingSocketClosed(
974 cbid,
975 socket_info.id,
976 BtStatus::Success,
977 )))
978 .await;
979
980 // Now exit this task.
981 break;
982 }
983 }
984 }
985 }
986
987 /// Helper function that waits for given stream to be readable and then reads the stream into
988 /// the provided buffer.
wait_and_read_stream( timeout: Duration, stream: &UnixStream, buf: &mut [u8], ) -> BtStatus989 async fn wait_and_read_stream(
990 timeout: Duration,
991 stream: &UnixStream,
992 buf: &mut [u8],
993 ) -> BtStatus {
994 // Wait on the stream to be readable.
995 match time::timeout(timeout, stream.readable()).await {
996 Ok(inner) => match inner {
997 Ok(()) => {}
998 Err(_e) => {
999 // Stream was not readable. This is usually due to some polling error.
1000 return BtStatus::Fail;
1001 }
1002 },
1003 Err(_) => {
1004 // Timed out waiting for stream to be readable.
1005 return BtStatus::NotReady;
1006 }
1007 };
1008
1009 match stream.try_read(buf) {
1010 Ok(n) => {
1011 if n != buf.len() {
1012 return BtStatus::Fail;
1013 }
1014 return BtStatus::Success;
1015 }
1016 _ => {
1017 return BtStatus::Fail;
1018 }
1019 }
1020 }
1021
1022 /// Task spawned on socket runtime to handle socket connections.
1023 ///
1024 /// This task will always result in a |SocketActions::OnOutgoingConnectionResult| message being
1025 /// sent and the result will depend on whether the connection is successful.
connecting_task( cbid: CallbackId, socket_id: SocketId, tx: Sender<Message>, connector: InternalConnectingSocket, connection_timeout: Duration, )1026 async fn connecting_task(
1027 cbid: CallbackId,
1028 socket_id: SocketId,
1029 tx: Sender<Message>,
1030 connector: InternalConnectingSocket,
1031 connection_timeout: Duration,
1032 ) {
1033 // If the unixstream isn't available for this connection, immediately return
1034 // a failure.
1035 let stream = match connector.stream {
1036 Some(s) => s,
1037 None => {
1038 let _ = tx
1039 .send(Message::SocketManagerActions(SocketActions::OnOutgoingConnectionResult(
1040 cbid,
1041 socket_id,
1042 BtStatus::Fail,
1043 None,
1044 )))
1045 .await;
1046 return;
1047 }
1048 };
1049
1050 // Wait for stream to be readable, then read channel
1051 let mut channel_bytes = [0 as u8; 4];
1052 let mut status =
1053 Self::wait_and_read_stream(connection_timeout, &stream, &mut channel_bytes).await;
1054 if i32::from_ne_bytes(channel_bytes) <= 0 {
1055 status = BtStatus::Fail;
1056 }
1057 if status != BtStatus::Success {
1058 log::info!(
1059 "Connecting socket to {} failed while trying to read channel from stream",
1060 connector.socket_info
1061 );
1062 let _ = tx
1063 .send(Message::SocketManagerActions(SocketActions::OnOutgoingConnectionResult(
1064 cbid, socket_id, status, None,
1065 )))
1066 .await;
1067 return;
1068 }
1069
1070 // Wait for stream to be readable, then read connect complete data
1071 let mut data = [0; socket::CONNECT_COMPLETE_SIZE];
1072 let status = Self::wait_and_read_stream(connection_timeout, &stream, &mut data).await;
1073 if status != BtStatus::Success {
1074 log::info!(
1075 "Connecting socket to {} failed while trying to read connect complete from stream",
1076 connector.socket_info
1077 );
1078 let _ = tx
1079 .send(Message::SocketManagerActions(SocketActions::OnOutgoingConnectionResult(
1080 cbid, socket_id, status, None,
1081 )))
1082 .await;
1083 return;
1084 }
1085 match socket::ConnectionComplete::try_from(&data[0..socket::CONNECT_COMPLETE_SIZE]) {
1086 Ok(cc) => {
1087 let status = BtStatus::from(cc.status as u32);
1088 if status != BtStatus::Success {
1089 let _ = tx
1090 .send(Message::SocketManagerActions(
1091 SocketActions::OnOutgoingConnectionResult(
1092 cbid,
1093 socket_id,
1094 status.clone(),
1095 None,
1096 ),
1097 ))
1098 .await;
1099 } else {
1100 let mut sock = connector.socket_info;
1101 sock.fd = Some(unixstream_to_file(stream));
1102 sock.port = cc.channel;
1103 sock.max_rx_size = cc.max_rx_packet_size.into();
1104 sock.max_tx_size = cc.max_tx_packet_size.into();
1105
1106 let _ = tx
1107 .send(Message::SocketManagerActions(
1108 SocketActions::OnOutgoingConnectionResult(
1109 cbid,
1110 socket_id,
1111 status.clone(),
1112 Some(sock),
1113 ),
1114 ))
1115 .await;
1116 }
1117 }
1118 Err(err) => {
1119 log::info!("Unable to parse ConnectionComplete: {}", err);
1120 let _ = tx
1121 .send(Message::SocketManagerActions(SocketActions::OnOutgoingConnectionResult(
1122 cbid,
1123 socket_id,
1124 BtStatus::Fail,
1125 None,
1126 )))
1127 .await;
1128 }
1129 }
1130 }
1131
handle_actions(&mut self, action: SocketActions)1132 pub fn handle_actions(&mut self, action: SocketActions) {
1133 match action {
1134 SocketActions::OnIncomingSocketReady(cbid, server_socket, status) => {
1135 if let Some(callback) = self.callbacks.get_by_id_mut(cbid) {
1136 callback.on_incoming_socket_ready(server_socket, status);
1137 }
1138 }
1139
1140 SocketActions::OnIncomingSocketClosed(cbid, socket_id, status) => {
1141 if let Some(callback) = self.callbacks.get_by_id_mut(cbid) {
1142 callback.on_incoming_socket_closed(socket_id, status);
1143
1144 // Also make sure to remove the socket from listening list.
1145 self.listening
1146 .entry(cbid)
1147 .and_modify(|v| v.retain(|s| s.socket_id != socket_id));
1148 }
1149 }
1150
1151 SocketActions::OnHandleIncomingConnection(cbid, socket_id, socket) => {
1152 if let Some(callback) = self.callbacks.get_by_id_mut(cbid) {
1153 callback.on_handle_incoming_connection(socket_id, socket);
1154 }
1155 }
1156
1157 SocketActions::OnOutgoingConnectionResult(cbid, socket_id, status, socket) => {
1158 if let Some(callback) = self.callbacks.get_by_id_mut(cbid) {
1159 callback.on_outgoing_connection_result(socket_id, status, socket);
1160 }
1161 }
1162 }
1163 }
1164
1165 /// Close Rfcomm sockets whose UUID is not allowed by policy
handle_admin_policy_changed(&mut self)1166 pub fn handle_admin_policy_changed(&mut self) {
1167 let forbidden_sockets = self
1168 .listening
1169 .values()
1170 .into_iter()
1171 .flatten()
1172 .filter(|sock| {
1173 sock.uuid
1174 // Don't need to close L2cap socket (indicated by no uuid).
1175 .map_or(false, |uuid| {
1176 !self.admin.lock().unwrap().is_service_allowed(uuid.into())
1177 })
1178 })
1179 .map(|sock| (sock.socket_id, sock.tx.clone(), sock.uuid.unwrap()))
1180 .collect::<Vec<(u64, Sender<SocketRunnerActions>, Uuid)>>();
1181
1182 self.runtime.spawn(async move {
1183 for (id, tx, uuid) in forbidden_sockets {
1184 log::debug!(
1185 "socket id {} is not allowed by admin policy due to uuid {}, closing",
1186 id,
1187 uuid
1188 );
1189 let _ = tx.send(SocketRunnerActions::Close(id)).await;
1190 }
1191 });
1192 }
1193
remove_callback(&mut self, callback: CallbackId)1194 pub fn remove_callback(&mut self, callback: CallbackId) {
1195 // Remove any associated futures and sockets waiting to accept.
1196 self.futures.remove(&callback);
1197 self.listening.remove(&callback);
1198 self.callbacks.remove_callback(callback);
1199 }
1200
1201 // Send MSC command to the peer. ONLY FOR QUALIFICATION USE.
1202 // libbluetooth auto starts the control request only when it is the client.
1203 // This function allows the host to start the control request while as a server.
rfcomm_send_msc(&mut self, dlci: u8, addr: String)1204 pub fn rfcomm_send_msc(&mut self, dlci: u8, addr: String) {
1205 match (|| -> Result<(), &str> {
1206 let addr = RawAddress::from_string(addr)
1207 .ok_or("Invalid address for starting control request")?;
1208 let sock = self
1209 .sock
1210 .as_ref()
1211 .ok_or("Socket Manager not initialized when starting control request")?;
1212 if sock.send_msc(dlci, addr) != BtStatus::Success {
1213 return Err("Failed to start control request");
1214 }
1215 Ok(())
1216 })() {
1217 Ok(_) => {}
1218 Err(msg) => log::warn!("{}", msg),
1219 };
1220 }
1221 }
1222
1223 impl IBluetoothSocketManager for BluetoothSocketManager {
register_callback( &mut self, callback: Box<dyn IBluetoothSocketManagerCallbacks + Send>, ) -> CallbackId1224 fn register_callback(
1225 &mut self,
1226 callback: Box<dyn IBluetoothSocketManagerCallbacks + Send>,
1227 ) -> CallbackId {
1228 self.callbacks.add_callback(callback)
1229 }
1230
listen_using_insecure_l2cap_channel(&mut self, callback: CallbackId) -> SocketResult1231 fn listen_using_insecure_l2cap_channel(&mut self, callback: CallbackId) -> SocketResult {
1232 if self.callbacks.get_by_id(callback).is_none() {
1233 return SocketResult::new(BtStatus::NotReady, INVALID_SOCKET_ID);
1234 }
1235
1236 let socket_info = BluetoothServerSocket::make_l2cap_channel(socket::SOCK_FLAG_NONE, false);
1237 self.socket_listen(socket_info, callback)
1238 }
1239
listen_using_insecure_l2cap_le_channel(&mut self, callback: CallbackId) -> SocketResult1240 fn listen_using_insecure_l2cap_le_channel(&mut self, callback: CallbackId) -> SocketResult {
1241 if self.callbacks.get_by_id(callback).is_none() {
1242 return SocketResult::new(BtStatus::NotReady, INVALID_SOCKET_ID);
1243 }
1244
1245 let socket_info = BluetoothServerSocket::make_l2cap_channel(socket::SOCK_FLAG_NONE, true);
1246 self.socket_listen(socket_info, callback)
1247 }
1248
listen_using_l2cap_channel(&mut self, callback: CallbackId) -> SocketResult1249 fn listen_using_l2cap_channel(&mut self, callback: CallbackId) -> SocketResult {
1250 if self.callbacks.get_by_id(callback).is_none() {
1251 return SocketResult::new(BtStatus::NotReady, INVALID_SOCKET_ID);
1252 }
1253
1254 let socket_info =
1255 BluetoothServerSocket::make_l2cap_channel(socket::SOCK_META_FLAG_SECURE, false);
1256 self.socket_listen(socket_info, callback)
1257 }
1258
listen_using_l2cap_le_channel(&mut self, callback: CallbackId) -> SocketResult1259 fn listen_using_l2cap_le_channel(&mut self, callback: CallbackId) -> SocketResult {
1260 if self.callbacks.get_by_id(callback).is_none() {
1261 return SocketResult::new(BtStatus::NotReady, INVALID_SOCKET_ID);
1262 }
1263
1264 let socket_info =
1265 BluetoothServerSocket::make_l2cap_channel(socket::SOCK_META_FLAG_SECURE, true);
1266 self.socket_listen(socket_info, callback)
1267 }
1268
listen_using_insecure_rfcomm_with_service_record( &mut self, callback: CallbackId, name: String, uuid: Uuid, ) -> SocketResult1269 fn listen_using_insecure_rfcomm_with_service_record(
1270 &mut self,
1271 callback: CallbackId,
1272 name: String,
1273 uuid: Uuid,
1274 ) -> SocketResult {
1275 if self.callbacks.get_by_id(callback).is_none() {
1276 return SocketResult::new(BtStatus::NotReady, INVALID_SOCKET_ID);
1277 }
1278
1279 let socket_info =
1280 BluetoothServerSocket::make_default_rfcomm_channel(socket::SOCK_FLAG_NONE, name, uuid);
1281 self.socket_listen(socket_info, callback)
1282 }
1283
listen_using_rfcomm_with_service_record( &mut self, callback: CallbackId, name: String, uuid: Uuid, ) -> SocketResult1284 fn listen_using_rfcomm_with_service_record(
1285 &mut self,
1286 callback: CallbackId,
1287 name: String,
1288 uuid: Uuid,
1289 ) -> SocketResult {
1290 if self.callbacks.get_by_id(callback).is_none() {
1291 return SocketResult::new(BtStatus::NotReady, INVALID_SOCKET_ID);
1292 }
1293
1294 let socket_info = BluetoothServerSocket::make_default_rfcomm_channel(
1295 socket::SOCK_META_FLAG_SECURE,
1296 name,
1297 uuid,
1298 );
1299
1300 self.socket_listen(socket_info, callback)
1301 }
1302
listen_using_rfcomm( &mut self, callback: CallbackId, channel: Option<i32>, application_uuid: Option<Uuid>, name: Option<String>, flags: Option<i32>, ) -> SocketResult1303 fn listen_using_rfcomm(
1304 &mut self,
1305 callback: CallbackId,
1306 channel: Option<i32>,
1307 application_uuid: Option<Uuid>,
1308 name: Option<String>,
1309 flags: Option<i32>,
1310 ) -> SocketResult {
1311 if self.callbacks.get_by_id(callback).is_none() {
1312 return SocketResult::new(BtStatus::NotReady, INVALID_SOCKET_ID);
1313 }
1314
1315 let flags = match flags {
1316 Some(flags) => flags,
1317 None => socket::SOCK_FLAG_NONE,
1318 };
1319
1320 self.socket_listen(
1321 BluetoothServerSocket::make_rfcomm_channel(flags, name, channel, application_uuid),
1322 callback,
1323 )
1324 }
1325
create_insecure_l2cap_channel( &mut self, callback: CallbackId, device: BluetoothDevice, psm: i32, ) -> SocketResult1326 fn create_insecure_l2cap_channel(
1327 &mut self,
1328 callback: CallbackId,
1329 device: BluetoothDevice,
1330 psm: i32,
1331 ) -> SocketResult {
1332 if self.callbacks.get_by_id(callback).is_none() {
1333 return SocketResult::new(BtStatus::NotReady, INVALID_SOCKET_ID);
1334 }
1335
1336 let socket_info =
1337 BluetoothSocket::make_l2cap_channel(socket::SOCK_FLAG_NONE, device, psm, false);
1338 self.socket_connect(socket_info, callback)
1339 }
1340
create_insecure_l2cap_le_channel( &mut self, callback: CallbackId, device: BluetoothDevice, psm: i32, ) -> SocketResult1341 fn create_insecure_l2cap_le_channel(
1342 &mut self,
1343 callback: CallbackId,
1344 device: BluetoothDevice,
1345 psm: i32,
1346 ) -> SocketResult {
1347 if self.callbacks.get_by_id(callback).is_none() {
1348 return SocketResult::new(BtStatus::NotReady, INVALID_SOCKET_ID);
1349 }
1350
1351 let socket_info =
1352 BluetoothSocket::make_l2cap_channel(socket::SOCK_FLAG_NONE, device, psm, true);
1353 self.socket_connect(socket_info, callback)
1354 }
1355
create_l2cap_channel( &mut self, callback: CallbackId, device: BluetoothDevice, psm: i32, ) -> SocketResult1356 fn create_l2cap_channel(
1357 &mut self,
1358 callback: CallbackId,
1359 device: BluetoothDevice,
1360 psm: i32,
1361 ) -> SocketResult {
1362 if self.callbacks.get_by_id(callback).is_none() {
1363 return SocketResult::new(BtStatus::NotReady, INVALID_SOCKET_ID);
1364 }
1365
1366 let socket_info =
1367 BluetoothSocket::make_l2cap_channel(socket::SOCK_META_FLAG_SECURE, device, psm, false);
1368 self.socket_connect(socket_info, callback)
1369 }
1370
create_l2cap_le_channel( &mut self, callback: CallbackId, device: BluetoothDevice, psm: i32, ) -> SocketResult1371 fn create_l2cap_le_channel(
1372 &mut self,
1373 callback: CallbackId,
1374 device: BluetoothDevice,
1375 psm: i32,
1376 ) -> SocketResult {
1377 if self.callbacks.get_by_id(callback).is_none() {
1378 return SocketResult::new(BtStatus::NotReady, INVALID_SOCKET_ID);
1379 }
1380
1381 let socket_info =
1382 BluetoothSocket::make_l2cap_channel(socket::SOCK_META_FLAG_SECURE, device, psm, true);
1383 self.socket_connect(socket_info, callback)
1384 }
1385
create_insecure_rfcomm_socket_to_service_record( &mut self, callback: CallbackId, device: BluetoothDevice, uuid: Uuid, ) -> SocketResult1386 fn create_insecure_rfcomm_socket_to_service_record(
1387 &mut self,
1388 callback: CallbackId,
1389 device: BluetoothDevice,
1390 uuid: Uuid,
1391 ) -> SocketResult {
1392 if self.callbacks.get_by_id(callback).is_none() {
1393 return SocketResult::new(BtStatus::NotReady, INVALID_SOCKET_ID);
1394 }
1395
1396 let socket_info =
1397 BluetoothSocket::make_rfcomm_channel(socket::SOCK_FLAG_NONE, device, uuid);
1398 self.socket_connect(socket_info, callback)
1399 }
1400
create_rfcomm_socket_to_service_record( &mut self, callback: CallbackId, device: BluetoothDevice, uuid: Uuid, ) -> SocketResult1401 fn create_rfcomm_socket_to_service_record(
1402 &mut self,
1403 callback: CallbackId,
1404 device: BluetoothDevice,
1405 uuid: Uuid,
1406 ) -> SocketResult {
1407 if self.callbacks.get_by_id(callback).is_none() {
1408 return SocketResult::new(BtStatus::NotReady, INVALID_SOCKET_ID);
1409 }
1410
1411 let socket_info =
1412 BluetoothSocket::make_rfcomm_channel(socket::SOCK_META_FLAG_SECURE, device, uuid);
1413 self.socket_connect(socket_info, callback)
1414 }
1415
accept(&mut self, callback: CallbackId, id: SocketId, timeout_ms: Option<u32>) -> BtStatus1416 fn accept(&mut self, callback: CallbackId, id: SocketId, timeout_ms: Option<u32>) -> BtStatus {
1417 match self.listening.get(&callback) {
1418 Some(v) => {
1419 if let Some(found) = v.iter().find(|item| item.socket_id == id) {
1420 let tx = found.tx.clone();
1421 let timeout_duration = match timeout_ms {
1422 Some(t) => Some(Duration::from_millis(t.into())),
1423 None => None,
1424 };
1425 self.runtime.spawn(async move {
1426 let _ =
1427 tx.send(SocketRunnerActions::AcceptTimeout(id, timeout_duration)).await;
1428 });
1429
1430 return BtStatus::Success;
1431 }
1432 }
1433 None => (),
1434 }
1435
1436 BtStatus::InvalidParam
1437 }
1438
close(&mut self, callback: CallbackId, id: SocketId) -> BtStatus1439 fn close(&mut self, callback: CallbackId, id: SocketId) -> BtStatus {
1440 match self.listening.get(&callback) {
1441 Some(v) => {
1442 if let Some(found) = v.iter().find(|item| item.socket_id == id) {
1443 let tx = found.tx.clone();
1444 self.runtime.spawn(async move {
1445 let _ = tx.send(SocketRunnerActions::Close(id)).await;
1446 });
1447
1448 return BtStatus::Success;
1449 }
1450 }
1451 None => (),
1452 }
1453
1454 BtStatus::InvalidParam
1455 }
1456 }
1457