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

On Thu, Mar 17, 2016 at 10:12 AM, Rob Moran <Rob.Moran@arm.com> wrote:

> I agree that registering service changed events is the same in both cases,
> but having to register for these across re-connects feels unintuitive
> versus scanning after a re-connect.
> I am assuming that discovering services again would still return the
> cached ones, however.
>

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

  await device.gatt.connect();
  // Depends on https://github.com/WebBluetoothCG/web-bluetooth/issues/53:
  device.addEventListener('servicechanged', change => console.log(change));
  let service = await device.gatt.getPrimaryService('uuid');
  let characteristic = await service.getCharacteristic('uuid2');
  device.gatt.disconnect();
  await device.gatt.connect();
  await service.getCharacteristic('uuid2') // Throws InvalidStateError:
service no longer exists?
  let service2 = await device.gatt.getPrimaryService('uuid'); // Waits
until discovery process finishes.
  service ?== service2; // ???
  device.gatt.disconnect();
  // 'uuid' service removed, replaced with 'uuid3' service.
  await device.gatt.connect();
  await service.getCharacteristic('uuid2') // Throws InvalidStateError:
service no longer exists?
  let service3 = await device.gatt.getPrimaryService('uuid'); //
NotFoundError.
  let service4 = await device.gatt.getPrimaryService('uuid3');
  service4 !== service2;

I think we wouldn't get any 'servicechanged' events in this scenario, since
the changes happen when no services are known.


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

  await device.gatt.connect();
  // Depends on https://github.com/WebBluetoothCG/web-bluetooth/issues/53:
  device.addEventListener('servicechanged', change => console.log);
  let service = await device.gatt.getPrimaryService('uuid');
  let characteristic = await service.getCharacteristic('uuid2');
  let value = await characteristic.readValue();
  device.gatt.disconnect();
  await device.gatt.connect();
  characteristic === await service.getCharacteristic('uuid2');
  service === await device.gatt.getPrimaryService('uuid');
  await device.gatt.getPrimaryService('uuid3');  // NotFoundError
  device.gatt.disconnect();
  // 'uuid' service removed, replaced with 'uuid3' service.
  await device.gatt.connect();
  // 'servicechanged' fired some time after this. Let's say it doesn't
arrive for a while.
  service === await device.gatt.getPrimaryService('uuid');  // Cached.
  characteristic === await service.getCharacteristic('uuid2');  // Cached.
  let value = await characteristic.readValue(); // InvalidStateError? What
GATT error does this cause?
  await device.gatt.getPrimaryService('uuid3');  // Cached NotFoundError.
  // Say 'servicechanged' arrives now. Listener logs it to console.
  let service2 = await device.gatt.getPrimaryService('uuid3');  // Succeeds.
  let service3 = await device.gatt.getPrimaryService('uuid'); //
NotFoundError.


Does that all make sense? Does it convince anyone to prefer as-if-bonded or
as-if-not-bonded?

Jeffrey


> Rob
>
> Hi Rob,
>
> I really meant GATT notifications, even though advertise would
> probably make more sense but Im not sure it is supported in a lot of
> systems, certainly not Web Bluetooth. Anyway, I don't think suggesting
> to use advertise will make the problem go away as devices may already
> be in the market.
>
> Btw, the statement about having to register service changed events and
> possibly holding stale services is true in any case regardless if we
> persist the attributes or not because the device may change them while
> connected not only when it is offline.
>
> On Thu, Mar 17, 2016 at 1:47 PM, Rob Moran <Rob.Moran@arm.com> wrote:
> > Hi Luiz,
> >
> > I assume you are meaning devices such as eddystone beacons?
> > I'm not sure if the Web Bluetooth requestDevice() function is the best
> interface to observe these sorts of beacons, but is more geared towards
> connecting and interacting with devices.
> > For purely observing devices, I think another function alongside
> requestDevice() (observeDevices()?) may be a better approach which can
> maintain the cache required for these sorts of devices, is read-only and
> may not need the security restrictions of requestDevice().
> >
> > Specific scanning apps (such as the physical web app) may also be
> another option?
> >
> > ________________________________________
> > From: Von Dentz, Luiz <luiz.von.dentz@intel.com>
> > Sent: 17 March 2016 11:11
> > To: Rob Moran
> > Cc: Christiansen, Kenneth R; Jeffrey Yasskin; public-web-bluetooth
> > Subject: Re: Should we expose all devices as if they were bonded?
> >
> > Hi Rob,
> >
> > There are device that advertise, notify one value and disconnect,
> > which creates a race condition where the application/page may not be
> > quick enough to catch the value which is then lost as the device
> > disconnects immediately to save power.
> >
> > On Thu, Mar 17, 2016 at 1:06 PM, Rob Moran <Rob.Moran@arm.com> wrote:
> >>
> >> IMO having the device appear unbonded and requiring a user to
> re-discover services and re-register for events, etc. after a disconnect is
> a cleaner and more atomic approach.
> >> Requiring the user to register for service changed events and possibly
> holding stale services (as they may not exist after a reconnect) could
> create more edge cases and potential errors to cover.
> >>
> >> In this scenario, I think the item to persist between connections is
> the security context, so that any further reconnections don't require a
> user action to undertake, but still honour the original service / name
> filters.
> >>
> >> Cheers,
> >>
> >> Rob
> >> ________________________________________
> >> From: Christiansen, Kenneth R <kenneth.r.christiansen@intel.com>
> >> Sent: 17 March 2016 10:39
> >> To: Jeffrey Yasskin; public-web-bluetooth
> >> Subject: RE: Should we expose all devices as if they were bonded?
> >>
> >> 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
> >>
> >> IMPORTANT NOTICE: The contents of this email and any attachments are
> confidential and may also be privileged. If you are not the intended
> recipient, please notify the sender immediately and do not disclose the
> contents to any other person, use it for any purpose, or store or copy the
> information in any medium. Thank you.
> >>
> >>
> >
> > IMPORTANT NOTICE: The contents of this email and any attachments are
> confidential and may also be privileged. If you are not the intended
> recipient, please notify the sender immediately and do not disclose the
> contents to any other person, use it for any purpose, or store or copy the
> information in any medium. Thank you.
> >
>
> IMPORTANT NOTICE: The contents of this email and any attachments are
> confidential and may also be privileged. If you are not the intended
> recipient, please notify the sender immediately and do not disclose the
> contents to any other person, use it for any purpose, or store or copy the
> information in any medium. Thank you.
>
>

Received on Thursday, 17 March 2016 21:01:37 UTC