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::Runtime;
19 use tokio::sync::mpsc::{channel, Receiver, Sender};
20 use tokio::task::JoinHandle;
21 use tokio::time;
22
23 use crate::bluetooth::{Bluetooth, BluetoothDevice};
24 use crate::bluetooth_admin::BluetoothAdminPolicyHelper;
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,
118 name,
119 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;
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) => "none".to_string(),
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: 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 /// The adapter API. Used for configuring the scan mode for listening socket.
520 adapter: Arc<Mutex<Box<Bluetooth>>>,
521
522 /// Admin helper
523 admin_helper: BluetoothAdminPolicyHelper,
524 }
525
526 impl BluetoothSocketManager {
527 /// Constructs the IBluetooth implementation.
new( tx: Sender<Message>, runtime: Arc<Runtime>, intf: Arc<Mutex<BluetoothInterface>>, adapter: Arc<Mutex<Box<Bluetooth>>>, ) -> Self528 pub fn new(
529 tx: Sender<Message>,
530 runtime: Arc<Runtime>,
531 intf: Arc<Mutex<BluetoothInterface>>,
532 adapter: Arc<Mutex<Box<Bluetooth>>>,
533 ) -> Self {
534 let callbacks = Callbacks::new(tx.clone(), Message::SocketManagerCallbackDisconnected);
535 let socket_counter: u64 = 1000;
536 let connecting = HashMap::new();
537 let listening = HashMap::new();
538
539 BluetoothSocketManager {
540 callbacks,
541 connecting,
542 listening,
543 runtime,
544 sock: socket::BtSocket::new(&intf.lock().unwrap()),
545 socket_counter,
546 tx,
547 adapter,
548 admin_helper: Default::default(),
549 }
550 }
551
552 /// Check if there is any listening socket.
is_listening(&self) -> bool553 fn is_listening(&self) -> bool {
554 self.listening.values().any(|vs| !vs.is_empty())
555 }
556
557 // TODO(abps) - We need to save information about who the caller is so that
558 // we can pipe it down to the lower levels. This needs to be
559 // provided by the projection layer and is currently missing.
get_caller_uid(&self) -> i32560 fn get_caller_uid(&self) -> i32 {
561 0
562 }
563
564 /// Get the next available socket id.
next_socket_id(&mut self) -> SocketId565 fn next_socket_id(&mut self) -> SocketId {
566 let next = self.socket_counter;
567 self.socket_counter = next + 1;
568
569 next
570 }
571
572 /// Common handler for |sock->listen| call.
socket_listen( &mut self, mut socket_info: BluetoothServerSocket, cbid: CallbackId, ) -> SocketResult573 fn socket_listen(
574 &mut self,
575 mut socket_info: BluetoothServerSocket,
576 cbid: CallbackId,
577 ) -> SocketResult {
578 if let Some(uuid) = socket_info.uuid {
579 if !self.admin_helper.is_service_allowed(&uuid) {
580 log::debug!("service {} is blocked by admin policy", DisplayUuid(&uuid));
581 return SocketResult::new(BtStatus::AuthRejected, INVALID_SOCKET_ID);
582 }
583 if self
584 .listening
585 .iter()
586 .any(|(_, v)| v.iter().any(|s| s.uuid.map_or(false, |u| u == uuid)))
587 {
588 log::warn!("Service {} already exists", DisplayUuid(&uuid));
589 return SocketResult::new(BtStatus::SocketError, INVALID_SOCKET_ID);
590 }
591 }
592
593 // Create listener socket pair
594 let (mut status, result) = self.sock.listen(
595 socket_info.sock_type.clone(),
596 socket_info.name.as_ref().unwrap_or(&String::new()).clone(),
597 socket_info.uuid,
598 match socket_info.sock_type {
599 SocketType::Rfcomm => socket_info.channel.unwrap_or(DYNAMIC_CHANNEL),
600 SocketType::L2cap | SocketType::L2capLe => {
601 socket_info.psm.unwrap_or(DYNAMIC_PSM_NO_SDP)
602 }
603 _ => 0,
604 },
605 socket_info.flags,
606 self.get_caller_uid(),
607 );
608
609 // Put socket into listening list and return result.
610 match result {
611 Ok(file) => {
612 // Push new socket into listeners.
613 let id = self.next_socket_id();
614 socket_info.id = id;
615 let (runner_tx, runner_rx) = channel::<SocketRunnerActions>(10);
616 let uuid = socket_info.uuid;
617
618 // Push a listening task to local runtime to wait for device to
619 // start accepting or get closed.
620 let rpc_tx = self.tx.clone();
621
622 // If the stream can't be converted to filestream, fail early.
623 let stream = match file_to_unixstream(file) {
624 Some(v) => v,
625 None => {
626 log::debug!("Converting from file to unixstream failed");
627 return SocketResult::new(BtStatus::SocketError, INVALID_SOCKET_ID);
628 }
629 };
630
631 // We only send socket ready after we've read the channel out.
632 let listen_status = status;
633 let joinhandle = self.runtime.spawn(async move {
634 BluetoothSocketManager::listening_task(
635 cbid,
636 listen_status,
637 runner_rx,
638 socket_info,
639 stream,
640 rpc_tx,
641 )
642 .await;
643 });
644
645 // Keep track of active listener sockets.
646 self.listening
647 .entry(cbid)
648 .or_default()
649 .push(InternalListeningSocket::new(cbid, id, runner_tx, uuid, joinhandle));
650
651 // Update the connectable mode since the list of listening socket has changed.
652 self.adapter.lock().unwrap().set_socket_listening(true);
653
654 SocketResult::new(status, id)
655 }
656 Err(_) => {
657 // Bad file descriptor but underlying api says success.
658 if status == BtStatus::Success {
659 log::error!("Invalid socketpair but listen api succeeded.");
660 status = BtStatus::Fail;
661 }
662
663 log::error!("Failed to listen on {}. Status={:?}", socket_info, status);
664
665 SocketResult::new(status, INVALID_SOCKET_ID)
666 }
667 }
668 }
669
670 /// Common handler for |sock->connect| call.
socket_connect( &mut self, mut socket_info: BluetoothSocket, cbid: CallbackId, ) -> SocketResult671 fn socket_connect(
672 &mut self,
673 mut socket_info: BluetoothSocket,
674 cbid: CallbackId,
675 ) -> SocketResult {
676 if let Some(uuid) = socket_info.uuid {
677 if !self.admin_helper.is_service_allowed(&uuid) {
678 log::debug!("service {} is blocked by admin policy", DisplayUuid(&uuid));
679 return SocketResult::new(BtStatus::AuthRejected, INVALID_SOCKET_ID);
680 }
681 }
682
683 // Create connecting socket pair.
684 let (mut status, result) = self.sock.connect(
685 socket_info.remote_device.address,
686 socket_info.sock_type.clone(),
687 socket_info.uuid,
688 socket_info.port,
689 socket_info.flags,
690 self.get_caller_uid(),
691 );
692
693 // Put socket into connecting list and return result. Connecting sockets
694 // need to be listening for a completion event at which point they will
695 // send the ready signal.
696 match result {
697 Ok(file) => {
698 // Push new socket into connectors. These will wait until the
699 // connection complete event is seen and then emit an event for
700 // callbacks.
701 let id = self.next_socket_id();
702 socket_info.id = id;
703
704 // Push a connecting task to local runtime to wait for connection
705 // completion.
706 let tx = self.tx.clone();
707 let joinhandle = self.runtime.spawn(async move {
708 BluetoothSocketManager::connecting_task(
709 cbid,
710 id,
711 tx,
712 socket_info,
713 file_to_unixstream(file),
714 Duration::from_millis(CONNECT_COMPLETE_TIMEOUT_MS),
715 )
716 .await;
717 });
718
719 // Keep track of these futures in case they need to be cancelled due to callback
720 // disconnecting.
721 self.connecting
722 .entry(cbid)
723 .or_default()
724 .push(InternalConnectingSocket::new(cbid, id, joinhandle));
725
726 SocketResult::new(status, id)
727 }
728 Err(_) => {
729 if status == BtStatus::Success {
730 log::error!("Invalid socketpair but connect api succeeded.");
731 status = BtStatus::Fail;
732 }
733
734 log::error!("Failed to connect to {}. Status={:?}", socket_info, status);
735
736 SocketResult::new(status, INVALID_SOCKET_ID)
737 }
738 }
739 }
740
listening_task( cbid: CallbackId, listen_status: BtStatus, mut runner_rx: Receiver<SocketRunnerActions>, mut socket_info: BluetoothServerSocket, stream: UnixStream, rpc_tx: Sender<Message>, )741 async fn listening_task(
742 cbid: CallbackId,
743 listen_status: BtStatus,
744 mut runner_rx: Receiver<SocketRunnerActions>,
745 mut socket_info: BluetoothServerSocket,
746 stream: UnixStream,
747 rpc_tx: Sender<Message>,
748 ) {
749 let mut accepting: Option<JoinHandle<()>> = None;
750 let stream = Arc::new(stream);
751
752 let connection_timeout = Duration::from_millis(CONNECT_COMPLETE_TIMEOUT_MS);
753 // Wait for stream to be readable, then read channel. This is the first thing that must
754 // happen in the listening channel. If this fails, close the channel.
755 let mut channel_bytes = [0_u8; 4];
756 let mut status =
757 Self::wait_and_read_stream(connection_timeout, &stream, &mut channel_bytes).await;
758 let channel = i32::from_ne_bytes(channel_bytes);
759 if channel <= 0 {
760 status = BtStatus::SocketError;
761 }
762
763 // If we don't get a valid channel, consider the socket as closed.
764 if status != BtStatus::Success {
765 // First send the incoming socket ready signal and then closed. If we
766 // are unable to read the channel, the client needs to consider the
767 // socket as closed.
768 let _ = rpc_tx
769 .send(Message::SocketManagerActions(SocketActions::OnIncomingSocketReady(
770 cbid,
771 socket_info.clone(),
772 status,
773 )))
774 .await;
775 let _ = rpc_tx
776 .send(Message::SocketManagerActions(SocketActions::OnIncomingSocketClosed(
777 cbid,
778 socket_info.id,
779 BtStatus::Success,
780 )))
781 .await;
782
783 return;
784 }
785
786 match socket_info.sock_type {
787 SocketType::Rfcomm => socket_info.channel = Some(channel),
788 SocketType::L2cap | SocketType::L2capLe => socket_info.psm = Some(channel),
789
790 // Don't care about other types. We don't support them in this path.
791 _ => (),
792 };
793 // Notify via callbacks that this socket is ready to be listened to since we have the
794 // channel available now.
795 let (forwarded_socket, forwarded_status) = (socket_info.clone(), listen_status);
796 let _ = rpc_tx
797 .send(Message::SocketManagerActions(SocketActions::OnIncomingSocketReady(
798 cbid,
799 forwarded_socket,
800 forwarded_status,
801 )))
802 .await;
803
804 loop {
805 let m = match runner_rx.recv().await {
806 Some(v) => v,
807 None => {
808 break;
809 }
810 };
811
812 match m {
813 SocketRunnerActions::AcceptTimeout(socket_id, may_timeout) => {
814 // If the given socket id doesn't match, ignore the call.
815 if &socket_id != &socket_info.id {
816 continue;
817 }
818
819 // Cancel the previous future before continuing.
820 if let Some(ref handle) = accepting {
821 handle.abort();
822 }
823
824 let tx = rpc_tx.clone();
825 let cloned_socket_info = socket_info.clone();
826 let cstream = stream.clone();
827
828 // Replace the previous joinhandle.
829 accepting = Some(tokio::spawn(async move {
830 loop {
831 let readable = if let Some(timeout) = may_timeout {
832 match time::timeout(timeout, cstream.readable()).await {
833 // Result ok means ready to read.
834 Ok(r) => r.is_ok(),
835 // Timeout means we exit this future after sending.
836 Err(_) => false,
837 }
838 } else {
839 cstream.readable().await.is_ok()
840 };
841
842 // Anytime the readable future completes but isn't readable,
843 // we send a socket ready with a failed status message (you
844 // can try accepting again).
845 if !readable {
846 let _ = tx
847 .send(Message::SocketManagerActions(
848 SocketActions::OnIncomingSocketReady(
849 cbid,
850 cloned_socket_info,
851 BtStatus::Timeout,
852 ),
853 ))
854 .await;
855 break;
856 }
857
858 // Read the accepted socket information and use
859 // CMSG to grab the sockets also transferred over
860 // this socket.
861 let rawfd = cstream.as_raw_fd();
862 let socket_info_inner = cloned_socket_info.clone();
863 let sock: std::io::Result<Option<BluetoothSocket>> =
864 cstream.try_io(tokio::io::Interest::READABLE, || {
865 let mut data = [0; socket::CONNECT_COMPLETE_SIZE];
866 let iov = [IoVec::from_mut_slice(&mut data)];
867 let mut cspace = nix::cmsg_space!(RawFd);
868 let maybe_sock = match recvmsg(
869 rawfd,
870 &iov,
871 Some(&mut cspace),
872 nix::sys::socket::MsgFlags::MSG_DONTWAIT,
873 ) {
874 Ok(recv) => {
875 let fd = match recv.cmsgs().next() {
876 Some(ControlMessageOwned::ScmRights(fds)) => {
877 if fds.len() == 1 {
878 Some(fds[0])
879 } else {
880 log::error!(
881 "Unexpected number of fds given: {}",
882 fds.len()
883 );
884 None
885 }
886 }
887 _ => {
888 log::error!(
889 "Ancillary fds not found in connection."
890 );
891 None
892 }
893 };
894
895 return match socket::ConnectionComplete::try_from(
896 &data[0..socket::CONNECT_COMPLETE_SIZE],
897 ) {
898 Ok(cc) => {
899 let status = BtStatus::from(cc.status as u32);
900 let sock = socket_info_inner
901 .to_connecting_socket(cc, fd);
902
903 if status == BtStatus::Success
904 && sock.fd.is_some()
905 {
906 Ok(Some(sock))
907 } else {
908 Ok(None)
909 }
910 }
911 Err(_) => Ok(None),
912 };
913 }
914
915 Err(e) => {
916 if e == nix::errno::Errno::EAGAIN {
917 Err(std::io::Error::new(
918 std::io::ErrorKind::WouldBlock,
919 "Recvfrom is readable but would block on read",
920 ))
921 } else {
922 Ok(None)
923 }
924 }
925 };
926
927 maybe_sock
928 });
929
930 // If we returned an error for the above socket, then the recv failed.
931 // Just continue this loop.
932 if sock.is_err() {
933 continue;
934 }
935
936 match sock.unwrap_or(None) {
937 Some(s) => {
938 let _ = tx
939 .send(Message::SocketManagerActions(
940 SocketActions::OnHandleIncomingConnection(
941 cbid, s.id, s,
942 ),
943 ))
944 .await;
945 }
946 // Exit out of the accepting state here.
947 None => {
948 log::error!(
949 "Incoming connection failed to recv: {}",
950 cloned_socket_info
951 );
952
953 let _ = tx
954 .send(Message::SocketManagerActions(
955 SocketActions::OnIncomingSocketReady(
956 cbid,
957 cloned_socket_info,
958 BtStatus::SocketError,
959 ),
960 ))
961 .await;
962
963 break;
964 }
965 }
966 }
967 }));
968 }
969 SocketRunnerActions::Close(socket_id) => {
970 // Ignore requests where socket id doesn't match.
971 if &socket_id != &socket_info.id {
972 continue;
973 }
974
975 // First close any active accepting handle.
976 if let Some(ref handle) = accepting {
977 handle.abort();
978 }
979
980 // Notify RPC that we're closing.
981 let _ = rpc_tx
982 .send(Message::SocketManagerActions(SocketActions::OnIncomingSocketClosed(
983 cbid,
984 socket_info.id,
985 BtStatus::Success,
986 )))
987 .await;
988
989 // Now exit this task.
990 break;
991 }
992 }
993 }
994 }
995
996 /// Helper function that waits for given stream to be readable and then reads the stream into
997 /// the provided buffer.
wait_and_read_stream( timeout: Duration, stream: &UnixStream, buf: &mut [u8], ) -> BtStatus998 async fn wait_and_read_stream(
999 timeout: Duration,
1000 stream: &UnixStream,
1001 buf: &mut [u8],
1002 ) -> BtStatus {
1003 // Wait on the stream to be readable.
1004 match time::timeout(timeout, stream.readable()).await {
1005 Ok(inner) => match inner {
1006 Ok(()) => {}
1007 Err(_e) => {
1008 // Stream was not readable. This is usually due to some polling error.
1009 return BtStatus::SocketError;
1010 }
1011 },
1012 Err(_) => {
1013 // Timed out waiting for stream to be readable.
1014 return BtStatus::NotReady;
1015 }
1016 };
1017
1018 match stream.try_read(buf) {
1019 Ok(n) => {
1020 if n != buf.len() {
1021 return BtStatus::SocketError;
1022 }
1023 BtStatus::Success
1024 }
1025 _ => BtStatus::SocketError,
1026 }
1027 }
1028
1029 /// Task spawned on socket runtime to handle socket connections.
1030 ///
1031 /// This task will always result in a |SocketActions::OnOutgoingConnectionResult| message being
1032 /// 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, )1033 async fn connecting_task(
1034 cbid: CallbackId,
1035 socket_id: SocketId,
1036 tx: Sender<Message>,
1037 socket_info: BluetoothSocket,
1038 stream: Option<UnixStream>,
1039 connection_timeout: Duration,
1040 ) {
1041 // If the unixstream isn't available for this connection, immediately return
1042 // a failure.
1043 let stream = match stream {
1044 Some(s) => s,
1045 None => {
1046 let _ = tx
1047 .send(Message::SocketManagerActions(SocketActions::OnOutgoingConnectionResult(
1048 cbid,
1049 socket_id,
1050 BtStatus::SocketError,
1051 None,
1052 )))
1053 .await;
1054 return;
1055 }
1056 };
1057
1058 // Wait for stream to be readable, then read channel
1059 let mut channel_bytes = [0_u8; 4];
1060 let mut status =
1061 Self::wait_and_read_stream(connection_timeout, &stream, &mut channel_bytes).await;
1062 if i32::from_ne_bytes(channel_bytes) <= 0 {
1063 status = BtStatus::SocketError;
1064 }
1065 if status != BtStatus::Success {
1066 log::info!(
1067 "Connecting socket to {} failed while trying to read channel from stream",
1068 socket_info
1069 );
1070 let _ = tx
1071 .send(Message::SocketManagerActions(SocketActions::OnOutgoingConnectionResult(
1072 cbid, socket_id, status, None,
1073 )))
1074 .await;
1075 return;
1076 }
1077
1078 // Wait for stream to be readable, then read connect complete data
1079 let mut data = [0; socket::CONNECT_COMPLETE_SIZE];
1080 let status = Self::wait_and_read_stream(connection_timeout, &stream, &mut data).await;
1081 if status != BtStatus::Success {
1082 log::info!(
1083 "Connecting socket to {} failed while trying to read connect complete from stream",
1084 socket_info
1085 );
1086 let _ = tx
1087 .send(Message::SocketManagerActions(SocketActions::OnOutgoingConnectionResult(
1088 cbid, socket_id, status, None,
1089 )))
1090 .await;
1091 return;
1092 }
1093 match socket::ConnectionComplete::try_from(&data[0..socket::CONNECT_COMPLETE_SIZE]) {
1094 Ok(cc) => {
1095 let status = BtStatus::from(cc.status as u32);
1096 if status != BtStatus::Success {
1097 let _ = tx
1098 .send(Message::SocketManagerActions(
1099 SocketActions::OnOutgoingConnectionResult(
1100 cbid, socket_id, status, None,
1101 ),
1102 ))
1103 .await;
1104 } else {
1105 let mut sock = socket_info;
1106 sock.fd = Some(unixstream_to_file(stream));
1107 sock.port = cc.channel;
1108 sock.max_rx_size = cc.max_rx_packet_size.into();
1109 sock.max_tx_size = cc.max_tx_packet_size.into();
1110
1111 let _ = tx
1112 .send(Message::SocketManagerActions(
1113 SocketActions::OnOutgoingConnectionResult(
1114 cbid,
1115 socket_id,
1116 status,
1117 Some(sock),
1118 ),
1119 ))
1120 .await;
1121 }
1122 }
1123 Err(err) => {
1124 log::info!("Unable to parse ConnectionComplete: {}", err);
1125 let _ = tx
1126 .send(Message::SocketManagerActions(SocketActions::OnOutgoingConnectionResult(
1127 cbid,
1128 socket_id,
1129 BtStatus::SocketError,
1130 None,
1131 )))
1132 .await;
1133 }
1134 }
1135 }
1136
handle_actions(&mut self, action: SocketActions)1137 pub fn handle_actions(&mut self, action: SocketActions) {
1138 match action {
1139 SocketActions::OnIncomingSocketReady(cbid, server_socket, status) => {
1140 if let Some(callback) = self.callbacks.get_by_id_mut(cbid) {
1141 callback.on_incoming_socket_ready(server_socket, status);
1142 }
1143 }
1144
1145 SocketActions::OnIncomingSocketClosed(cbid, socket_id, status) => {
1146 if let Some(callback) = self.callbacks.get_by_id_mut(cbid) {
1147 callback.on_incoming_socket_closed(socket_id, status);
1148
1149 // Also make sure to remove the socket from listening list.
1150 self.listening
1151 .entry(cbid)
1152 .and_modify(|v| v.retain(|s| s.socket_id != socket_id));
1153
1154 if !self.is_listening() {
1155 // Update the connectable mode since the list of listening socket has changed.
1156 self.adapter.lock().unwrap().set_socket_listening(false);
1157 }
1158 }
1159 }
1160
1161 SocketActions::OnHandleIncomingConnection(cbid, socket_id, socket) => {
1162 if let Some(callback) = self.callbacks.get_by_id_mut(cbid) {
1163 callback.on_handle_incoming_connection(socket_id, socket);
1164 }
1165 }
1166
1167 SocketActions::OnOutgoingConnectionResult(cbid, socket_id, status, socket) => {
1168 if let Some(callback) = self.callbacks.get_by_id_mut(cbid) {
1169 callback.on_outgoing_connection_result(socket_id, status, socket);
1170
1171 // Also make sure to remove the socket from connecting list.
1172 self.connecting
1173 .entry(cbid)
1174 .and_modify(|v| v.retain(|s| s.socket_id != socket_id));
1175 }
1176 }
1177
1178 SocketActions::DisconnectAll(addr) => {
1179 self.sock.disconnect_all(addr);
1180 }
1181 }
1182 }
1183
1184 /// Close Rfcomm sockets whose UUID is not allowed by policy
handle_admin_policy_changed(&mut self, admin_helper: BluetoothAdminPolicyHelper)1185 pub(crate) fn handle_admin_policy_changed(&mut self, admin_helper: BluetoothAdminPolicyHelper) {
1186 self.admin_helper = admin_helper;
1187 let forbidden_sockets = self
1188 .listening
1189 .values()
1190 .flatten()
1191 .filter(|sock| {
1192 sock.uuid
1193 // Don't need to close L2cap socket (indicated by no uuid).
1194 .map_or(false, |uuid| !self.admin_helper.is_service_allowed(&uuid))
1195 })
1196 .map(|sock| (sock.socket_id, sock.tx.clone(), sock.uuid.unwrap()))
1197 .collect::<Vec<(u64, Sender<SocketRunnerActions>, Uuid)>>();
1198
1199 self.runtime.spawn(async move {
1200 for (id, tx, uuid) in forbidden_sockets {
1201 log::debug!(
1202 "socket id {} is not allowed by admin policy due to uuid {}, closing",
1203 id,
1204 DisplayUuid(&uuid)
1205 );
1206 let _ = tx.send(SocketRunnerActions::Close(id)).await;
1207 }
1208 });
1209 }
1210
remove_callback(&mut self, callback: CallbackId)1211 pub fn remove_callback(&mut self, callback: CallbackId) {
1212 // Remove any associated futures and sockets waiting to accept.
1213 self.connecting.remove(&callback).map(|sockets| {
1214 for s in sockets {
1215 s.joinhandle.abort();
1216 }
1217 });
1218 self.listening.remove(&callback).map(|sockets| {
1219 for s in sockets {
1220 if s.joinhandle.is_finished() {
1221 continue;
1222 }
1223 let tx = s.tx.clone();
1224 let id = s.socket_id;
1225 self.runtime.spawn(async move {
1226 let _ = tx.send(SocketRunnerActions::Close(id)).await;
1227 });
1228 }
1229 });
1230
1231 if !self.is_listening() {
1232 // Update the connectable mode since the list of listening socket has changed.
1233 self.adapter.lock().unwrap().set_socket_listening(false);
1234 }
1235
1236 self.callbacks.remove_callback(callback);
1237 }
1238
1239 // Send MSC command to the peer. ONLY FOR QUALIFICATION USE.
1240 // libbluetooth auto starts the control request only when it is the client.
1241 // This function allows the host to start the control request while as a server.
rfcomm_send_msc(&mut self, dlci: u8, addr: RawAddress)1242 pub fn rfcomm_send_msc(&mut self, dlci: u8, addr: RawAddress) {
1243 if self.sock.send_msc(dlci, addr) != BtStatus::Success {
1244 log::warn!("Failed to start control request");
1245 }
1246 }
1247 }
1248
1249 impl IBluetoothSocketManager for BluetoothSocketManager {
register_callback( &mut self, callback: Box<dyn IBluetoothSocketManagerCallbacks + Send>, ) -> CallbackId1250 fn register_callback(
1251 &mut self,
1252 callback: Box<dyn IBluetoothSocketManagerCallbacks + Send>,
1253 ) -> CallbackId {
1254 self.callbacks.add_callback(callback)
1255 }
1256
unregister_callback(&mut self, callback: CallbackId) -> bool1257 fn unregister_callback(&mut self, callback: CallbackId) -> bool {
1258 self.callbacks.remove_callback(callback)
1259 }
1260
listen_using_insecure_l2cap_channel(&mut self, callback: CallbackId) -> SocketResult1261 fn listen_using_insecure_l2cap_channel(&mut self, callback: CallbackId) -> SocketResult {
1262 if self.callbacks.get_by_id(callback).is_none() {
1263 return SocketResult::new(BtStatus::NotReady, INVALID_SOCKET_ID);
1264 }
1265
1266 let socket_info = BluetoothServerSocket::make_l2cap_channel(socket::SOCK_FLAG_NONE, false);
1267 self.socket_listen(socket_info, callback)
1268 }
1269
listen_using_insecure_l2cap_le_channel(&mut self, callback: CallbackId) -> SocketResult1270 fn listen_using_insecure_l2cap_le_channel(&mut self, callback: CallbackId) -> SocketResult {
1271 if self.callbacks.get_by_id(callback).is_none() {
1272 return SocketResult::new(BtStatus::NotReady, INVALID_SOCKET_ID);
1273 }
1274
1275 let socket_info = BluetoothServerSocket::make_l2cap_channel(socket::SOCK_FLAG_NONE, true);
1276 self.socket_listen(socket_info, callback)
1277 }
1278
listen_using_l2cap_channel(&mut self, callback: CallbackId) -> SocketResult1279 fn listen_using_l2cap_channel(&mut self, callback: CallbackId) -> SocketResult {
1280 if self.callbacks.get_by_id(callback).is_none() {
1281 return SocketResult::new(BtStatus::NotReady, INVALID_SOCKET_ID);
1282 }
1283
1284 let socket_info =
1285 BluetoothServerSocket::make_l2cap_channel(socket::SOCK_META_FLAG_SECURE, false);
1286 self.socket_listen(socket_info, callback)
1287 }
1288
listen_using_l2cap_le_channel(&mut self, callback: CallbackId) -> SocketResult1289 fn listen_using_l2cap_le_channel(&mut self, callback: CallbackId) -> 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 =
1295 BluetoothServerSocket::make_l2cap_channel(socket::SOCK_META_FLAG_SECURE, true);
1296 self.socket_listen(socket_info, callback)
1297 }
1298
listen_using_insecure_rfcomm_with_service_record( &mut self, callback: CallbackId, name: String, uuid: Uuid, ) -> SocketResult1299 fn listen_using_insecure_rfcomm_with_service_record(
1300 &mut self,
1301 callback: CallbackId,
1302 name: String,
1303 uuid: Uuid,
1304 ) -> SocketResult {
1305 if self.callbacks.get_by_id(callback).is_none() {
1306 return SocketResult::new(BtStatus::NotReady, INVALID_SOCKET_ID);
1307 }
1308
1309 let socket_info =
1310 BluetoothServerSocket::make_default_rfcomm_channel(socket::SOCK_FLAG_NONE, name, uuid);
1311 self.socket_listen(socket_info, callback)
1312 }
1313
listen_using_rfcomm_with_service_record( &mut self, callback: CallbackId, name: String, uuid: Uuid, ) -> SocketResult1314 fn listen_using_rfcomm_with_service_record(
1315 &mut self,
1316 callback: CallbackId,
1317 name: String,
1318 uuid: Uuid,
1319 ) -> SocketResult {
1320 if self.callbacks.get_by_id(callback).is_none() {
1321 return SocketResult::new(BtStatus::NotReady, INVALID_SOCKET_ID);
1322 }
1323
1324 let socket_info = BluetoothServerSocket::make_default_rfcomm_channel(
1325 socket::SOCK_META_FLAG_SECURE,
1326 name,
1327 uuid,
1328 );
1329
1330 self.socket_listen(socket_info, callback)
1331 }
1332
listen_using_rfcomm( &mut self, callback: CallbackId, channel: Option<i32>, application_uuid: Option<Uuid>, name: Option<String>, flags: Option<i32>, ) -> SocketResult1333 fn listen_using_rfcomm(
1334 &mut self,
1335 callback: CallbackId,
1336 channel: Option<i32>,
1337 application_uuid: Option<Uuid>,
1338 name: Option<String>,
1339 flags: Option<i32>,
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 flags = match flags {
1346 Some(flags) => flags,
1347 None => socket::SOCK_FLAG_NONE,
1348 };
1349
1350 self.socket_listen(
1351 BluetoothServerSocket::make_rfcomm_channel(flags, name, channel, application_uuid),
1352 callback,
1353 )
1354 }
1355
create_insecure_l2cap_channel( &mut self, callback: CallbackId, device: BluetoothDevice, psm: i32, ) -> SocketResult1356 fn create_insecure_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_FLAG_NONE, device, psm, false);
1368 self.socket_connect(socket_info, callback)
1369 }
1370
create_insecure_l2cap_le_channel( &mut self, callback: CallbackId, device: BluetoothDevice, psm: i32, ) -> SocketResult1371 fn create_insecure_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_FLAG_NONE, device, psm, true);
1383 self.socket_connect(socket_info, callback)
1384 }
1385
create_l2cap_channel( &mut self, callback: CallbackId, device: BluetoothDevice, psm: i32, ) -> SocketResult1386 fn create_l2cap_channel(
1387 &mut self,
1388 callback: CallbackId,
1389 device: BluetoothDevice,
1390 psm: i32,
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_l2cap_channel(socket::SOCK_META_FLAG_SECURE, device, psm, false);
1398 self.socket_connect(socket_info, callback)
1399 }
1400
create_l2cap_le_channel( &mut self, callback: CallbackId, device: BluetoothDevice, psm: i32, ) -> SocketResult1401 fn create_l2cap_le_channel(
1402 &mut self,
1403 callback: CallbackId,
1404 device: BluetoothDevice,
1405 psm: i32,
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_l2cap_channel(socket::SOCK_META_FLAG_SECURE, device, psm, true);
1413 self.socket_connect(socket_info, callback)
1414 }
1415
create_insecure_rfcomm_socket_to_service_record( &mut self, callback: CallbackId, device: BluetoothDevice, uuid: Uuid, ) -> SocketResult1416 fn create_insecure_rfcomm_socket_to_service_record(
1417 &mut self,
1418 callback: CallbackId,
1419 device: BluetoothDevice,
1420 uuid: Uuid,
1421 ) -> SocketResult {
1422 if self.callbacks.get_by_id(callback).is_none() {
1423 return SocketResult::new(BtStatus::NotReady, INVALID_SOCKET_ID);
1424 }
1425
1426 let socket_info =
1427 BluetoothSocket::make_rfcomm_channel(socket::SOCK_FLAG_NONE, device, uuid);
1428 self.socket_connect(socket_info, callback)
1429 }
1430
create_rfcomm_socket_to_service_record( &mut self, callback: CallbackId, device: BluetoothDevice, uuid: Uuid, ) -> SocketResult1431 fn create_rfcomm_socket_to_service_record(
1432 &mut self,
1433 callback: CallbackId,
1434 device: BluetoothDevice,
1435 uuid: Uuid,
1436 ) -> SocketResult {
1437 if self.callbacks.get_by_id(callback).is_none() {
1438 return SocketResult::new(BtStatus::NotReady, INVALID_SOCKET_ID);
1439 }
1440
1441 let socket_info =
1442 BluetoothSocket::make_rfcomm_channel(socket::SOCK_META_FLAG_SECURE, device, uuid);
1443 self.socket_connect(socket_info, callback)
1444 }
1445
accept(&mut self, callback: CallbackId, id: SocketId, timeout_ms: Option<u32>) -> BtStatus1446 fn accept(&mut self, callback: CallbackId, id: SocketId, timeout_ms: Option<u32>) -> BtStatus {
1447 match self.listening.get(&callback) {
1448 Some(v) => {
1449 if let Some(found) = v.iter().find(|item| item.socket_id == id) {
1450 let tx = found.tx.clone();
1451 let timeout_duration = timeout_ms.map(|t| Duration::from_millis(t.into()));
1452 self.runtime.spawn(async move {
1453 let _ =
1454 tx.send(SocketRunnerActions::AcceptTimeout(id, timeout_duration)).await;
1455 });
1456
1457 return BtStatus::Success;
1458 }
1459 }
1460 None => (),
1461 }
1462
1463 BtStatus::InvalidParam
1464 }
1465
close(&mut self, callback: CallbackId, id: SocketId) -> BtStatus1466 fn close(&mut self, callback: CallbackId, id: SocketId) -> BtStatus {
1467 match self.listening.get(&callback) {
1468 Some(v) => {
1469 if let Some(found) = v.iter().find(|item| item.socket_id == id) {
1470 let tx = found.tx.clone();
1471 self.runtime.spawn(async move {
1472 let _ = tx.send(SocketRunnerActions::Close(id)).await;
1473 });
1474
1475 return BtStatus::Success;
1476 }
1477 }
1478 None => (),
1479 }
1480
1481 BtStatus::InvalidParam
1482 }
1483 }
1484