Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allowed services support #11580

Merged
merged 1 commit into from
Jun 5, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 20 additions & 3 deletions components/net/bluetooth_thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use net_traits::bluetooth_thread::{BluetoothDeviceMsg, BluetoothMethodMsg};
use net_traits::bluetooth_thread::{BluetoothResult, BluetoothServiceMsg, BluetoothServicesMsg};
use rand::{self, Rng};
use std::borrow::ToOwned;
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
use std::string::String;
use std::thread;
use std::time::Duration;
Expand All @@ -32,6 +32,7 @@ const INCLUDED_SERVICE_ERROR: &'static str = "No included service found";
const CHARACTERISTIC_ERROR: &'static str = "No characteristic found";
const DESCRIPTOR_ERROR: &'static str = "No descriptor found";
const VALUE_ERROR: &'static str = "No characteristic or descriptor found with that id";
const SECURITY_ERROR: &'static str = "The operation is insecure";
// The discovery session needs some time to find any nearby devices
const DISCOVERY_TIMEOUT_MS: u64 = 1500;
#[cfg(target_os = "linux")]
Expand Down Expand Up @@ -139,6 +140,7 @@ pub struct BluetoothManager {
cached_services: HashMap<String, BluetoothGATTService>,
cached_characteristics: HashMap<String, BluetoothGATTCharacteristic>,
cached_descriptors: HashMap<String, BluetoothGATTDescriptor>,
allowed_services: HashMap<String, HashSet<String>>,
}

impl BluetoothManager {
Expand All @@ -154,6 +156,7 @@ impl BluetoothManager {
cached_services: HashMap::new(),
cached_characteristics: HashMap::new(),
cached_descriptors: HashMap::new(),
allowed_services: HashMap::new(),
}
}

Expand Down Expand Up @@ -225,7 +228,8 @@ impl BluetoothManager {
if !self.address_to_id.contains_key(&address) {
let generated_id = self.generate_device_id();
self.address_to_id.insert(address, generated_id.clone());
self.cached_devices.insert(generated_id, device.clone());
self.cached_devices.insert(generated_id.clone(), device.clone());
self.allowed_services.insert(generated_id, HashSet::new());
}
}
}
Expand Down Expand Up @@ -446,6 +450,11 @@ impl BluetoothManager {
Some(id) => id.clone(),
None => return drop(sender.send(Err(String::from(DEVICE_MATCH_ERROR)))),
};
let mut services = options.get_services_set();
if let Some(services_set) = self.allowed_services.get(&device_id) {
services = services_set | &services;
}
self.allowed_services.insert(device_id.clone(), services);
if let Some(device) = self.get_device(&mut adapter, &device_id) {
let message = Ok(BluetoothDeviceMsg {
id: device_id,
Expand Down Expand Up @@ -499,6 +508,9 @@ impl BluetoothManager {
uuid: String,
sender: IpcSender<BluetoothResult<BluetoothServiceMsg>>) {
let mut adapter = get_adapter_or_return_error!(self, sender);
if !self.allowed_services.get(&device_id).map_or(false, |s| s.contains(&uuid)) {
return drop(sender.send(Err(String::from(SECURITY_ERROR))));
}
let services = self.get_gatt_services_by_uuid(&mut adapter, &device_id, &uuid);
if services.is_empty() {
return drop(sender.send(Err(String::from(PRIMARY_SERVICE_ERROR))));
Expand All @@ -523,7 +535,12 @@ impl BluetoothManager {
sender: IpcSender<BluetoothResult<BluetoothServicesMsg>>) {
let mut adapter = get_adapter_or_return_error!(self, sender);
let services = match uuid {
Some(id) => self.get_gatt_services_by_uuid(&mut adapter, &device_id, &id),
Some(ref id) => {
if !self.allowed_services.get(&device_id).map_or(false, |s| s.contains(id)) {
return drop(sender.send(Err(String::from(SECURITY_ERROR))))
}
self.get_gatt_services_by_uuid(&mut adapter, &device_id, id)
},
None => self.get_and_cache_gatt_services(&mut adapter, &device_id),
};
if services.is_empty() {
Expand Down
21 changes: 21 additions & 0 deletions components/net_traits/bluetooth_scanfilter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use std::collections::HashSet;
use std::slice::Iter;

// A device name can never be longer than 29 bytes. An adv packet is at most
Expand All @@ -16,6 +17,14 @@ impl ServiceUUIDSequence {
pub fn new(vec: Vec<String>) -> ServiceUUIDSequence {
ServiceUUIDSequence(vec)
}

fn get_services_set(&self) -> HashSet<String> {
let mut set = HashSet::new();
for s in self.0.iter() {
set.insert(s.clone());
}
set
}
}

#[derive(Deserialize, Serialize)]
Expand Down Expand Up @@ -69,6 +78,14 @@ impl BluetoothScanfilterSequence {
pub fn iter(&self) -> Iter<BluetoothScanfilter> {
self.0.iter()
}

fn get_services_set(&self) -> HashSet<String> {
let mut set = HashSet::new();
for filter in self.iter() {
set = &set | &filter.services.get_services_set();
}
set
}
}

#[derive(Deserialize, Serialize)]
Expand All @@ -90,4 +107,8 @@ impl RequestDeviceoptions {
pub fn get_filters(&self) -> &BluetoothScanfilterSequence {
&self.filters
}

pub fn get_services_set(&self) -> HashSet<String> {
&self.filters.get_services_set() | &self.optional_services.get_services_set()
}
}