- From: Jeffrey Yasskin <jyasskin@google.com>
- Date: Thu, 31 Mar 2016 16:41:22 -0700
- To: François Beaufort 🇫🇷 <fbeaufort@google.com>
- Cc: "Von Dentz, Luiz" <luiz.von.dentz@intel.com>, Rob Moran <Rob.Moran@arm.com>, public-web-bluetooth <public-web-bluetooth@w3.org>, "Christiansen, Kenneth R" <kenneth.r.christiansen@intel.com>
- Message-ID: <CANh-dXnAi_YHsc53k1iSt88MxrLxsVpT+4bwtLyLpzv29DNT7Q@mail.gmail.com>
I think we're going to want to treat things as-if-bonded with 1 queued notification, in the long run, but so far the folks writing sample apps are asking for as-if-non-bonded, and that's simpler for Chrome to implement, so let's go with that for now, until we start getting complaints. I've filed https://github.com/WebBluetoothCG/web-bluetooth/issues/226 so I remember to spec this. On Thu, Mar 31, 2016 at 7:47 AM, François Beaufort 🇫🇷 < fbeaufort@google.com> wrote: > 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 23:42:12 UTC