-
Notifications
You must be signed in to change notification settings - Fork 189
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
Specify a Bluetooth Scanning API. #239
Conversation
</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. |
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. |
</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.
@g-ortuno points out that this is unimplementable in the Android API.
@beaufortfrancois @jracle do you think it's better for this to work inconsistently depending on the platform, or to leave out the connectable bit until Android adds support for it?
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.
@jyasskin my proposal is to add a nullable boolean to BluetoothDevice object ( see #253 )
interface BluetoothDevice {
...
readonly attribute boolean? connectable;
};
I'm frustrated by those platform inconsistencies, but due to them, I'm more comfortable leaving out the connectable filter for now, and adding above proposal instead. In that case, we would have a consistent behavior, checking for the boolean before attempting connection.
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.
Ok. I'll leave it out of the filters for now, and we can keep figuring out what to do on #253.
Hi,
|
My thought with those fields was that we could later extend them to whole objects with all the complexity of https://developer.android.com/reference/android/bluetooth/le/ScanFilter.Builder.html, so I wanted to use the same names as the AD field. That said, I can see some sense in using a different name for the shorthand. While I mull it over, 👍 this comment to prefer |
I believe the spec consistently refers to advertising events instead of either advertising packets or scan responses, which comes from BT4.2 1.A.1.2 saying that an advertising event comprises an advertising packet and resulting scan requests and responses, on each of the three advertising channels. So I think this is ok as-is, and that using "scan events" would diverge too much from the Bluetooth spec. |
Only
Yes, I plan to add a way to get a |
I can definitely see the value in being able to specify a mask in manufacturer data. If you are planning on supporting that in the future. Maybe it's better that we define the .manufacturerData filter to be a structure that contains (at this time only) manufacturer ID? If you don't opt for this, then it may be better to still keep the manufacturerId as the name of the field, then you can do a conversion or "deprecated detection" once you have a new version of the API. |
Isn't it implicit that requestLEScan filters are implemendted in software (browser) anyways? That way we are not limited to what the underlying bluetooth API implements. requestDevice is implemented in software, right? If we implement it in software, then we can have multiple sessions doing scans and filters of their own irrespective of what the adapter/native is filtering. Also, iOS and BluZ only supports limited (and global) filtering options, which typically include only service UUID and/or a couple of other minor things. How do we deal with that then? If this filter gets implemented in software, it seems to gravitate towards making filtering options and algorithm the same for both requestDevice and requestLEScan. |
This doesn't cover scanning from a service worker yet. Fixes WebBluetoothCG#191.
Before, filters: [{}] would have been a completely open filter, but that seems too subtle.
The browser has to fill in any filters that the platform doesn't provide, but the main reason to have a declarative system at all is so we can take advantage of OS and hardware support for the filters. Otherwise, we'd just let Javascript do the filtering. On the other hand, having exactly the same filters for both systems would make them easier to understand, so I guess I'm not really opposed to doing that. |
and remove some unnecessary definitions.
The latest commits rename |
Only doing filtering perhaps would be possible, but I guess if performance and security is a concern I would leave the filtering up to the underline stack so we don't spam the system with IPC messages containing advertisement reports that the browser may not be able to understand. |
The diversity of platforms means we have to expect to do some filtering in the browser. We should try to pass off as much as possible to the underlying platform though. Is the security issue just that processes that can intercept IPC messages will find out the advertisements? Can't such privileged processes create their own advertisement requests anyway? |
I'm going to commit the current state. Please file issues when you notice them, and I'll fix them in smaller patches. |
No, I meant that the browser itself is not a privileged application which shouldn't be given direct access for things that have shared control such as scanning. This is actually acknowledge in the Android API: https://developer.android.com/reference/android/bluetooth/le/BluetoothLeScanner.html
In Linux this would translate to have CAP_NET_ADMIN a.k.a root and then using the kernel Bluetooth Management socket to control the scanning parameters and results. |
Ok, yes, I expect the non-system-supported filters to have to run at a lower power use and/or stop while the browser's in the background. Chrome does take the BLUETOOTH_ADMIN permission in order to make |
Hi, I wanted to know if there is any method to get the UUID, Major, Minor and other services like Battery and signal strength of the signal received without requiring to connect with the device. We wanted to use beacons which would normally be in a unconnectable sleep mode. From what I understand requestLEScan would be a good method to use however in chrome console this method is not showing up and is undefined within navigator.bluethooth |
@nikhilkashid Right, requestLEScan is the right method for this. Sadly it's not yet implemented in Chrome. https://github.com/WebBluetoothCG/web-bluetooth/blob/master/implementation-status.md#scanning-api |
Thank you @g-ortuno. We wanted to run a few experiments and view how requestLEScan would work. Is there a way we can try doing this? |
@nikhilkashid You can't for now. |
@jyasskin @beaufortfrancois HI, I've a question, devices without Peripheral mode also supports Web Bluetooth API ? Does Web Bluetooth API works with the BLE phones with central mode only(without peripheral mode). I want to send sensor data to web page using Web Bluetooth API. My phone has 4.2 BLE (Not peripheral mode) is not detecting by API. I tried on some other phone which supports peripheral mode, and it appears in the list. I am using Ubuntu 16.04 LTE, Google chrome 55 (developer edition), enabled Bluetooth flag, Also follow guidelines [(https://acassis.wordpress.com/2016/06/28/how-to-get-chrome-web-bluetooth-working-on-linux/)] I am newbie, kindly need your help Please. |
@f138150 Peripheral mode is how devices (heart rate monitors, beacons, etc.) tell nearby devices of their presence. If a device doesn't support Peripheral mode then it can't communicate its presence so the API won't be able to find it. That said, it's surprising a 4.2 BLE device doesn't support Peripheral mode. What device is it? |
@beaufortfrancois would you be able to provide any rough estimate of when we could expect watchAdvertisements/scanning to be implemented? Wouldn't this be incredibly useful in combination with a Physical Web referral in a use-case where the user wants to easily distinguish between several devices (say parking meters) by distance (rssi) and pinpoint the one he's right next to. I'm new to the space; please correct me if I'm misunderstanding. |
@arashd I'm eager as well to see this coming ;) |
@beaufortfrancois I understand! |
@arashd, there's no active chromium work on scanning now. Still desired,
and there's still active Web Bluetooth work, but scanning will take a
while. https://www.chromium.org/teams/device-team/device-okrs were our
stated goals ~3 months ago. We're not hitting the Bluetooth targets due to
other priorities. We'll be publishing OKRs again in July.
…On Thu, Jun 8, 2017 at 10:54 PM, Arash Delijani ***@***.***> wrote:
@beaufortfrancois <https://github.com/beaufortfrancois> I understand!
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#239 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAXnm9ZgA8F9_IIhHpD-Luz_F3JTMaHqks5sCN4zgaJpZM4IaZQb>
.
|
Thank you for that clarification @scheib. I'll keep an eye out for the new OKRs! |
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