Struct bluer::gatt::CharacteristicReader
source · [−]pub struct CharacteristicReader { /* private fields */ }
bluetoothd
only.Expand description
Streams data from a characteristic with low overhead.
Implementations
sourceimpl CharacteristicReader
impl CharacteristicReader
sourcepub fn mtu(&self) -> usize
pub fn mtu(&self) -> usize
Maximum transmission unit.
Examples found in repository
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!(" {} bytes written", 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
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 {} with data size {}", i, 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
sourceimpl AsRawFd for CharacteristicReader
impl AsRawFd for CharacteristicReader
sourceimpl AsyncRead for CharacteristicReader
impl AsyncRead for CharacteristicReader
sourceimpl Debug for CharacteristicReader
impl Debug for CharacteristicReader
sourceimpl IntoRawFd for CharacteristicReader
impl IntoRawFd for CharacteristicReader
sourcefn 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 CharacteristicReader where
__CharacteristicReader<'pin>: Unpin,
Auto Trait Implementations
impl RefUnwindSafe for CharacteristicReader
impl Send for CharacteristicReader
impl Sync for CharacteristicReader
impl UnwindSafe for CharacteristicReader
Blanket Implementations
sourceimpl<R> AsyncReadExt for R where
R: AsyncRead + ?Sized,
impl<R> AsyncReadExt for R where
R: AsyncRead + ?Sized,
sourcefn chain<R>(self, next: R) -> Chain<Self, R> where
R: AsyncRead,
fn chain<R>(self, next: R) -> Chain<Self, R> where
R: AsyncRead,
Creates a new AsyncRead
instance that chains this stream with
next
. Read more
sourcefn read(&'a mut self, buf: &'a mut [u8]) -> Read<'a, Self> where
Self: Unpin,
fn read(&'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
sourcefn read_buf<B>(&'a mut self, buf: &'a mut B) -> ReadBuf<'a, Self, B> where
Self: Unpin,
B: BufMut,
fn read_buf<B>(&'a mut self, buf: &'a mut B) -> ReadBuf<'a, Self, B> where
Self: Unpin,
B: BufMut,
Pulls some bytes from this source into the specified buffer, advancing the buffer’s internal cursor. Read more
sourcefn read_exact(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self> where
Self: Unpin,
fn read_exact(&'a mut self, buf: &'a mut [u8]) -> ReadExact<'a, Self> where
Self: Unpin,
Reads the exact number of bytes required to fill buf
. Read more
sourcefn read_u8(&'a mut self) -> ReadU8<&'a mut Self> where
Self: Unpin,
fn read_u8(&'a mut self) -> ReadU8<&'a mut Self> where
Self: Unpin,
Reads an unsigned 8 bit integer from the underlying reader. Read more
sourcefn read_i8(&'a mut self) -> ReadI8<&'a mut Self> where
Self: Unpin,
fn read_i8(&'a mut self) -> ReadI8<&'a mut Self> where
Self: Unpin,
Reads a signed 8 bit integer from the underlying reader. Read more
sourcefn read_u16(&'a mut self) -> ReadU16<&'a mut Self> where
Self: Unpin,
fn read_u16(&'a mut self) -> ReadU16<&'a mut Self> where
Self: Unpin,
Reads an unsigned 16-bit integer in big-endian order from the underlying reader. Read more
sourcefn read_i16(&'a mut self) -> ReadI16<&'a mut Self> where
Self: Unpin,
fn read_i16(&'a mut self) -> ReadI16<&'a mut Self> where
Self: Unpin,
Reads a signed 16-bit integer in big-endian order from the underlying reader. Read more
sourcefn read_u32(&'a mut self) -> ReadU32<&'a mut Self> where
Self: Unpin,
fn read_u32(&'a mut self) -> ReadU32<&'a mut Self> where
Self: Unpin,
Reads an unsigned 32-bit integer in big-endian order from the underlying reader. Read more
sourcefn read_i32(&'a mut self) -> ReadI32<&'a mut Self> where
Self: Unpin,
fn read_i32(&'a mut self) -> ReadI32<&'a mut Self> where
Self: Unpin,
Reads a signed 32-bit integer in big-endian order from the underlying reader. Read more
sourcefn read_u64(&'a mut self) -> ReadU64<&'a mut Self> where
Self: Unpin,
fn read_u64(&'a mut self) -> ReadU64<&'a mut Self> where
Self: Unpin,
Reads an unsigned 64-bit integer in big-endian order from the underlying reader. Read more
sourcefn read_i64(&'a mut self) -> ReadI64<&'a mut Self> where
Self: Unpin,
fn read_i64(&'a mut self) -> ReadI64<&'a mut Self> where
Self: Unpin,
Reads an signed 64-bit integer in big-endian order from the underlying reader. Read more
sourcefn read_u128(&'a mut self) -> ReadU128<&'a mut Self> where
Self: Unpin,
fn read_u128(&'a mut self) -> ReadU128<&'a mut Self> where
Self: Unpin,
Reads an unsigned 128-bit integer in big-endian order from the underlying reader. Read more
sourcefn read_i128(&'a mut self) -> ReadI128<&'a mut Self> where
Self: Unpin,
fn read_i128(&'a mut self) -> ReadI128<&'a mut Self> where
Self: Unpin,
Reads an signed 128-bit integer in big-endian order from the underlying reader. Read more
sourcefn read_f32(&'a mut self) -> ReadF32<&'a mut Self> where
Self: Unpin,
fn read_f32(&'a mut self) -> ReadF32<&'a mut Self> where
Self: Unpin,
Reads an 32-bit floating point type in big-endian order from the underlying reader. Read more
sourcefn read_f64(&'a mut self) -> ReadF64<&'a mut Self> where
Self: Unpin,
fn read_f64(&'a mut self) -> ReadF64<&'a mut Self> where
Self: Unpin,
Reads an 64-bit floating point type in big-endian order from the underlying reader. Read more
sourcefn read_u16_le(&'a mut self) -> ReadU16Le<&'a mut Self> where
Self: Unpin,
fn read_u16_le(&'a mut self) -> ReadU16Le<&'a mut Self> where
Self: Unpin,
Reads an unsigned 16-bit integer in little-endian order from the underlying reader. Read more
sourcefn read_i16_le(&'a mut self) -> ReadI16Le<&'a mut Self> where
Self: Unpin,
fn read_i16_le(&'a mut self) -> ReadI16Le<&'a mut Self> where
Self: Unpin,
Reads a signed 16-bit integer in little-endian order from the underlying reader. Read more
sourcefn read_u32_le(&'a mut self) -> ReadU32Le<&'a mut Self> where
Self: Unpin,
fn read_u32_le(&'a mut self) -> ReadU32Le<&'a mut Self> where
Self: Unpin,
Reads an unsigned 32-bit integer in little-endian order from the underlying reader. Read more
sourcefn read_i32_le(&'a mut self) -> ReadI32Le<&'a mut Self> where
Self: Unpin,
fn read_i32_le(&'a mut self) -> ReadI32Le<&'a mut Self> where
Self: Unpin,
Reads a signed 32-bit integer in little-endian order from the underlying reader. Read more
sourcefn read_u64_le(&'a mut self) -> ReadU64Le<&'a mut Self> where
Self: Unpin,
fn read_u64_le(&'a mut self) -> ReadU64Le<&'a mut Self> where
Self: Unpin,
Reads an unsigned 64-bit integer in little-endian order from the underlying reader. Read more
sourcefn read_i64_le(&'a mut self) -> ReadI64Le<&'a mut Self> where
Self: Unpin,
fn read_i64_le(&'a mut self) -> ReadI64Le<&'a mut Self> where
Self: Unpin,
Reads an signed 64-bit integer in little-endian order from the underlying reader. Read more
sourcefn read_u128_le(&'a mut self) -> ReadU128Le<&'a mut Self> where
Self: Unpin,
fn read_u128_le(&'a mut self) -> ReadU128Le<&'a mut Self> where
Self: Unpin,
Reads an unsigned 128-bit integer in little-endian order from the underlying reader. Read more
sourcefn read_i128_le(&'a mut self) -> ReadI128Le<&'a mut Self> where
Self: Unpin,
fn read_i128_le(&'a mut self) -> ReadI128Le<&'a mut Self> where
Self: Unpin,
Reads an signed 128-bit integer in little-endian order from the underlying reader. Read more
sourcefn read_f32_le(&'a mut self) -> ReadF32Le<&'a mut Self> where
Self: Unpin,
fn read_f32_le(&'a mut self) -> ReadF32Le<&'a mut Self> where
Self: Unpin,
Reads an 32-bit floating point type in little-endian order from the underlying reader. Read more
sourcefn read_f64_le(&'a mut self) -> ReadF64Le<&'a mut Self> where
Self: Unpin,
fn read_f64_le(&'a mut self) -> ReadF64Le<&'a mut Self> where
Self: Unpin,
Reads an 64-bit floating point type in little-endian order from the underlying reader. Read more
sourcefn read_to_end(
&'a mut self,
buf: &'a mut Vec<u8, Global>
) -> ReadToEnd<'a, Self> where
Self: Unpin,
fn read_to_end(
&'a mut self,
buf: &'a mut Vec<u8, Global>
) -> ReadToEnd<'a, Self> where
Self: Unpin,
Reads all bytes until EOF in this source, placing them into buf
. Read more
sourcefn read_to_string(&'a mut self, dst: &'a mut String) -> ReadToString<'a, Self> where
Self: Unpin,
fn read_to_string(&'a mut self, dst: &'a mut String) -> ReadToString<'a, Self> where
Self: Unpin,
Reads all bytes until EOF in this source, appending them to buf
. Read more
sourceimpl<T> BorrowMut<T> for T where
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more