1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 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
//! Rumble is a Bluetooth Low Energy (BLE) central module library for Rust. //! Currently only Linux (with the BlueZ bluetooth library) is supported, although //! other operating systems may be supported in the future. Rumble interfaces with //! BlueZ using its socket interface rather than DBus. This offers much more control //! and reliability over the DBus interface, and does not require running BlueZ in //! experimental mode for BLE. //! //! As of version 0.2, the API is becoming more stable and the library itself more //! useful. You should still expect to encounter bugs, limitations, and odd behaviors. //! Pull requests (and wireshark traces) welcome! //! //! ## Usage //! //! An example of how to use the library to control some BLE smart lights: //! //! ```rust,no_run //! extern crate rumble; //! extern crate rand; //! //! use std::thread; //! use std::time::Duration; //! use rand::{Rng, thread_rng}; //! use rumble::bluez::manager::Manager; //! use rumble::api::{UUID, Central, Peripheral}; //! //! pub fn main() { //! let manager = Manager::new().unwrap(); //! //! // get the first bluetooth adapter //! let adapters = manager.adapters().unwrap(); //! let mut adapter = adapters.into_iter().nth(0).unwrap(); //! //! // reset the adapter -- clears out any errant state //! adapter = manager.down(&adapter).unwrap(); //! adapter = manager.up(&adapter).unwrap(); //! //! // connect to the adapter //! let central = adapter.connect().unwrap(); //! //! // start scanning for devices //! central.start_scan().unwrap(); //! // instead of waiting, you can use central.on_event to be notified of //! // new devices //! thread::sleep(Duration::from_secs(2)); //! //! // find the device we're interested in //! let light = central.peripherals().into_iter() //! .find(|p| p.properties().local_name.iter() //! .any(|name| name.contains("LEDBlue"))).unwrap(); //! //! // connect to the device //! light.connect().unwrap(); //! //! // discover characteristics //! light.discover_characteristics().unwrap(); //! //! // find the characteristic we want //! let chars = light.characteristics(); //! let cmd_char = chars.iter().find(|c| c.uuid == UUID::B16(0xFFE9)).unwrap(); //! //! // dance party //! let mut rng = thread_rng(); //! for _ in 0..20 { //! let color_cmd = vec![0x56, rng.gen(), rng.gen(), rng.gen(), 0x00, 0xF0, 0xAA]; //! light.command(&cmd_char, &color_cmd).unwrap(); //! thread::sleep(Duration::from_millis(200)); //! } //! } //! ``` extern crate libc; #[macro_use] extern crate log; #[macro_use] extern crate nix; #[cfg(target_os = "windows")] extern crate winrt; extern crate bytes; #[macro_use] extern crate enum_primitive; extern crate num; #[macro_use] extern crate nom; #[macro_use] extern crate bitflags; extern crate failure; #[macro_use] extern crate failure_derive; use std::result; use std::time::Duration; #[cfg(target_os = "linux")] pub mod bluez; #[cfg(target_os = "windows")] pub mod winrtble; pub mod api; #[derive(Debug, Fail, Clone)] pub enum Error { #[fail(display = "Permission denied")] PermissionDenied, #[fail(display = "Device not found")] DeviceNotFound, #[fail(display = "Not connected")] NotConnected, #[fail(display = "The operation is not supported: {}", _0)] NotSupported(String), #[fail(display = "Timed out after {:?}", _0)] TimedOut(Duration), #[fail(display = "{}", _0)] Other(String), } // Rumble Result type pub type Result<T> = result::Result<T, Error>;