/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use std::collections::{HashMap, HashSet}; use std::slice::Iter; use base::id::WebViewId; use serde::{Deserialize, Serialize}; // A device name can never be longer than 29 bytes. An adv packet is at most // 31 bytes long. The length and identifier of the length field take 2 bytes. // That leaves 29 bytes for the name. const MAX_NAME_LENGTH: usize = 29; #[derive(Debug, Deserialize, Serialize)] pub struct ServiceUUIDSequence(Vec); impl ServiceUUIDSequence { pub fn new(vec: Vec) -> ServiceUUIDSequence { ServiceUUIDSequence(vec) } fn get_services_set(&self) -> HashSet { self.0.iter().map(String::clone).collect() } } type ManufacturerData = HashMap, Vec)>; type ServiceData = HashMap, Vec)>; #[derive(Debug, Deserialize, Serialize)] pub struct BluetoothScanfilter { name: Option, name_prefix: String, services: ServiceUUIDSequence, manufacturer_data: Option, service_data: Option, } impl BluetoothScanfilter { pub fn new( name: Option, name_prefix: String, services: Vec, manufacturer_data: Option, service_data: Option, ) -> BluetoothScanfilter { BluetoothScanfilter { name, name_prefix, services: ServiceUUIDSequence::new(services), manufacturer_data, service_data, } } pub fn get_name(&self) -> Option<&str> { self.name.as_deref() } pub fn get_name_prefix(&self) -> &str { &self.name_prefix } pub fn get_services(&self) -> &[String] { &self.services.0 } pub fn get_manufacturer_data(&self) -> Option<&ManufacturerData> { self.manufacturer_data.as_ref() } pub fn get_service_data(&self) -> Option<&ServiceData> { self.service_data.as_ref() } pub fn is_empty_or_invalid(&self) -> bool { (self.name.is_none() && self.name_prefix.is_empty() && self.get_services().is_empty() && self.manufacturer_data.is_none() && self.service_data.is_none()) || self.get_name().unwrap_or("").len() > MAX_NAME_LENGTH || self.name_prefix.len() > MAX_NAME_LENGTH } } #[derive(Debug, Deserialize, Serialize)] pub struct BluetoothScanfilterSequence(Vec); impl BluetoothScanfilterSequence { pub fn new(vec: Vec) -> BluetoothScanfilterSequence { BluetoothScanfilterSequence(vec) } pub fn has_empty_or_invalid_filter(&self) -> bool { self.0.iter().any(BluetoothScanfilter::is_empty_or_invalid) } pub fn iter(&self) -> Iter { self.0.iter() } fn get_services_set(&self) -> HashSet { self.iter() .flat_map(|filter| filter.services.get_services_set()) .collect() } fn is_empty(&self) -> bool { self.0.is_empty() } } #[derive(Debug, Deserialize, Serialize)] pub struct RequestDeviceoptions { webview_id: WebViewId, filters: BluetoothScanfilterSequence, optional_services: ServiceUUIDSequence, } impl RequestDeviceoptions { pub fn new( webview_id: WebViewId, filters: BluetoothScanfilterSequence, services: ServiceUUIDSequence, ) -> RequestDeviceoptions { RequestDeviceoptions { webview_id, filters, optional_services: services, } } pub fn webview_id(&self) -> WebViewId { self.webview_id } pub fn get_filters(&self) -> &BluetoothScanfilterSequence { &self.filters } pub fn get_services_set(&self) -> HashSet { &self.filters.get_services_set() | &self.optional_services.get_services_set() } pub fn is_accepting_all_devices(&self) -> bool { self.filters.is_empty() } }