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