Skip to main content

ServiceControl

Struct ServiceControl 

Source
pub struct ServiceControl { /* private fields */ }
Available on crate feature bluetoothd only.
Expand description

An object to control a service once it has been registered.

Use service_control to obtain controller and associated handle.

Implementations§

Source§

impl ServiceControl

Source

pub fn handle(&self) -> Result<NonZeroU16>

Gets the assigned handle of the service.

Examples found in repository?
examples/gatt_server_io.rs (line 72)
24async fn main() -> bluer::Result<()> {
25    env_logger::init();
26    let session = bluer::Session::new().await?;
27    let adapter = session.default_adapter().await?;
28    adapter.set_powered(true).await?;
29
30    println!("Advertising on Bluetooth adapter {} with address {}", adapter.name(), adapter.address().await?);
31    let mut manufacturer_data = BTreeMap::new();
32    manufacturer_data.insert(MANUFACTURER_ID, vec![0x21, 0x22, 0x23, 0x24]);
33    let le_advertisement = Advertisement {
34        service_uuids: vec![SERVICE_UUID].into_iter().collect(),
35        manufacturer_data,
36        discoverable: Some(true),
37        local_name: Some("gatt_server".to_string()),
38        ..Default::default()
39    };
40    let adv_handle = adapter.advertise(le_advertisement).await?;
41
42    println!("Serving GATT service on Bluetooth adapter {}", adapter.name());
43    let (service_control, service_handle) = service_control();
44    let (char_control, char_handle) = characteristic_control();
45    let app = Application {
46        services: vec![Service {
47            uuid: SERVICE_UUID,
48            primary: true,
49            characteristics: vec![Characteristic {
50                uuid: CHARACTERISTIC_UUID,
51                write: Some(CharacteristicWrite {
52                    write: true,
53                    write_without_response: true,
54                    method: CharacteristicWriteMethod::Io,
55                    ..Default::default()
56                }),
57                notify: Some(CharacteristicNotify {
58                    notify: true,
59                    method: CharacteristicNotifyMethod::Io,
60                    ..Default::default()
61                }),
62                control_handle: char_handle,
63                ..Default::default()
64            }],
65            control_handle: service_handle,
66            ..Default::default()
67        }],
68        ..Default::default()
69    };
70    let app_handle = adapter.serve_gatt_application(app).await?;
71
72    println!("Service handle is 0x{:x}", service_control.handle()?);
73    println!("Characteristic handle is 0x{:x}", char_control.handle()?);
74
75    println!("Service ready. Press enter to quit.");
76    let stdin = BufReader::new(tokio::io::stdin());
77    let mut lines = stdin.lines();
78
79    let mut value: Vec<u8> = vec![0x10, 0x01, 0x01, 0x10];
80    let mut read_buf = Vec::new();
81    let mut reader_opt: Option<CharacteristicReader> = None;
82    let mut writer_opt: Option<CharacteristicWriter> = None;
83    let mut interval = interval(Duration::from_secs(1));
84    pin_mut!(char_control);
85
86    loop {
87        tokio::select! {
88            _ = lines.next_line() => break,
89            evt = char_control.next() => {
90                match evt {
91                    Some(CharacteristicControlEvent::Write(req)) => {
92                        println!("Accepting write event with MTU {} from {}", req.mtu(), req.device_address());
93                        read_buf = vec![0; req.mtu()];
94                        reader_opt = Some(req.accept()?);
95                    },
96                    Some(CharacteristicControlEvent::Notify(notifier)) => {
97                        println!("Accepting notify request event with MTU {} from {}", notifier.mtu(), notifier.device_address());
98                        writer_opt = Some(notifier);
99                    },
100                    None => break,
101                }
102            }
103            _ = interval.tick() => {
104                println!("Decrementing each element by one");
105                for v in &mut *value {
106                    *v = v.saturating_sub(1);
107                }
108                println!("Value is {:x?}", &value);
109                if let Some(writer) = writer_opt.as_mut() {
110                    println!("Notifying with value {:x?}", &value);
111                    if let Err(err) = writer.write(&value).await {
112                        println!("Notification stream error: {}", &err);
113                        writer_opt = None;
114                    }
115                }
116            }
117            read_res = async {
118                match &mut reader_opt {
119                    Some(reader) => reader.read(&mut read_buf).await,
120                    None => future::pending().await,
121                }
122            } => {
123                match read_res {
124                    Ok(0) => {
125                        println!("Write stream ended");
126                        reader_opt = None;
127                    }
128                    Ok(n) => {
129                        value = read_buf[0..n].to_vec();
130                        println!("Write request with {} bytes: {:x?}", n, &value);
131                    }
132                    Err(err) => {
133                        println!("Write stream error: {}", &err);
134                        reader_opt = None;
135                    }
136                }
137            }
138        }
139    }
140
141    println!("Removing service and advertisement");
142    drop(app_handle);
143    drop(adv_handle);
144    sleep(Duration::from_secs(1)).await;
145
146    Ok(())
147}

Trait Implementations§

Source§

impl Debug for ServiceControl

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.