servo/devices

Name: devices

Owner: Servo

Description: Servo-specific APIs to access various devices

Created: 2016-03-09 17:14:41.0

Updated: 2018-04-16 10:27:32.0

Pushed: 2018-04-09 20:05:43.0

Homepage: null

Size: 90

Language: Rust

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

devices

Servo-specific APIs to access various devices


Bluetooth

Bluetooth related code is located in bluetooth.rs.

Implementation

Underlying dependency crates:

Empty prefixed structures are located in empty.rs.

Usage
Without the bluetooth-test feature

There are three supported platforms (Android, Linux, MacOS), on other platforms we fall back to a default (Empty prefixed) implementation. Each enum (BluetoothAdapter, BluetoothDevice, etc.) will contain only one variant for each targeted platform. See the following BluetoothAdapter example:

Android:

pub enum BluetoothAdapter {
    Android(Arc<BluetoothAdapterAndroid>),
}

Linux:

pub enum BluetoothAdapter {
    Bluez(Arc<BluetoothAdapterBluez>),
}

MacOS:

pub enum BluetoothAdapter {
    Mac(Arc<BluetoothAdapterMac>),
}

unsupported platforms:

pub enum BluetoothAdapter {
    Empty(Arc<BluetoothAdapterEmpty>),
}

You will have a platform specific adapter, e.g. on android target, BluetoothAdapter::init() will create a BluetoothAdapter::Android enum variant, which wraps an Arc<BluetoothAdapterAndroid>.

pub fn init() -> Result<BluetoothAdapter, Box<Error>> {
    let blurdroid_adapter = try!(BluetoothAdapterAndroid::get_adapter());
    Ok(BluetoothAdapter::Android(Arc::new(blurdroid_adapter)))
}

On each platform you can call the same functions to reach the same GATT hierarchy elements. The following code can access the same bluetooth device on all supported platforms:

device::{BluetoothAdapter, BluetoothDevice};

ain() {
// Get the bluetooth adapter.
let adapter = BluetoothAdpater::init().expect("No bluetooth adapter found!");
// Get a device with the id 01:2A:00:4D:00:04 if it exists.
let device = adapter.get_device("01:2A:00:4D:00:04".to_owned() /*device address*/)
                    .expect("No bluetooth device found!");

With the bluetooth-test feature

The bluetooth-test feature is not a default feature, to use it, append features = ["bluetooth-test"], to the device crate dependency in the project's Cargo.toml.

Each enum (BluetoothAdapter, BluetoothDevice, etc.) will contain one variant of the three possible default target, and a Mock variant, which wraps a Fake structure.

Android:

pub enum BluetoothAdapter {
    Android(Arc<BluetoothAdapterAndroid>),
    Mock(Arc<FakeBluetoothAdapter>),
}

Linux:

pub enum BluetoothAdapter {
    Bluez(Arc<BluetoothAdapterBluez>),
    Mock(Arc<FakeBluetoothAdapter>),
}

Mac:

pub enum BluetoothAdapter {
    Mac(Arc<BluetoothAdapterMac>),
    Mock(Arc<FakeBluetoothAdapter>),
}

unsupported platforms:

pub enum BluetoothAdapter {
    Empty(Arc<BluetoothAdapterEmpty>),
    Mock(Arc<FakeBluetoothAdapter>),
}

Beside the platform specific structures, you can create and access mock adapters, devices, services etc. These mock structures implements all the platform specific functions too. To create a mock GATT hierarchy, first you need to call the BluetoothAdapter::init_mock() function, insted of BluetoothAdapter::init().

use device::{BluetoothAdapter, BluetoothDevice};
use std::String;

// This function takes a BluetoothAdapter,
// and print the ids of the devices, which the adapter can find.
fn print_device_ids(adapter: &BluetoothAdpater) {
    let devices = match adapter.get_devices().expect("No devices on the adapter!");
    for device in devices {
        println!("{:?}", device.get_id());
    }
}

fn main() {
// This code uses a real adapter.
    // Get the bluetooth adapter.
    let adapter = BluetoothAdpater::init().expect("No bluetooth adapter found!");
    // Get a device with the id 01:2A:00:4D:00:04 if it exists.
    let device = adapter.get_device("01:2A:00:4D:00:04".to_owned() /*device address*/)
                        .expect("No bluetooth device found!");

// This code uses a mock adapter.
    // Creating a mock adapter.
    let mock_adapter = BluetoothAdpater::init_mock().unwrap();
    // Creating a mock device.
    let mock_device =
        BluetoothDevice::create_mock_device(mock_adapter,
                                            "device_id_string_goes_here".to_owned())
        .unwrap();
    // Changing its device_id.
    let new_device_id = String::from("new_device_id_string".to_owned());
    mock_device.set_id(new_device_id.clone());
    // Calling the get_id function must return the last id we set.
    assert_equals!(new_device_id, mock_device.get_id());
    // Getting the mock_device with its id
    // must return the same mock device object we created before.
    assert_equals!(Some(mock_device),
                   mock_adapter.get_device(new_device_id.clone()).unwrap());
    // The print_device_ids function accept real and mock adapters too.
    print_device_ids(&adapter);
    print_device_ids(&mock_adapter);
}

Calling a test function on a not Mock structure, will result an error with the message: Error! Test functions are not supported on real devices!.


This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.