Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy --faster` does not report any errors - [ ] These changes fix #__ (github issue number if applicable). Either: - [ ] There are tests for these changes OR - [X] These changes do not require tests because there are no webbluetooth tests yet. Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. Source-Repo: https://github.com/servo/servo Source-Revision: 6b1088234bca2643a993dd8b9b809e8a763c03bb
154 lines
6.5 KiB
Rust
154 lines
6.5 KiB
Rust
/* 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 http://mozilla.org/MPL/2.0/. */
|
|
|
|
use bluetooth_blacklist::{Blacklist, uuid_is_blacklisted};
|
|
use dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMethods;
|
|
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding;
|
|
use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods;
|
|
use dom::bindings::error::Error::{Security, Type};
|
|
use dom::bindings::error::{Fallible, ErrorResult};
|
|
use dom::bindings::global::GlobalRef;
|
|
use dom::bindings::js::{JS, MutHeap, Root};
|
|
use dom::bindings::reflector::{Reflectable, Reflector, reflect_dom_object};
|
|
use dom::bindings::str::DOMString;
|
|
use dom::bluetoothdevice::BluetoothDevice;
|
|
use dom::bluetoothremotegattservice::BluetoothRemoteGATTService;
|
|
use dom::bluetoothuuid::{BluetoothServiceUUID, BluetoothUUID};
|
|
use ipc_channel::ipc::{self, IpcSender};
|
|
use net_traits::bluetooth_thread::BluetoothMethodMsg;
|
|
use std::cell::Cell;
|
|
|
|
// https://webbluetoothcg.github.io/web-bluetooth/#bluetoothremotegattserver
|
|
#[dom_struct]
|
|
pub struct BluetoothRemoteGATTServer {
|
|
reflector_: Reflector,
|
|
device: MutHeap<JS<BluetoothDevice>>,
|
|
connected: Cell<bool>,
|
|
}
|
|
|
|
impl BluetoothRemoteGATTServer {
|
|
pub fn new_inherited(device: &BluetoothDevice) -> BluetoothRemoteGATTServer {
|
|
BluetoothRemoteGATTServer {
|
|
reflector_: Reflector::new(),
|
|
device: MutHeap::new(device),
|
|
connected: Cell::new(false),
|
|
}
|
|
}
|
|
|
|
pub fn new(global: GlobalRef, device: &BluetoothDevice) -> Root<BluetoothRemoteGATTServer> {
|
|
reflect_dom_object(box BluetoothRemoteGATTServer::new_inherited(device),
|
|
global,
|
|
BluetoothRemoteGATTServerBinding::Wrap)
|
|
}
|
|
|
|
fn get_bluetooth_thread(&self) -> IpcSender<BluetoothMethodMsg> {
|
|
let global_root = self.global();
|
|
let global_ref = global_root.r();
|
|
global_ref.as_window().bluetooth_thread()
|
|
}
|
|
}
|
|
|
|
impl BluetoothRemoteGATTServerMethods for BluetoothRemoteGATTServer {
|
|
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-device
|
|
fn Device(&self) -> Root<BluetoothDevice> {
|
|
self.device.get()
|
|
}
|
|
|
|
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-connected
|
|
fn Connected(&self) -> bool {
|
|
self.connected.get()
|
|
}
|
|
|
|
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-connect
|
|
fn Connect(&self) -> Fallible<Root<BluetoothRemoteGATTServer>> {
|
|
let (sender, receiver) = ipc::channel().unwrap();
|
|
self.get_bluetooth_thread().send(
|
|
BluetoothMethodMsg::GATTServerConnect(String::from(self.Device().Id()), sender)).unwrap();
|
|
let server = receiver.recv().unwrap();
|
|
match server {
|
|
Ok(connected) => {
|
|
self.connected.set(connected);
|
|
Ok(Root::from_ref(self))
|
|
},
|
|
Err(error) => {
|
|
Err(Type(error))
|
|
},
|
|
}
|
|
}
|
|
|
|
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-disconnect
|
|
fn Disconnect(&self) -> ErrorResult {
|
|
let (sender, receiver) = ipc::channel().unwrap();
|
|
self.get_bluetooth_thread().send(
|
|
BluetoothMethodMsg::GATTServerDisconnect(String::from(self.Device().Id()), sender)).unwrap();
|
|
let server = receiver.recv().unwrap();
|
|
match server {
|
|
Ok(connected) => {
|
|
self.connected.set(connected);
|
|
Ok(())
|
|
},
|
|
Err(error) => {
|
|
Err(Type(error))
|
|
},
|
|
}
|
|
}
|
|
|
|
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservice
|
|
fn GetPrimaryService(&self, service: BluetoothServiceUUID) -> Fallible<Root<BluetoothRemoteGATTService>> {
|
|
let uuid = try!(BluetoothUUID::GetService(self.global().r(), service)).to_string();
|
|
if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
|
|
return Err(Security)
|
|
}
|
|
let (sender, receiver) = ipc::channel().unwrap();
|
|
self.get_bluetooth_thread().send(
|
|
BluetoothMethodMsg::GetPrimaryService(String::from(self.Device().Id()), uuid, sender)).unwrap();
|
|
let service = receiver.recv().unwrap();
|
|
match service {
|
|
Ok(service) => {
|
|
Ok(BluetoothRemoteGATTService::new(self.global().r(),
|
|
&self.device.get(),
|
|
DOMString::from(service.uuid),
|
|
service.is_primary,
|
|
service.instance_id))
|
|
},
|
|
Err(error) => {
|
|
Err(Type(error))
|
|
},
|
|
}
|
|
}
|
|
|
|
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattserver-getprimaryservices
|
|
fn GetPrimaryServices(&self,
|
|
service: Option<BluetoothServiceUUID>)
|
|
-> Fallible<Vec<Root<BluetoothRemoteGATTService>>> {
|
|
let mut uuid: Option<String> = None;
|
|
if let Some(s) = service {
|
|
uuid = Some(try!(BluetoothUUID::GetService(self.global().r(), s)).to_string());
|
|
if let Some(ref uuid) = uuid {
|
|
if uuid_is_blacklisted(uuid.as_ref(), Blacklist::All) {
|
|
return Err(Security)
|
|
}
|
|
}
|
|
};
|
|
let (sender, receiver) = ipc::channel().unwrap();
|
|
self.get_bluetooth_thread().send(
|
|
BluetoothMethodMsg::GetPrimaryServices(String::from(self.Device().Id()), uuid, sender)).unwrap();
|
|
let services_vec = receiver.recv().unwrap();
|
|
match services_vec {
|
|
Ok(service_vec) => {
|
|
Ok(service_vec.into_iter()
|
|
.map(|service| BluetoothRemoteGATTService::new(self.global().r(),
|
|
&self.device.get(),
|
|
DOMString::from(service.uuid),
|
|
service.is_primary,
|
|
service.instance_id))
|
|
.collect())
|
|
},
|
|
Err(error) => {
|
|
Err(Type(error))
|
|
},
|
|
}
|
|
}
|
|
}
|