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 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
// btleplug Source Code File // // Copyright 2020 Nonpolynomial Labs LLC. All rights reserved. // // Licensed under the BSD 3-Clause license. See LICENSE file in the project root // for full license information. // // Some portions of this file are taken and/or modified from Rumble // (https://github.com/mwylde/rumble), using a dual MIT/Apache License under the // following copyright: // // Copyright (c) 2014 The Rust Project Developers //! BtlePlug is a Bluetooth Low Energy (BLE) central module library for Rust. It //! currently supports Windows 10, macOS (and possibly iOS), Linux (using BlueZ //! sockets instead of D-Bus). Android support is coming in a future update. //! //! ## Usage //! //! An example of how to use the library to control some BLE smart lights: //! //! ```rust,no_run //! extern crate btleplug; //! extern crate rand; //! //! use std::thread; //! use std::time::Duration; //! use rand::{Rng, thread_rng}; //! #[cfg(target_os = "linux")] //! use btleplug::bluez::{adapter::ConnectedAdapter, manager::Manager}; //! #[cfg(target_os = "windows")] //! use btleplug::winrtble::{adapter::Adapter, manager::Manager}; //! #[cfg(target_os = "macos")] //! use btleplug::corebluetooth::{adapter::Adapter, manager::Manager}; //! use btleplug::api::{UUID, Central, Peripheral}; //! //! // adapter retreival works differently depending on your platform right now. //! // API needs to be aligned. //! //! #[cfg(any(target_os = "windows", target_os = "macos"))] //! fn get_central(manager: &Manager) -> Adapter { //! let adapters = manager.adapters().unwrap(); //! adapters.into_iter().nth(0).unwrap() //! } //! //! #[cfg(target_os = "linux")] //! fn get_central(manager: &Manager) -> ConnectedAdapter { //! let adapters = manager.adapters().unwrap(); //! let adapter = adapters.into_iter().nth(0).unwrap(); //! adapter.connect().unwrap() //! } //! //! pub fn main() { //! let manager = Manager::new().unwrap(); //! //! // get the first bluetooth adapter //! // //! // connect to the adapter //! let central = get_central(&manager); //! //! // start scanning for devices //! central.start_scan().unwrap(); //! // instead of waiting, you can use central.event_receiver() to fetch a channel and //! // 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; #[cfg(target_os = "linux")] #[macro_use] extern crate nix; #[cfg(target_os = "windows")] extern crate winrt; #[cfg(any(target_os = "macos", target_os = "ios"))] #[macro_use] extern crate objc; // We won't actually use anything specifically out of this crate. However, if we // want the CoreBluetooth code to compile, we need the objc protocols // (specifically, the core bluetooth protocols) exposed by it. #[cfg(any(target_os = "macos", target_os = "ios"))] extern crate cocoa; extern crate bytes; #[cfg(target_os = "linux")] #[macro_use] extern crate enum_primitive; extern crate num; #[cfg(target_os = "linux")] #[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; pub mod api; #[cfg(target_os = "linux")] pub mod bluez; mod common; #[cfg(any(target_os = "macos", target_os = "ios"))] pub mod corebluetooth; #[cfg(target_os = "windows")] pub mod winrtble; #[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), } // BtlePlug Result type pub type Result<T> = result::Result<T, Error>;