Skip to content
Permalink
Browse files

Step annotations for WebBluetooth functions

  • Loading branch information...
zakorgy authored and dati91 committed Nov 24, 2016
1 parent 89c4219 commit 8dd100f74fdabd55d5f3c179b3d5e52d2e0aa0e5

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -79,7 +79,7 @@ impl<Listener: AsyncBluetoothListener + Reflectable> BluetoothResponseListener f
match response {
Ok(response) => self.receiver.root().handle_response(response, promise_cx, &promise),
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetooth-requestdevice
// Step 3-4.
// Step 3 - 4.
Err(error) => promise.reject_error(promise_cx, Error::from(error)),
}
}
@@ -187,9 +187,9 @@ impl Bluetooth {
let option = RequestDeviceoptions::new(BluetoothScanfilterSequence::new(uuid_filters),
ServiceUUIDSequence::new(optional_services_uuids));

// TODO: Step 3-5: Implement the permission API.
// TODO: Step 3 - 5: Implement the permission API.

// Note: Steps 6-8 are implemented in
// Note: Steps 6 - 8 are implemented in
// components/net/bluetooth_thread.rs in request_device function.
let sender = response_async(p, self);
self.get_bluetooth_thread().send(BluetoothRequest::RequestDevice(option, sender)).unwrap();
@@ -295,7 +295,7 @@ fn canonicalize_filter(filter: &BluetoothLEScanFilterInit) -> Fallible<Bluetooth
None => String::new(),
};

// Step 6 -7.
// Step 6 - 7.
let manufacturer_data = match filter.manufacturerData {
Some(ref manufacturer_data_map) => {
// Note: If manufacturer_data_map is empty, that means there are no key values in it.
@@ -304,23 +304,23 @@ fn canonicalize_filter(filter: &BluetoothLEScanFilterInit) -> Fallible<Bluetooth
}
let mut map = HashMap::new();
for (key, bdfi) in manufacturer_data_map.iter() {
// Step 7.1-7.2.
// Step 7.1 - 7.2.
let manufacturer_id = match u16::from_str(key.as_ref()) {
Ok(id) => id,
Err(err) => return Err(Type(format!("{} {} {}", KEY_CONVERSION_ERROR, key, err))),
};

// Step 7.3: No need to convert to IDL values since this is only used by native code.

// Step 7.4 -7.5.
// Step 7.4 - 7.5.
map.insert(manufacturer_id, try!(canonicalize_bluetooth_data_filter_init(bdfi)));
}
Some(map)
},
None => None,
};

// Step 8-9.
// Step 8 - 9.
let service_data = match filter.serviceData {
Some(ref service_data_map) => {
// Note: If service_data_map is empty, that means there are no key values in it.
@@ -336,7 +336,7 @@ fn canonicalize_filter(filter: &BluetoothLEScanFilterInit) -> Fallible<Bluetooth
_ => StringOrUnsignedLong::String(key.clone())
};

// Step 9.3-9.4.
// Step 9.3 - 9.4.
let service = try!(BluetoothUUID::service(service_name)).to_string();

// Step 9.5.
@@ -346,7 +346,7 @@ fn canonicalize_filter(filter: &BluetoothLEScanFilterInit) -> Fallible<Bluetooth

// Step 9.6: No need to convert to IDL values since this is only used by native code.

// Step 9.7 -9.8.
// Step 9.7 - 9.8.
map.insert(service, try!(canonicalize_bluetooth_data_filter_init(bdfi)));
}
Some(map)
@@ -404,7 +404,7 @@ impl BluetoothMethods for Bluetooth {

// Step 2.
self.request_bluetooth_devices(&p, &option.filters, &option.optionalServices);
//Note: Step 3-4. in response function, Step 5. in handle_response function.
//Note: Step 3 - 4. in response function, Step 5. in handle_response function.
return p;
}

@@ -416,7 +416,7 @@ impl AsyncBluetoothListener for Bluetooth {
fn handle_response(&self, response: BluetoothResponse, promise_cx: *mut JSContext, promise: &Rc<Promise>) {
match response {
// https://webbluetoothcg.github.io/web-bluetooth/#request-bluetooth-devices
// Step 13-14.
// Step 13 - 14.
BluetoothResponse::RequestDevice(device) => {
let mut device_instance_map = self.device_instance_map.borrow_mut();
if let Some(existing_device) = device_instance_map.get(&device.id.clone()) {
@@ -78,6 +78,7 @@ impl BluetoothDeviceMethods for BluetoothDevice {

// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothdevice-gatt
fn Gatt(&self) -> Root<BluetoothRemoteGATTServer> {
// TODO: Step 1 - 2: Implement the Permission API.
self.gatt.or_init(|| {
BluetoothRemoteGATTServer::new(&self.global(), self)
})
@@ -103,24 +103,36 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris

#[allow(unrooted_must_root)]
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptor
// https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
fn GetDescriptor(&self, descriptor: BluetoothDescriptorUUID) -> Rc<Promise> {
let p = Promise::new(&self.global());
let p_cx = p.global().get_cx();

// Step 1.
let uuid = match BluetoothUUID::descriptor(descriptor) {
Ok(uuid) => uuid.to_string(),
Err(e) => {
p.reject_error(p_cx, e);
return p;
}
};

// Step 2.
if uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) {
p.reject_error(p_cx, Security);
return p;
}

// Step 3 - 4.
if !self.Service().Device().Gatt().Connected() {
p.reject_error(p_cx, Network);
return p;
}

// TODO: Step 5: Implement representedService internal slot for BluetoothRemoteGATTService.

// Note: Steps 6 - 7 are implemented in components/bluetooth/lib.rs in get_descriptor function
// and in handle_response function.
let sender = response_async(&p, self);
self.get_bluetooth_thread().send(
BluetoothRequest::GetDescriptor(self.get_instance_id(), uuid, sender)).unwrap();
@@ -129,13 +141,15 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris

#[allow(unrooted_must_root)]
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptors
// https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
fn GetDescriptors(&self,
descriptor: Option<BluetoothDescriptorUUID>)
-> Rc<Promise> {
let p = Promise::new(&self.global());
let p_cx = p.global().get_cx();
let mut uuid: Option<String> = None;
if let Some(d) = descriptor {
// Step 1.
uuid = match BluetoothUUID::descriptor(d) {
Ok(uuid) => Some(uuid.to_string()),
Err(e) => {
@@ -144,16 +158,24 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
}
};
if let Some(ref uuid) = uuid {
// Step 2.
if uuid_is_blocklisted(uuid.as_ref(), Blocklist::All) {
p.reject_error(p_cx, Security);
return p;
}
}
};

// Step 3 - 4.
if !self.Service().Device().Gatt().Connected() {
p.reject_error(p_cx, Network);
return p;
}

// TODO: Step 5: Implement representedService internal slot for BluetoothRemoteGATTService.

// Note: Steps 6 - 7 are implemented in components/bluetooth/lib.rs in get_descriptors function
// and in handle_response function.
let sender = response_async(&p, self);
self.get_bluetooth_thread().send(
BluetoothRequest::GetDescriptors(self.get_instance_id(), uuid, sender)).unwrap();
@@ -170,18 +192,31 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
fn ReadValue(&self) -> Rc<Promise> {
let p = Promise::new(&self.global());
let p_cx = p.global().get_cx();

// Step 1.
if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Reads) {
p.reject_error(p_cx, Security);
return p;
}

// Step 2.
if !self.Service().Device().Gatt().Connected() {
p.reject_error(p_cx, Network);
return p;
}

// TODO: Step 3 - 4: Implement representedCharacteristic internal slot for BluetoothRemoteGATTCharacteristic.

// TODO: Step 5: Implement the `connection-checking-wrapper` algorithm for BluetoothRemoteGATTServer.

// Step 5.1.
if !self.Properties().Read() {
p.reject_error(p_cx, NotSupported);
return p;
}

// Note: Remaining substeps of Step 5 are implemented in components/bluetooth/lib.rs in readValue function
// and in handle_response function.
let sender = response_async(&p, self);
self.get_bluetooth_thread().send(
BluetoothRequest::ReadValue(self.get_instance_id(), sender)).unwrap();
@@ -193,25 +228,39 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
fn WriteValue(&self, value: Vec<u8>) -> Rc<Promise> {
let p = Promise::new(&self.global());
let p_cx = p.global().get_cx();

// Step 1.
if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Writes) {
p.reject_error(p_cx, Security);
return p;
}

// Step 2 - 3.
if value.len() > MAXIMUM_ATTRIBUTE_LENGTH {
p.reject_error(p_cx, InvalidModification);
return p;
}

// Step 4.
if !self.Service().Device().Gatt().Connected() {
p.reject_error(p_cx, Network);
return p;
}

// TODO: Step 5 - 6: Implement representedCharacteristic internal slot for BluetoothRemoteGATTCharacteristic.

// TODO: Step 7: Implement the `connection-checking-wrapper` algorithm for BluetoothRemoteGATTServer.

// Step 7.1.
if !(self.Properties().Write() ||
self.Properties().WriteWithoutResponse() ||
self.Properties().AuthenticatedSignedWrites()) {
p.reject_error(p_cx, NotSupported);
return p;
}

// Note: Remaining substeps of Step 7 are implemented in components/bluetooth/lib.rs in writeValue function
// and in handle_response function.
let sender = response_async(&p, self);
self.get_bluetooth_thread().send(
BluetoothRequest::WriteValue(self.get_instance_id(), value, sender)).unwrap();
@@ -223,22 +272,32 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
fn StartNotifications(&self) -> Rc<Promise> {
let p = Promise::new(&self.global());
let p_cx = p.global().get_cx();

// Step 1.
if uuid_is_blocklisted(self.uuid.as_ref(), Blocklist::Reads) {
p.reject_error(p_cx, Security);
return p;
}
// Step 3.

// TODO: Step 2 - 3: Implement representedCharacteristic internal slot for BluetoothRemoteGATTCharacteristic.

// Step 4.
if !(self.Properties().Notify() ||
self.Properties().Indicate()) {
p.reject_error(p_cx, NotSupported);
return p;
}

// TODO: Step 5: Implement `active notification context set` for BluetoothRemoteGATTCharacteristic.

// Step 6.
if !self.Service().Device().Gatt().Connected() {
p.reject_error(p_cx, Network);
return p;
}

// Note: Steps 7 - 11 are implemented in components/bluetooth/lib.rs in enable_notification function
// and in handle_response function.
let sender = response_async(&p, self);
self.get_bluetooth_thread().send(
BluetoothRequest::EnableNotification(self.get_instance_id(),
@@ -252,6 +311,12 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
fn StopNotifications(&self) -> Rc<Promise> {
let p = Promise::new(&self.global());
let sender = response_async(&p, self);

// TODO: Step 1 - 4: Implement representedCharacteristic internal slot and
// `active notification context set` for BluetoothRemoteGATTCharacteristic,

// Note: Part of Step 4 and Step 5 are implemented in components/bluetooth/lib.rs in enable_notification
// function and in handle_response function.
self.get_bluetooth_thread().send(
BluetoothRequest::EnableNotification(self.get_instance_id(),
false,
@@ -266,6 +331,9 @@ impl BluetoothRemoteGATTCharacteristicMethods for BluetoothRemoteGATTCharacteris
impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic {
fn handle_response(&self, response: BluetoothResponse, promise_cx: *mut JSContext, promise: &Rc<Promise>) {
match response {
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptor
// https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
// Step 7.
BluetoothResponse::GetDescriptor(descriptor) => {
let context = self.service.get().get_device().get_context();
let mut descriptor_map = context.get_descriptor_map().borrow_mut();
@@ -279,6 +347,9 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic {
descriptor_map.insert(descriptor.instance_id, MutHeap::new(&bt_descriptor));
promise.resolve_native(promise_cx, &bt_descriptor);
},
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-getdescriptors
// https://webbluetoothcg.github.io/web-bluetooth/#getgattchildren
// Step 7.
BluetoothResponse::GetDescriptors(descriptors_vec) => {
let mut descriptors = vec!();
let context = self.service.get().get_device().get_context();
@@ -300,17 +371,40 @@ impl AsyncBluetoothListener for BluetoothRemoteGATTCharacteristic {
}
promise.resolve_native(promise_cx, &descriptors);
},
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-readvalue
BluetoothResponse::ReadValue(result) => {
// TODO: Step 5.5.1: Implement activeAlgorithms internal slot for BluetoothRemoteGATTServer.

// Step 5.5.2.
// TODO(#5014): Replace ByteString with ArrayBuffer when it is implemented.
let value = ByteString::new(result);
*self.value.borrow_mut() = Some(value.clone());

// Step 5.5.3.
self.upcast::<EventTarget>().fire_bubbling_event(atom!("characteristicvaluechanged"));

// Step 5.5.4.
promise.resolve_native(promise_cx, &value);
},
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-writevalue
BluetoothResponse::WriteValue(result) => {
// TODO: Step 7.5.1: Implement activeAlgorithms internal slot for BluetoothRemoteGATTServer.

// Step 7.5.2.
// TODO(#5014): Replace ByteString with an ArrayBuffer wrapped in a DataView.
*self.value.borrow_mut() = Some(ByteString::new(result));

// Step 7.5.3.
promise.resolve_native(promise_cx, &());
},
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-startnotifications
// https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-stopnotifications
BluetoothResponse::EnableNotification(_result) => {
// (StartNotification) TODO: Step 10: Implement `active notification context set`
// for BluetoothRemoteGATTCharacteristic.

// (StartNotification) Step 11.
// (StopNotification) Step 5.
promise.resolve_native(promise_cx, self);
},
_ => promise.reject_error(promise_cx, Error::Type("Something went wrong...".to_owned())),
Oops, something went wrong.

0 comments on commit 8dd100f

Please sign in to comment.
You can’t perform that action at this time.