Re: Should we expose all devices as if they were bonded?

On Thu, Mar 17, 2016 at 4:07 AM, Von Dentz, Luiz <luiz.von.dentz@intel.com>
wrote:
> Hi Jeffrey,
>
>
> How exactly would one queue if the state should reset to unsubscribed?
> Or do you mean that any and all notification/indication shall be
> queued and replayed to the application/page once it subscribe again?

If we treat devices as not-bonded, I think we get the following flow:

  await device.gatt.connect();
  let service = await device.gatt.getPrimaryService('uuid');
  let characteristic = await service.getCharacteristic('uuid2');
  characteristic.addEventListener('characteristicvaluechanged', value =>
console.log(value));
  // Get some events
  device.gatt.disconnect();
  // Wait some time; device queues some notifications/indications
internally.
  await device.gatt.connect();
  service = await device.gatt.getPrimaryService('uuid');
  // Oops, device delivers queued notifications to the browser here,
  // before the site has subscribed.
  characteristic = await service.getCharacteristic('uuid2');
  characteristic.addEventListener('characteristicvaluechanged', value =>
console.log(value));
  // We get all the notifications sent after this point.

If we treat devices as bonded, I think we get the following flow instead:

  await device.gatt.connect();
  let service = await device.gatt.getPrimaryService('uuid');
  let characteristic = await service.getCharacteristic('uuid2');
  characteristic.addEventListener('characteristicvaluechanged', value =>
console.log(value));
  // Get some events
  device.gatt.disconnect();
  // Wait some time; device queues some notifications/indications
internally.
  await device.gatt.connect();
  // Don't need to re-discover services and characteristics.
  // Device delivers queued notifications/indications, and we get all of
them.


Kenneth is totally right though. In the bonded case, if tab 1 runs:

  await device.gatt.connect();
  let service = await device.gatt.getPrimaryService('heart_rate');
  let characteristic = await
service.getCharacteristic('heart_rate_measurement');
  characteristic.addEventListener('characteristicvaluechanged', value =>
console.log(value));
  device.gatt.disconnect();

And then tab 2 runs:
  await device.gatt.connect();
  let service = await device.gatt.getPrimaryService('heart_rate');
  let characteristic = await
service.getCharacteristic('heart_rate_measurement');
  characteristic.addEventListener('characteristicvaluechanged', value =>
console.log(value));

Later, tab 1 runs:
  await device.gatt.connect();

If we want to really emulate the bonded state, we need to deliver all the
heart rate measurements that were delivered to tab 2, also to tab 1. We
might even need to do this if tab 1 is closed and then re-opened. That's
potentially a lot of storage.

However, maybe it makes sense to only deliver the most recent
notification/indication for any particular subscribed characteristic. The
Bluetooth Core spec leaves device queuing behavior up to higher-level
specs, so it's not clear if this will serve everyone's purposes, but it
works for the case Luiz brought up, and bounds the amount of data we need
to store.

Jeffrey

> If I would read this for the stack point of view it means it shall
> remember the subscriptions so that the UA can queue them, which sounds
> the same as been 'bounded', we actually use terms like
> temporary/persistent device in BlueZ since 'Bounded' refer to
> link-keys being stored which is different than what we are trying to
> accomplished.
>
> In case someone is wondering how persistent/temporary devices works in
> BlueZ, any action that triggers a connection to a certain device would
> make the device persistent including its attribute cache. This is
> actually not only useful for not losing early notifications but also
> to automatically reconnect using passive scanning, though the later
> actually requires the application to register an agent with
> RegisterProfile:
> https://git.kernel.org/cgit/bluetooth/bluez.git/tree/doc/gatt-api.txt
>
> On Thu, Mar 17, 2016 at 12:39 PM, Christiansen, Kenneth R
> <kenneth.r.christiansen@intel.com> wrote:
>> At least for development purposes it would be nice to have them
unbounded (but I guess we could have a way to change the behavior in
devtools when it is open)
>>
>> I am not sure whether I want the notifications to be queued, at least
not by default. Think about something like temperature change and heart
rate measurements.
>>
>> Kenneth
>>
>>> -----Original Message-----
>>> From: Jeffrey Yasskin [mailto:jyasskin@google.com]
>>> Sent: Thursday, March 17, 2016 2:22 AM
>>> To: public-web-bluetooth <public-web-bluetooth@w3.org>
>>> Subject: Should we expose all devices as if they were bonded?
>>>
>>> Two issues came up recently where the Bluetooth spec defines different
>>> behavior depending on whether a device is bonded.
>>>
>>> In https://groups.google.com/a/chromium.org/d/topic/web-
>>> bluetooth/PQpZAFNlvT4/discussion
>>> and https://github.com/thegecko/web-bluetooth-dfu/issues/12, Luiz is
>>> suggesting that we have Web Bluetooth remember services,
characteristics,
>>> and descriptors across disconnection, even when there's no physical
bond.
>>> That's similar to treating the web site as bonded to the peripheral.
We'd in
>>> the case of no bond, we'd re-discover the known services, etc. after re-
>>> connecting, and send service-changed events for the ones that have
>>> changed. We'd also allow users to hold onto Service, etc. objects across
>>> disconnect/connect pairs, and continue using the objects afterward. On
the
>>> other hand, if we treat pages as un-bonded, users would need to re-fetch
>>> services, etc. before using them after a disconnect/reconnect pair.
>>>
>>> In https://github.com/WebBluetoothCG/web-bluetooth/issues/220 and
>>> https://bugs.chromium.org/p/chromium/issues/detail?id=589796, we have
>>> to decide whether users need to re-subscribe to notifications after a
>>> disconnection. If we treat pages as bonded, the notification state
should
>>> persist across disconnections. If we treat pages as non-bonded, the
state
>>> should reset to unsubscribed on disconnection. (3.G.3.3.3.3) If we keep
the
>>> page subscribed across disconnection, users might expect us to queue
>>> notifications, or at least indications, and deliver them the next time
the page
>>> is connected. Should we do the same if the page is unloaded? That kind
of
>>> unbounded queueing seems problematic.
>>>
>>> And, of course, beyond always treating a page as bonded or not-bonded,
we
>>> could make the page's bonded-ness depend on the presence of a physical
>>> bond.
>>>
>>> Are there other areas where treating the page as having or not-having a
>>> bond would cause divergent behavior?
>>>
>>> Which behavior do you folks think makes more sense for the web API?
>>>
>>> Jeffrey
>>

Received on Thursday, 17 March 2016 18:16:34 UTC