- From: François Beaufort 🇫🇷 <fbeaufort@google.com>
- Date: Thu, 31 Mar 2016 14:47:57 +0000
- To: Jeffrey Yasskin <jyasskin@google.com>, "Von Dentz, Luiz" <luiz.von.dentz@intel.com>
- Cc: Rob Moran <Rob.Moran@arm.com>, public-web-bluetooth <public-web-bluetooth@w3.org>, "Christiansen, Kenneth R" <kenneth.r.christiansen@intel.com>
- Message-ID: <CAPpwU5KN7kz9t0gp_qUFHoOy7EexLKVtAWtbypgp78Uj2KhNZw@mail.gmail.com>
What is the status on this? On Fri, Mar 18, 2016 at 8:18 PM Jeffrey Yasskin <jyasskin@google.com> wrote: > On Fri, Mar 18, 2016 at 7:57 AM, Von Dentz, Luiz > <luiz.von.dentz@intel.com> wrote: > > Hi Jeffrey, > > > > On Thu, Mar 17, 2016 at 11:00 PM, Jeffrey Yasskin <jyasskin@google.com> > wrote: > >> 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. > > > > Well if that would be the case 'servicechanged' cannot be used for > > detecting new services since it appears to ignore any change outside > > the known range. > > In the design I've got so far, to detect a service you expect to be > added, you'd getPrimaryService('the-service'), catch the rejection if > it's not there, and then watch for 'servicechanged' to tell you it's > been added. Skipping the getPrimaryService() call could indeed cause > the browser to skip the 'servicechanged' event because of the rules in > > https://webbluetoothcg.github.io/web-bluetooth/#only-notify-for-requested-services > . > Those are there so the browser doesn't have to do a full discovery on > connect(). > > >> 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(); > > > > This seems to ignore that fact that the changes can happens while > > connected where the following events would be exactly the same. > > This example happens to show the change occurring while disconnected, > in order to highlight the difference from the as-if-non-bonded case. > If the change happens while the device is connected and after the > service has been retrieved during the current connection, I think the > bonded and non-bonded options act the same. Have I missed something? > > >> // '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? > > > > The main concept difference appears to be persistent cache vs > > temporary cache, the miss chance is slightly bigger on the former but > > handling is almost the same either way. > > I don't really follow, sorry. IIUC, the persistent/as-if-bonded option > guarantees sites don't miss a single notification sent right after the > connection is established, and allows sites to write less code, but > requires more code from the browser. The temporary/as-if-non-bonded > option allows missed notifications, but allows a simpler browser > implementation. > > > Btw, the persistent cache can > > be used to check the services matches during the connection phase > > which further reduces the chance of cache miss. > > I still think the persistent-but-non-bonded cache can fail to notice > added and removed characteristics within an existing service whose > range doesn't change. We don't need that to change in Bluez to > implement Web Bluetooth, since we can just blame any resulting bugs on > the user's platform, but I don't want to bake it into the web API. > > Jeffrey > > >> 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, 31 March 2016 14:48:37 UTC