pub struct Socket { /* private fields */ }
rfcomm
only.Expand description
Implementations§
source§impl Socket
impl Socket
sourcepub fn listen(self, backlog: u32) -> Result<Listener>
pub fn listen(self, backlog: u32) -> Result<Listener>
Convert the socket into a Listener.
backlog
defines the maximum number of pending connections are queued by the operating system
at any given time.
This will not register an SDP record for this channel. Register a Bluetooth RFCOMM profile instead, if you need a service record.
sourcepub async fn connect(self, sa: SocketAddr) -> Result<Stream>
pub async fn connect(self, sa: SocketAddr) -> Result<Stream>
Establish a stream connection with a peer at the specified socket address.
This requires knowledge of the channel number. Register a Bluetooth RFCOMM profile, if you need to discover the channel number using a service record.
sourcepub fn bind(&self, sa: SocketAddr) -> Result<()>
pub fn bind(&self, sa: SocketAddr) -> Result<()>
Bind the socket to the given address.
sourcepub fn local_addr(&self) -> Result<SocketAddr>
pub fn local_addr(&self) -> Result<SocketAddr>
Get the local address of this socket.
Examples found in repository?
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
async fn main() -> bluer::Result<()> {
env_logger::init();
let session = bluer::Session::new().await?;
let adapter = session.default_adapter().await?;
adapter.set_powered(true).await?;
adapter.set_discoverable(true).await?;
let adapter_addr = adapter.address().await?;
let local_sa = SocketAddr::new(adapter_addr, CHANNEL);
let listener = Listener::bind(local_sa).await?;
println!(
"Listening on {} channel {}. Press enter to quit.",
listener.as_ref().local_addr()?.addr,
listener.as_ref().local_addr()?.channel
);
let stdin = BufReader::new(tokio::io::stdin());
let mut lines = stdin.lines();
loop {
println!("\nWaiting for connection...");
let (mut stream, sa) = tokio::select! {
l = listener.accept() => {
match l {
Ok(v) => v,
Err(err) => {
println!("Accepting connection failed: {}", &err);
continue;
}}
},
_ = lines.next_line() => break,
};
println!("Accepted connection from {:?}", &sa);
println!("Sending hello");
if let Err(err) = stream.write_all(HELLO_MSG).await {
println!("Write failed: {}", &err);
continue;
}
loop {
let buf_size = 1024;
let mut buf = vec![0; buf_size as _];
let n = match stream.read(&mut buf).await {
Ok(0) => {
println!("Stream ended");
break;
}
Ok(n) => n,
Err(err) => {
println!("Read failed: {}", &err);
break;
}
};
let buf = &buf[..n];
println!("Echoing {} bytes", buf.len());
if let Err(err) = stream.write_all(buf).await {
println!("Write failed: {}", &err);
continue;
}
}
}
Ok(())
}
More examples
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
async fn main() -> bluer::Result<()> {
env_logger::init();
let session = bluer::Session::new().await?;
let adapter = session.default_adapter().await?;
adapter.set_powered(true).await?;
let args: Vec<_> = env::args().collect();
if args.len() != 2 {
eprintln!("Specify target Bluetooth address as argument");
exit(1);
}
let target_addr: Address = args[1].parse().expect("invalid address");
let target_sa = SocketAddr::new(target_addr, CHANNEL);
println!("Connecting to {:?}", &target_sa);
let mut stream = Stream::connect(target_sa).await.expect("connection failed");
println!("Local address: {:?}", stream.as_ref().local_addr()?);
println!("Remote address: {:?}", stream.peer_addr()?);
println!("Security: {:?}", stream.as_ref().security()?);
println!("\nReceiving hello");
let mut hello_buf = [0u8; HELLO_MSG.len()];
stream.read_exact(&mut hello_buf).await.expect("read failed");
println!("Received: {}", String::from_utf8_lossy(&hello_buf));
if hello_buf != HELLO_MSG {
panic!("Wrong hello message");
}
let (mut rh, mut wh) = stream.into_split();
let mut rng = rand::thread_rng();
for i in 0..15 {
let len = rng.gen_range(0..50000);
let data: Vec<u8> = (0..len).map(|_| rng.gen()).collect();
println!("\nTest iteration {i} with data size {len}");
// We must read back the data while sending, otherwise the connection
// buffer will overrun and we will lose data.
let read_task = tokio::spawn(async move {
let mut echo_buf = vec![0u8; len];
let res = match rh.read_exact(&mut echo_buf).await {
Ok(_) => Ok(echo_buf),
Err(err) => Err(err),
};
(rh, res)
});
// Note that write_all will automatically split the buffer into
// multiple writes of MTU size.
wh.write_all(&data).await.expect("write failed");
println!("Waiting for echo");
let (rh_back, res) = read_task.await.unwrap();
rh = rh_back;
let echo_buf = res.expect("read failed");
if echo_buf != data {
panic!("Echoed data does not match sent data");
}
println!("Data matches");
}
println!("Done");
Ok(())
}
sourcepub fn security(&self) -> Result<Security>
pub fn security(&self) -> Result<Security>
Get socket security.
This corresponds to the BT_SECURITY
socket option.
Examples found in repository?
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
async fn main() -> bluer::Result<()> {
env_logger::init();
let session = bluer::Session::new().await?;
let adapter = session.default_adapter().await?;
adapter.set_powered(true).await?;
let args: Vec<_> = env::args().collect();
if args.len() != 2 {
eprintln!("Specify target Bluetooth address as argument");
exit(1);
}
let target_addr: Address = args[1].parse().expect("invalid address");
let target_sa = SocketAddr::new(target_addr, CHANNEL);
println!("Connecting to {:?}", &target_sa);
let mut stream = Stream::connect(target_sa).await.expect("connection failed");
println!("Local address: {:?}", stream.as_ref().local_addr()?);
println!("Remote address: {:?}", stream.peer_addr()?);
println!("Security: {:?}", stream.as_ref().security()?);
println!("\nReceiving hello");
let mut hello_buf = [0u8; HELLO_MSG.len()];
stream.read_exact(&mut hello_buf).await.expect("read failed");
println!("Received: {}", String::from_utf8_lossy(&hello_buf));
if hello_buf != HELLO_MSG {
panic!("Wrong hello message");
}
let (mut rh, mut wh) = stream.into_split();
let mut rng = rand::thread_rng();
for i in 0..15 {
let len = rng.gen_range(0..50000);
let data: Vec<u8> = (0..len).map(|_| rng.gen()).collect();
println!("\nTest iteration {i} with data size {len}");
// We must read back the data while sending, otherwise the connection
// buffer will overrun and we will lose data.
let read_task = tokio::spawn(async move {
let mut echo_buf = vec![0u8; len];
let res = match rh.read_exact(&mut echo_buf).await {
Ok(_) => Ok(echo_buf),
Err(err) => Err(err),
};
(rh, res)
});
// Note that write_all will automatically split the buffer into
// multiple writes of MTU size.
wh.write_all(&data).await.expect("write failed");
println!("Waiting for echo");
let (rh_back, res) = read_task.await.unwrap();
rh = rh_back;
let echo_buf = res.expect("read failed");
if echo_buf != data {
panic!("Echoed data does not match sent data");
}
println!("Data matches");
}
println!("Done");
Ok(())
}
sourcepub fn set_security(&self, security: Security) -> Result<()>
pub fn set_security(&self, security: Security) -> Result<()>
Set socket security.
This corresponds to the BT_SECURITY
socket option.
sourcepub fn recv_buffer(&self) -> Result<i32>
pub fn recv_buffer(&self) -> Result<i32>
Gets the maximum socket receive buffer in bytes.
This corresponds to the SO_RCVBUF
socket option.
sourcepub fn set_recv_buffer(&self, recv_buffer: i32) -> Result<()>
pub fn set_recv_buffer(&self, recv_buffer: i32) -> Result<()>
Sets the maximum socket receive buffer in bytes.
This corresponds to the SO_RCVBUF
socket option.
sourcepub fn conn_info(&self) -> Result<ConnInfo>
pub fn conn_info(&self) -> Result<ConnInfo>
Gets the RFCOMM socket connection information.
This corresponds to the RFCOMM_CONNINFO
socket option.
sourcepub fn is_master(&self) -> Result<bool>
pub fn is_master(&self) -> Result<bool>
Gets whether the RFCOMM socket is the master.
This corresponds to the RFCOMM_LM
socket option and option bit RFCOMM_LM_MASTER
.
sourcepub fn set_master(&self, master: bool) -> Result<()>
pub fn set_master(&self, master: bool) -> Result<()>
sets whether the RFCOMM socket is the master.
This corresponds to the RFCOMM_LM
socket option and option bit RFCOMM_LM_MASTER
.
sourcepub fn input_buffer(&self) -> Result<u32>
pub fn input_buffer(&self) -> Result<u32>
Get the number of bytes in the input buffer.
This corresponds to the TIOCINQ
IOCTL.
sourcepub fn output_buffer(&self) -> Result<u32>
pub fn output_buffer(&self) -> Result<u32>
Get the number of bytes in the output buffer.
This corresponds to the TIOCOUTQ
IOCTL.
sourcepub fn create_tty(&self, dev_id: i16) -> Result<i16>
pub fn create_tty(&self, dev_id: i16) -> Result<i16>
Creates a TTY (virtual serial port) for this RFCOMM connection.
Set dev_id
to -1 to automatically allocate an id.
Returns the allocated device id.
This corresponds to the RFCOMMCREATEDEV
IOCTL.
sourcepub fn release_tty(dev_id: i16) -> Result<()>
pub fn release_tty(dev_id: i16) -> Result<()>
Releases a TTY (virtual serial port) for this RFCOMM connection.
This corresponds to the RFCOMMRELEASEDEV
IOCTL.
sourcepub unsafe fn from_raw_fd(fd: RawFd) -> Result<Self>
pub unsafe fn from_raw_fd(fd: RawFd) -> Result<Self>
Constructs a new Socket from the given raw file descriptor.
The file descriptor must have been set to non-blocking mode.
This function consumes ownership of the specified file descriptor. The returned object will take responsibility for closing it when the object goes out of scope.
§Safety
If the passed file descriptor is invalid, undefined behavior may occur.
Trait Implementations§
source§impl FromRawFd for Socket
impl FromRawFd for Socket
source§unsafe fn from_raw_fd(fd: RawFd) -> Self
unsafe fn from_raw_fd(fd: RawFd) -> Self
Constructs a new instance of Self
from the given raw file
descriptor.
The file descriptor must have been set to non-blocking mode.
§Panics
Panics when the conversion fails. Use Socket::from_raw_fd for a non-panicking variant.