btleplug/lib.rs
1// btleplug Source Code File
2//
3// Copyright 2020 Nonpolynomial Labs LLC. All rights reserved.
4//
5// Licensed under the BSD 3-Clause license. See LICENSE file in the project root
6// for full license information.
7//
8// Some portions of this file are taken and/or modified from Rumble
9// (https://github.com/mwylde/rumble), using a dual MIT/Apache License under the
10// following copyright:
11//
12// Copyright (c) 2014 The Rust Project Developers
13
14//! btleplug is a Bluetooth Low Energy (BLE) central module library for Rust.
15//! It currently supports Windows 10, macOS (and possibly iOS) and Linux
16//! (BlueZ). Android support is planned for the future.
17//!
18//! ## Usage
19//!
20//! An example of how to use the library to control some BLE smart lights:
21//!
22//! ```rust,no_run
23//! use btleplug::api::{bleuuid::uuid_from_u16, Central, Manager as _, Peripheral as _, ScanFilter, WriteType};
24//! use btleplug::platform::{Adapter, Manager, Peripheral};
25//! use rand::{Rng, thread_rng};
26//! use std::error::Error;
27//! use std::thread;
28//! use std::time::Duration;
29//! use tokio::time;
30//! use uuid::Uuid;
31//!
32//! const LIGHT_CHARACTERISTIC_UUID: Uuid = uuid_from_u16(0xFFE9);
33//!
34//! #[tokio::main]
35//! async fn main() -> Result<(), Box<dyn Error>> {
36//! let manager = Manager::new().await.unwrap();
37//!
38//! // get the first bluetooth adapter
39//! let adapters = manager.adapters().await?;
40//! let central = adapters.into_iter().nth(0).unwrap();
41//!
42//! // start scanning for devices
43//! central.start_scan(ScanFilter::default()).await?;
44//! // instead of waiting, you can use central.events() to get a stream which will
45//! // notify you of new devices, for an example of that see examples/event_driven_discovery.rs
46//! time::sleep(Duration::from_secs(2)).await;
47//!
48//! // find the device we're interested in
49//! let light = find_light(¢ral).await.unwrap();
50//!
51//! // connect to the device
52//! light.connect().await?;
53//!
54//! // discover services and characteristics
55//! light.discover_services().await?;
56//!
57//! // find the characteristic we want
58//! let chars = light.characteristics();
59//! let cmd_char = chars.iter().find(|c| c.uuid == LIGHT_CHARACTERISTIC_UUID).unwrap();
60//!
61//! // dance party
62//! let mut rng = thread_rng();
63//! for _ in 0..20 {
64//! let color_cmd = vec![0x56, rng.gen(), rng.gen(), rng.gen(), 0x00, 0xF0, 0xAA];
65//! light.write(&cmd_char, &color_cmd, WriteType::WithoutResponse).await?;
66//! time::sleep(Duration::from_millis(200)).await;
67//! }
68//! Ok(())
69//! }
70//!
71//! async fn find_light(central: &Adapter) -> Option<Peripheral> {
72//! for p in central.peripherals().await.unwrap() {
73//! if p.properties()
74//! .await
75//! .unwrap()
76//! .unwrap()
77//! .local_name
78//! .iter()
79//! .any(|name| name.contains("LEDBlue"))
80//! {
81//! return Some(p);
82//! }
83//! }
84//! None
85//! }
86//! ```
87
88use crate::api::ParseBDAddrError;
89use std::result;
90use std::time::Duration;
91
92pub mod api;
93#[cfg(target_os = "linux")]
94mod bluez;
95#[cfg(not(target_os = "linux"))]
96mod common;
97#[cfg(target_vendor = "apple")]
98mod corebluetooth;
99#[cfg(target_os = "android")]
100mod droidplug;
101pub mod platform;
102#[cfg(feature = "serde")]
103pub mod serde;
104#[cfg(target_os = "windows")]
105mod winrtble;
106
107/// The main error type returned by most methods in btleplug.
108#[derive(Debug, thiserror::Error)]
109pub enum Error {
110 #[error("Permission denied")]
111 PermissionDenied,
112
113 #[error("Device not found")]
114 DeviceNotFound,
115
116 #[error("Not connected")]
117 NotConnected,
118
119 #[error("Unexpected callback")]
120 UnexpectedCallback,
121
122 #[error("Unexpected characteristic")]
123 UnexpectedCharacteristic,
124
125 #[error("No such characteristic")]
126 NoSuchCharacteristic,
127
128 #[error("The operation is not supported: {}", _0)]
129 NotSupported(String),
130
131 #[error("Timed out after {:?}", _0)]
132 TimedOut(Duration),
133
134 #[error("Error parsing UUID: {0}")]
135 Uuid(#[from] uuid::Error),
136
137 #[error("Invalid Bluetooth address: {0}")]
138 InvalidBDAddr(#[from] ParseBDAddrError),
139
140 #[error("Runtime Error: {}", _0)]
141 RuntimeError(String),
142
143 #[error("{}", _0)]
144 Other(Box<dyn std::error::Error + Send + Sync>),
145}
146
147/// Convenience type for a result using the btleplug [`Error`] type.
148pub type Result<T> = result::Result<T, Error>;