Struct bluer::gatt::CharacteristicReader
source · pub struct CharacteristicReader { /* private fields */ }
Available on crate feature
bluetoothd
only.Expand description
Streams data from a characteristic with low overhead.
Implementations§
source§impl CharacteristicReader
impl CharacteristicReader
sourcepub fn adapter_name(&self) -> &str
pub fn adapter_name(&self) -> &str
Name of adapter.
sourcepub fn device_address(&self) -> Address
pub fn device_address(&self) -> Address
Address of remote device.
sourcepub fn mtu(&self) -> usize
pub fn mtu(&self) -> usize
Maximum transmission unit.
Examples found in repository?
examples/gatt_client.rs (line 121)
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
async fn exercise_characteristic(char: &Characteristic) -> Result<()> {
println!(" Characteristic flags: {:?}", char.flags().await?);
sleep(Duration::from_secs(1)).await;
if char.flags().await?.read {
println!(" Reading characteristic value");
let value = char.read().await?;
println!(" Read value: {:x?}", &value);
sleep(Duration::from_secs(1)).await;
}
let data = vec![0xee, 0x11, 0x11, 0x0];
println!(" Writing characteristic value {:x?} using function call", &data);
char.write(&data).await?;
sleep(Duration::from_secs(1)).await;
if char.flags().await?.read {
let value = char.read().await?;
println!(" Read value back: {:x?}", &value);
sleep(Duration::from_secs(1)).await;
}
println!(" Obtaining write IO");
let mut write_io = char.write_io().await?;
println!(" Write IO obtained");
println!(" Writing characteristic value {:x?} five times using IO", &data);
for _ in 0..5u8 {
let written = write_io.write(&data).await?;
println!(" {written} bytes written");
}
println!(" Closing write IO");
drop(write_io);
sleep(Duration::from_secs(1)).await;
println!(" Starting notification session");
{
let notify = char.notify().await?;
pin_mut!(notify);
for _ in 0..5u8 {
match notify.next().await {
Some(value) => {
println!(" Notification value: {:x?}", &value);
}
None => {
println!(" Notification session was terminated");
}
}
}
println!(" Stopping notification session");
}
sleep(Duration::from_secs(1)).await;
println!(" Obtaining notification IO");
let mut notify_io = char.notify_io().await?;
println!(" Obtained notification IO with MTU={}", notify_io.mtu());
for _ in 0..5u8 {
let mut buf = vec![0; notify_io.mtu()];
match notify_io.read(&mut buf).await {
Ok(0) => {
println!(" Notification IO end of stream");
break;
}
Ok(read) => {
println!(" Notified with {} bytes: {:x?}", read, &buf[0..read]);
}
Err(err) => {
println!(" Notification IO failed: {}", &err);
break;
}
}
}
println!(" Stopping notification IO");
drop(notify_io);
sleep(Duration::from_secs(1)).await;
Ok(())
}
More examples
examples/gatt_echo_client.rs (line 68)
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
async fn exercise_characteristic(char: &Characteristic) -> Result<()> {
let mut write_io = char.write_io().await?;
println!(" Obtained write IO with MTU {} bytes", write_io.mtu());
let mut notify_io = char.notify_io().await?;
println!(" Obtained notification IO with MTU {} bytes", notify_io.mtu());
// Flush notify buffer.
let mut buf = [0; 1024];
while let Ok(Ok(_)) = timeout(Duration::from_secs(1), notify_io.read(&mut buf)).await {}
let mut rng = rand::thread_rng();
for i in 0..1024 {
let mut len = rng.gen_range(0..20000);
// Try to trigger packet reordering over EATT.
if i % 10 == 0 {
// Big packet is split into multiple small packets.
// (by L2CAP layer, because GATT MTU is bigger than L2CAP MTU)
len = write_io.mtu(); // 512
}
if i % 10 == 1 {
// Small packet can use different L2CAP channel when EATT is enabled.
len = 20;
}
// Thus small packet can arrive before big packet.
// The solution is to disable EATT in /etc/bluetooth/main.conf.
println!(" Test iteration {i} with data size {len}");
let data: Vec<u8> = (0..len).map(|_| rng.gen()).collect();
// 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 notify_io.read_exact(&mut echo_buf).await {
Ok(_) => Ok(echo_buf),
Err(err) => Err(err),
};
(notify_io, res)
});
// Note that write_all will automatically split the buffer into
// multiple writes of MTU size.
write_io.write_all(&data).await.expect("write failed");
println!(" Waiting for echo");
let (notify_io_back, res) = read_task.await.unwrap();
notify_io = notify_io_back;
let echo_buf = res.expect("read failed");
if echo_buf != data {
println!();
println!("Echo data mismatch!");
println!("Send data: {:x?}", &data);
println!("Received data: {:x?}", &echo_buf);
println!();
println!("By 512 blocks:");
for (sent, recv) in data.chunks(512).zip(echo_buf.chunks(512)) {
println!();
println!(
"Send: {:x?} ... {:x?}",
&sent[0..4.min(sent.len())],
&sent[sent.len().saturating_sub(4)..]
);
println!(
"Recv: {:x?} ... {:x?}",
&recv[0..4.min(recv.len())],
&recv[recv.len().saturating_sub(4)..]
);
}
println!();
panic!("echoed data does not match sent data");
}
println!(" Data matches");
}
println!(" Test okay");
Ok(())
}
sourcepub async fn recvable(&self) -> Result<()>
pub async fn recvable(&self) -> Result<()>
Wait for a new characteristic value to become available.
sourcepub fn try_recv(&self) -> Result<Vec<u8>>
pub fn try_recv(&self) -> Result<Vec<u8>>
Try to receive the characteristic value from a single notify or write operation.
Does not wait for new data to arrive.
sourcepub async fn recv(&self) -> Result<Vec<u8>>
pub async fn recv(&self) -> Result<Vec<u8>>
Receive the characteristic value from a single notify or write operation.
Waits for data to arrive.
sourcepub fn into_raw_fd(self) -> Result<RawFd>
pub fn into_raw_fd(self) -> Result<RawFd>
Consumes this object, returning the raw underlying file descriptor.
Trait Implementations§
source§impl AsRawFd for CharacteristicReader
impl AsRawFd for CharacteristicReader
source§impl AsyncRead for CharacteristicReader
impl AsyncRead for CharacteristicReader
source§impl Debug for CharacteristicReader
impl Debug for CharacteristicReader
source§impl IntoRawFd for CharacteristicReader
impl IntoRawFd for CharacteristicReader
source§fn into_raw_fd(self) -> RawFd
fn into_raw_fd(self) -> RawFd
Consumes this object, returning the raw underlying file descriptor. Read more
impl<'pin> Unpin for CharacteristicReaderwhere
__CharacteristicReader<'pin>: Unpin,
Auto Trait Implementations§
impl !Freeze for CharacteristicReader
impl RefUnwindSafe for CharacteristicReader
impl Send for CharacteristicReader
impl Sync for CharacteristicReader
impl UnwindSafe for CharacteristicReader
Blanket Implementations§
source§impl<R> AsyncReadExt for R
impl<R> AsyncReadExt for R
source§fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self>where
Self: Unpin,
fn read<'a>(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self>where
Self: Unpin,
Pulls some bytes from this source into the specified buffer,
returning how many bytes were read. Read more
source§fn read_buf<'a, B>(&'a mut self, buf: &'a mut B) -> ReadBuf<'a, Self, B>
fn read_buf<'a, B>(&'a mut self, buf: &'a mut B) -> ReadBuf<'a, Self, B>
Pulls some bytes from this source into the specified buffer,
advancing the buffer’s internal cursor. Read more
source§fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self>where
Self: Unpin,
fn read_exact<'a>(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self>where
Self: Unpin,
Reads the exact number of bytes required to fill
buf
. Read moresource§fn read_u8(&mut self) -> ReadU8<&mut Self>where
Self: Unpin,
fn read_u8(&mut self) -> ReadU8<&mut Self>where
Self: Unpin,
Reads an unsigned 8 bit integer from the underlying reader. Read more
source§fn read_i8(&mut self) -> ReadI8<&mut Self>where
Self: Unpin,
fn read_i8(&mut self) -> ReadI8<&mut Self>where
Self: Unpin,
Reads a signed 8 bit integer from the underlying reader. Read more
source§fn read_u16(&mut self) -> ReadU16<&mut Self>where
Self: Unpin,
fn read_u16(&mut self) -> ReadU16<&mut Self>where
Self: Unpin,
Reads an unsigned 16-bit integer in big-endian order from the
underlying reader. Read more
source§fn read_i16(&mut self) -> ReadI16<&mut Self>where
Self: Unpin,
fn read_i16(&mut self) -> ReadI16<&mut Self>where
Self: Unpin,
Reads a signed 16-bit integer in big-endian order from the
underlying reader. Read more
source§fn read_u32(&mut self) -> ReadU32<&mut Self>where
Self: Unpin,
fn read_u32(&mut self) -> ReadU32<&mut Self>where
Self: Unpin,
Reads an unsigned 32-bit integer in big-endian order from the
underlying reader. Read more
source§fn read_i32(&mut self) -> ReadI32<&mut Self>where
Self: Unpin,
fn read_i32(&mut self) -> ReadI32<&mut Self>where
Self: Unpin,
Reads a signed 32-bit integer in big-endian order from the
underlying reader. Read more
source§fn read_u64(&mut self) -> ReadU64<&mut Self>where
Self: Unpin,
fn read_u64(&mut self) -> ReadU64<&mut Self>where
Self: Unpin,
Reads an unsigned 64-bit integer in big-endian order from the
underlying reader. Read more
source§fn read_i64(&mut self) -> ReadI64<&mut Self>where
Self: Unpin,
fn read_i64(&mut self) -> ReadI64<&mut Self>where
Self: Unpin,
Reads an signed 64-bit integer in big-endian order from the
underlying reader. Read more
source§fn read_u128(&mut self) -> ReadU128<&mut Self>where
Self: Unpin,
fn read_u128(&mut self) -> ReadU128<&mut Self>where
Self: Unpin,
Reads an unsigned 128-bit integer in big-endian order from the
underlying reader. Read more
source§fn read_i128(&mut self) -> ReadI128<&mut Self>where
Self: Unpin,
fn read_i128(&mut self) -> ReadI128<&mut Self>where
Self: Unpin,
Reads an signed 128-bit integer in big-endian order from the
underlying reader. Read more
source§fn read_f32(&mut self) -> ReadF32<&mut Self>where
Self: Unpin,
fn read_f32(&mut self) -> ReadF32<&mut Self>where
Self: Unpin,
Reads an 32-bit floating point type in big-endian order from the
underlying reader. Read more
source§fn read_f64(&mut self) -> ReadF64<&mut Self>where
Self: Unpin,
fn read_f64(&mut self) -> ReadF64<&mut Self>where
Self: Unpin,
Reads an 64-bit floating point type in big-endian order from the
underlying reader. Read more
source§fn read_u16_le(&mut self) -> ReadU16Le<&mut Self>where
Self: Unpin,
fn read_u16_le(&mut self) -> ReadU16Le<&mut Self>where
Self: Unpin,
Reads an unsigned 16-bit integer in little-endian order from the
underlying reader. Read more
source§fn read_i16_le(&mut self) -> ReadI16Le<&mut Self>where
Self: Unpin,
fn read_i16_le(&mut self) -> ReadI16Le<&mut Self>where
Self: Unpin,
Reads a signed 16-bit integer in little-endian order from the
underlying reader. Read more
source§fn read_u32_le(&mut self) -> ReadU32Le<&mut Self>where
Self: Unpin,
fn read_u32_le(&mut self) -> ReadU32Le<&mut Self>where
Self: Unpin,
Reads an unsigned 32-bit integer in little-endian order from the
underlying reader. Read more
source§fn read_i32_le(&mut self) -> ReadI32Le<&mut Self>where
Self: Unpin,
fn read_i32_le(&mut self) -> ReadI32Le<&mut Self>where
Self: Unpin,
Reads a signed 32-bit integer in little-endian order from the
underlying reader. Read more
source§fn read_u64_le(&mut self) -> ReadU64Le<&mut Self>where
Self: Unpin,
fn read_u64_le(&mut self) -> ReadU64Le<&mut Self>where
Self: Unpin,
Reads an unsigned 64-bit integer in little-endian order from the
underlying reader. Read more
source§fn read_i64_le(&mut self) -> ReadI64Le<&mut Self>where
Self: Unpin,
fn read_i64_le(&mut self) -> ReadI64Le<&mut Self>where
Self: Unpin,
Reads an signed 64-bit integer in little-endian order from the
underlying reader. Read more
source§fn read_u128_le(&mut self) -> ReadU128Le<&mut Self>where
Self: Unpin,
fn read_u128_le(&mut self) -> ReadU128Le<&mut Self>where
Self: Unpin,
Reads an unsigned 128-bit integer in little-endian order from the
underlying reader. Read more
source§fn read_i128_le(&mut self) -> ReadI128Le<&mut Self>where
Self: Unpin,
fn read_i128_le(&mut self) -> ReadI128Le<&mut Self>where
Self: Unpin,
Reads an signed 128-bit integer in little-endian order from the
underlying reader. Read more
source§fn read_f32_le(&mut self) -> ReadF32Le<&mut Self>where
Self: Unpin,
fn read_f32_le(&mut self) -> ReadF32Le<&mut Self>where
Self: Unpin,
Reads an 32-bit floating point type in little-endian order from the
underlying reader. Read more
source§fn read_f64_le(&mut self) -> ReadF64Le<&mut Self>where
Self: Unpin,
fn read_f64_le(&mut self) -> ReadF64Le<&mut Self>where
Self: Unpin,
Reads an 64-bit floating point type in little-endian order from the
underlying reader. Read more
source§fn read_to_end<'a>(&'a mut self, buf: &'a mut Vec<u8>) -> ReadToEnd<'a, Self>where
Self: Unpin,
fn read_to_end<'a>(&'a mut self, buf: &'a mut Vec<u8>) -> ReadToEnd<'a, Self>where
Self: Unpin,
Reads all bytes until EOF in this source, placing them into
buf
. Read moresource§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more