-
Notifications
You must be signed in to change notification settings - Fork 195
Specify a Bluetooth Scanning API. #239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
scanning.bs
Outdated
</p> | ||
<ol> | ||
<li> | ||
If |event| doesn't <a for="BluetoothLEScanFilter">match</a> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that this leaves no way to do a completely open scan. It has to be filtered for some UUID or Manufacturer ID. Is that OK, or do we need an extra filter type to match everything? (I don't want to make no-filters the sign for completely-open because that makes the API non-monotonic: reducing the number of filters would match less, less, less, and then more advertisements.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to #234 I think developers will have good use cases for matching everything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is BluetoothLEScanOptions.acceptAllAdvertisements
now.
I wonder why developers would use |
@beaufortfrancois At the moment, |
This makes more sense now ;) So once you have a navigator.bluetooth.requestLEScan({
filters: [{manufacturerData: 0x004C}]
}).then(() => {
navigator.bluetooth.addEventListener('advertisementreceived', event => {
if (!event.device.gatt) {
// How do I connect to this device specifically?
}
})
}) |
There's no API for that yet, and I've mailed the security UI folks to ask their opinion on it. The benefits of the chooser are that 1) the user has to pay enough attention to make a choice, and 2) the user can override the page's idea of which device is best. If we ensure that exactly one device appears in the chooser that opens as a result of an advertisement, then we lose both of those. On the other hand, we might be able to add a |
Some devices may use non-connectable flag, e.g. broadcaster, in that case requestDevice might actually not work in the end so perhaps we need some field to indicate this to the application. |
I think we don't need to distinguish between ADV_IND and ADV_DIRECT_IND: the difference is whether the controller can send a SCAN_REQ in response, but the advertising event should just combine data from the advertisement with the SCAN_RSP, so websites don't need to react to the difference. Do we want to mark this in the advertising event or on the device? I'd initially thought the advertising event, but since we always have to wait for a subsequent advertisement in order to connect, it probably makes sense to turn it to 'true' on the device as soon as we see any connectable advertisement from that device. |
scanning.bs
Outdated
navigator.bluetooth.<a idl for="Bluetooth" lt="requestLEScan()">requestLEScan</a>({ | ||
filters: [{manufacturerData: 0x004C}], | ||
options: { | ||
keepDuplicates: true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/keepDuplicates/keepRepeatedDevices/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, thanks.
04e61ff
to
d971187
Compare
Im quite concerned with these APIs, it is quite low level which may lead us to need to expose scanning intervals which depending on the duty cycle can block other traffic such as GATT to happen. Im also not quite sure how to interpret the aggregation of scan response, there could be other advertisements in the meantime shall the stacks hold the results until it gets a scan response, for requestDevice that may be fine because the API don't except individual reports just a device, but here the holding of events may change the sequence. Perhaps if this is done via device object, so the scan response wouldn't matter and only advertisement would actually cause events. |
How about timeout? Is the call expected to constantly scan or stop after sometime? Some of the devices(iOS for example) doesn't constantly scan and backs off after some period. Is the same expected here? |
Is the event expected to have parsed data with separate values for name etc., or raw data and JS side to interpret it? |
In order to compete with [Android](https://developer.android.com/reference/android/bluetooth/le/ScanCallback.html#onScanResult%28int, android.bluetooth.le.ScanResult%29) and Mac, I think BlueZ is going to have to report information with this much detail. We can limit the load websites are allowed to put on the system, but beacon use cases definitely need to enable duplicate events, and seem to need the timing of the last advertisement in order to know when things are stale. If BlueZ doesn't start reporting advertising events, we can infer some of this from changes in the Device object, but it's going to work less well than other platforms.
It seems ok to delay the event until after the SCAN_RSP, although maybe we'll find use cases that prefer to get both events. The uses will have to be ok with whatever Android and Mac do, since it's harder to change them.
I could let the UA stop a scan if it's been running "too long". Advertisements aren't reliable anyway, so iOS's periodic scan probably already satisfies the spec, but I could add explicit wording to allow that. I don't think having folks pass a timeout to
Parsed data. See https://webbluetoothcg.github.io/web-bluetooth/#fire-an-advertisementreceived-event for the parsing. We're nervous about exposing the raw data, both because we can't implement that on Mac, and because some of the fields, like the public addresses, hold data that we're not sure websites should know. |
BlueZ is used in very different systems as Android, it is quite common to have multiple applications using the API in parallel, perhaps we could compare it to Mac but looking at its API it seems to be very similar to the kind of access BlueZ offers with StartDiscovery combined with SetDiscoveryFilter. Btw, it is already possibility to enable duplicated reports, in that case the RSSI property is emitted every time we receive a report from the peripheral, similar to what is stated in the Mac documentation.
Well we do wait for the scan response so the applications can see the device name, etc, which is quite convenient for requestDevice but it perhaps wouldn't be for requestLEScan, anyway as long as it not strictly forbidden I guess we can live with that. Btw, we also have to keep in mind there could be peripherals connected which makes requestLEScan even less reliable as it cannot use very high scan duty cycle in such cases. |
scanning.bs
Outdated
</li> | ||
<li> | ||
If <code>|filter|.connectable</code> is `true`, | ||
|event| has either the <a>ADV_IND</a> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't cover scanning from a service worker yet.
Fixes #191.
Previews at https://rawgit.com/jyasskin/web-bluetooth-1/scanning/scanning.html and https://rawgit.com/jyasskin/web-bluetooth-1/scanning/index.html#bluetoothdevice