pub struct SocketAddr {
pub addr: Address,
pub addr_type: AddressType,
pub psm: u16,
pub cid: u16,
}l2cap only.Expand description
An L2CAP socket address.
Fields§
§addr: AddressDevice address.
When listening or binding, specify Address::any for any local adapter address.
addr_type: AddressTypeDevice address type.
psm: u16Protocol service multiplexor (PSM).
For classic Bluetooth (BR/EDR), listening on a PSM below PSM_BR_EDR_DYN_START
requires the CAP_NET_BIND_SERVICE capability.
The PSM must be odd and the last bit of the upper byte must be zero, i.e.
it must follow the bit pattern xxxxxxx0_xxxxxxx1 where x may be 1 or 0.
For Bluetooth Low Energy, listening on a PSM below PSM_LE_DYN_START
requires the CAP_NET_BIND_SERVICE capability.
The highest allowed PSM for LE is PSM_LE_MAX.
Set to 0 for listening to assign an available PSM.
cid: u16Connection identifier (CID).
Should be set to 0.
Implementations§
Source§impl SocketAddr
impl SocketAddr
Sourcepub const fn new(addr: Address, addr_type: AddressType, psm: u16) -> Self
pub const fn new(addr: Address, addr_type: AddressType, psm: u16) -> Self
Creates a new L2CAP socket address.
Examples found in repository?
14async fn main() -> bluer::Result<()> {
15 env_logger::init();
16 let session = bluer::Session::new().await?;
17 let adapter = session.default_adapter().await?;
18 adapter.set_powered(true).await?;
19
20 let args: Vec<_> = env::args().collect();
21 if args.len() != 2 {
22 eprintln!("Specify target Bluetooth address as argument");
23 exit(1);
24 }
25
26 let target_addr: Address = args[1].parse().expect("invalid address");
27 let target_sa = SocketAddr::new(target_addr, AddressType::LePublic, PSM);
28
29 println!("Connecting to {:?}", &target_sa);
30 let mut stream = Stream::connect(target_sa).await.expect("connection failed");
31 println!("Local address: {:?}", stream.as_ref().local_addr()?);
32 println!("Remote address: {:?}", stream.peer_addr()?);
33 println!("Send MTU: {:?}", stream.as_ref().send_mtu());
34 println!("Recv MTU: {}", stream.as_ref().recv_mtu()?);
35 println!("Security: {:?}", stream.as_ref().security()?);
36 println!("Flow control: {:?}", stream.as_ref().flow_control());
37
38 println!("\nReceiving hello");
39 let mut hello_buf = [0u8; HELLO_MSG.len()];
40 stream.read_exact(&mut hello_buf).await.expect("read failed");
41 println!("Received: {}", String::from_utf8_lossy(&hello_buf));
42 if hello_buf != HELLO_MSG {
43 panic!("Wrong hello message");
44 }
45
46 let (mut rh, mut wh) = stream.into_split();
47 let mut rng = rand::thread_rng();
48 for i in 0..15 {
49 let len = rng.gen_range(0..50000);
50 let data: Vec<u8> = (0..len).map(|_| rng.gen()).collect();
51
52 println!("\nTest iteration {i} with data size {len}");
53
54 // We must read back the data while sending, otherwise the connection
55 // buffer will overrun and we will lose data.
56 let read_task = tokio::spawn(async move {
57 let mut echo_buf = vec![0u8; len];
58 let res = match rh.read_exact(&mut echo_buf).await {
59 Ok(_) => Ok(echo_buf),
60 Err(err) => Err(err),
61 };
62 (rh, res)
63 });
64
65 // Note that write_all will automatically split the buffer into
66 // multiple writes of MTU size.
67 wh.write_all(&data).await.expect("write failed");
68
69 println!("Waiting for echo");
70 let (rh_back, res) = read_task.await.unwrap();
71 rh = rh_back;
72 let echo_buf = res.expect("read failed");
73
74 if echo_buf != data {
75 panic!("Echoed data does not match sent data");
76 }
77 println!("Data matches");
78 }
79
80 println!("Done");
81 Ok(())
82}More examples
18async fn main() -> bluer::Result<()> {
19 env_logger::init();
20 let session = bluer::Session::new().await?;
21 let adapter = session.default_adapter().await?;
22 adapter.set_powered(true).await?;
23 let adapter_addr = adapter.address().await?;
24 let adapter_addr_type = adapter.address_type().await?;
25
26 // Advertising is necessary for device to be connectable.
27 println!(
28 "Advertising on Bluetooth adapter {} with {} address {}",
29 adapter.name(),
30 &adapter_addr_type,
31 &adapter_addr
32 );
33 let le_advertisement = Advertisement {
34 service_uuids: vec![SERVICE_UUID].into_iter().collect(),
35 discoverable: Some(true),
36 local_name: Some("l2cap_server".to_string()),
37 ..Default::default()
38 };
39 let adv_handle = adapter.advertise(le_advertisement).await?;
40
41 let local_sa = SocketAddr::new(adapter_addr, adapter_addr_type, PSM);
42 let listener = StreamListener::bind(local_sa).await?;
43
44 println!("Listening on PSM {}. Press enter to quit.", listener.as_ref().local_addr()?.psm);
45 let stdin = BufReader::new(tokio::io::stdin());
46 let mut lines = stdin.lines();
47
48 loop {
49 println!("\nWaiting for connection...");
50
51 let (mut stream, sa) = tokio::select! {
52 l = listener.accept() => {
53 match l {
54 Ok(v) => v,
55 Err(err) => {
56 println!("Accepting connection failed: {}", &err);
57 continue;
58 }}
59 },
60 _ = lines.next_line() => break,
61 };
62 let recv_mtu = stream.as_ref().recv_mtu()?;
63
64 println!("Accepted connection from {:?} with receive MTU {} bytes", &sa, &recv_mtu);
65
66 println!("Sending hello");
67 if let Err(err) = stream.write_all(HELLO_MSG).await {
68 println!("Write failed: {}", &err);
69 continue;
70 }
71
72 let mut n = 0;
73 loop {
74 n += 1;
75
76 // Vary buffer size between MTU and smaller value to test
77 // partial reads.
78 let buf_size = if n % 5 == 0 { recv_mtu - 70 } else { recv_mtu };
79 let mut buf = vec![0; buf_size as _];
80
81 let n = match stream.read(&mut buf).await {
82 Ok(0) => {
83 println!("Stream ended");
84 break;
85 }
86 Ok(n) => n,
87 Err(err) => {
88 println!("Read failed: {}", &err);
89 continue;
90 }
91 };
92 let buf = &buf[..n];
93
94 println!("Echoing {} bytes", buf.len());
95 if let Err(err) = stream.write_all(buf).await {
96 println!("Write failed: {}", &err);
97 continue;
98 }
99 }
100 }
101
102 println!("Removing advertisement");
103 drop(adv_handle);
104 sleep(Duration::from_secs(1)).await;
105
106 Ok(())
107}Sourcepub const fn any_br_edr() -> Self
pub const fn any_br_edr() -> Self
When specified to Socket::bind binds to any local adapter address using classic Bluetooth (BR/EDR) and a dynamically allocated PSM.
Sourcepub const fn any_le() -> Self
pub const fn any_le() -> Self
When specified to Socket::bind binds to any public, local adapter address using Bluetooth Low Energy and a dynamically allocated PSM.
Trait Implementations§
Source§impl Clone for SocketAddr
impl Clone for SocketAddr
Source§fn clone(&self) -> SocketAddr
fn clone(&self) -> SocketAddr
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for SocketAddr
impl Debug for SocketAddr
Source§impl Default for SocketAddr
impl Default for SocketAddr
Source§fn default() -> SocketAddr
fn default() -> SocketAddr
Source§impl<'de> Deserialize<'de> for SocketAddr
impl<'de> Deserialize<'de> for SocketAddr
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl Hash for SocketAddr
impl Hash for SocketAddr
Source§impl Ord for SocketAddr
impl Ord for SocketAddr
Source§fn cmp(&self, other: &SocketAddr) -> Ordering
fn cmp(&self, other: &SocketAddr) -> Ordering
1.21.0 (const: unstable) · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
Source§impl PartialEq for SocketAddr
impl PartialEq for SocketAddr
Source§fn eq(&self, other: &SocketAddr) -> bool
fn eq(&self, other: &SocketAddr) -> bool
self and other values to be equal, and is used by ==.