/* 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 dom::bindings::codegen::Bindings::BluetoothDeviceBinding::BluetoothDeviceMethods; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding; use dom::bindings::codegen::Bindings::BluetoothRemoteGATTServerBinding::BluetoothRemoteGATTServerMethods; use dom::bindings::error::Error::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>, connected: Cell, } 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 { reflect_dom_object(box BluetoothRemoteGATTServer::new_inherited(device), global, BluetoothRemoteGATTServerBinding::Wrap) } fn get_bluetooth_thread(&self) -> IpcSender { 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 { 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> { 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> { let uuid = try!(BluetoothUUID::GetService(self.global().r(), service)).to_string(); 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) -> Fallible>> { let mut uuid: Option = None; if let Some(s) = service { uuid = Some(try!(BluetoothUUID::GetService(self.global().r(), s)).to_string()) }; 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)) }, } } }