Crates.io | gatt |
lib.rs | gatt |
version | 0.3.0-alpha.1 |
source | src |
created_at | 2020-11-29 08:21:38.898266 |
updated_at | 2021-12-09 03:06:30.078028 |
description | Bluetooth Generic Attribute Protocol Server |
homepage | |
repository | https://github.com/yskszk63/gatt |
max_upload_size | |
id | 317698 |
size | 109,500 |
Bluetooth Low Energy Generic Attribute Profile
ref BLUETOOTH CORE SPECIFICATION Version 5.1 | Vol 3, Part G Generic Attribute Profile (GATT)
use gatt::{CharacteristicProperties, Registration, Server};
use gatt::services as srv;
use gatt::characteristics as ch;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
enum Token {
DeviceName,
BatteryLevelNotify,
}
fn new_registration() -> Registration<Token> {
let mut registration = Registration::new();
registration.add_primary_service(srv::GENERIC_ACCESS);
registration.add_characteristic_with_token(
Token::DeviceName,
ch::DEVICE_NAME,
"abc",
CharacteristicProperties::WRITE,
);
registration.add_characteristic(
ch::APPEARANCE,
0x03c0u16.to_le_bytes().to_vec(),
CharacteristicProperties::READ,
);
registration.add_primary_service(srv::GENERIC_ATTRIBUTE);
registration.add_characteristic(
ch::SERVICE_CHANGED,
"",
CharacteristicProperties::INDICATE,
);
registration.add_primary_service(srv::DEVICE_INFORMATION);
registration.add_characteristic(
ch::MANUFACTURER_NAME_STRING,
"機械",
CharacteristicProperties::READ,
);
registration.add_characteristic(
ch::MODEL_NUMBER_STRING,
"A123",
CharacteristicProperties::READ,
);
registration.add_characteristic(
ch::SERIAL_NUMBER_STRING,
"333-444",
CharacteristicProperties::READ,
);
registration.add_primary_service(srv::BATTERY);
registration.add_characteristic_with_token(
Token::BatteryLevelNotify,
ch::BATTERY_LEVEL,
"",
CharacteristicProperties::NOTIFY,
);
registration
}
#[tokio::main(flavor = "current_thread")]
async fn main() -> anyhow::Result<()> {
use std::io::stdin;
use tokio::task::spawn_blocking;
use tokio::io::AsyncWriteExt;
let mut server = Server::bind()?;
let mut connection = server.accept(new_registration()).await?.unwrap();
let mut events = connection.events();
let mut notification = connection.notification(&Token::BatteryLevelNotify)?;
let task = connection.run();
tokio::pin!(task);
let mut n = 0;
loop {
tokio::select! {
r = Pin::new(&mut task) => {
r?;
break;
}
maybe_line = spawn_blocking(|| stdin().read_line(&mut String::new())) => {
maybe_line??;
notification.write_all(&[n]).await?;
n += 1;
}
event = events.next() => {
if let Some(event) = event {
println!("{:?}", event);
}
}
}
}
// ...
# Ok(())
}
Tested on Linux 5.13 (Arch Linux)
Licensed under either of
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.!
License: MIT OR Apache-2.0