I'm trying to write a web app to interact with a Eddystone beacon. The beacon advertise a URL for the app and exposes a service and 2 characteristics.
My device has the following services and characteristics as shown by gatttool on linux
$ gatttool -I
[00:1A:7D:DA:71:15][LE]> connect 00:1A:7D:DA:71:15
Attempting to connect to 00:1A:7D:DA:71:15
Connection successful
[00:1A:7D:DA:71:15][LE]> primary
attr handle: 0x0001, end grp handle: 0x0005 uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x0006, end grp handle: 0x0009 uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle: 0x000a, end grp handle: 0x0012 uuid: ba42561b-b1d2-440a-8d04-0cefb43faece
[00:1A:7D:DA:71:15][LE]> characteristics
handle: 0x0002, char properties: 0x02, char value handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb
handle: 0x0004, char properties: 0x02, char value handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb
handle: 0x0007, char properties: 0x20, char value handle: 0x0008, uuid: 00002a05-0000-1000-8000-00805f9b34fb
handle: 0x000b, char properties: 0x1a, char value handle: 0x000c, uuid: 6bcb06e2-7475-42a9-a62a-54a1f3ce11e6
handle: 0x000f, char properties: 0x1a, char value handle: 0x0010, uuid: 6bcb06e2-7475-42a9-a62a-54a1f3ce11e5
[00:1A:7D:DA:71:15][LE]
I'm working from the example here
if (navigator.bluetooth) {
console.log("bluetooth found");
navigator.bluetooth.requestDevice({
filters: [{
services: ['ba42561b-b1d2-440a-8d04-0cefb43faece']
}]
})
.then(device => {
bluetoothDevice = device;
console.log(device.name);
console.log(device.uuids);
device.connectGATT();
})
.then(server => {
return server.getPrimaryService('ba42561b-b1d2-440a-8d04-0cefb43faece');
})
.then(service => {
return service.getCharacteristic('6bcb06e2-7475-42a9-a62a-54a1f3ce11e6');
})
.then( characteristic => {
var toggleOn = new Uint8Array([1]);
return characteristic.writeValue(toggleOn);
})
.catch(error => {
console.log("error:- " + error);
});
}
This code never finds the device. If I change the filter to use the namePrefix
it finds the device but only lists one of the services and not the one I'm interested in.
Anybody know what I'm doing wrong with the discovery and finding the right services?
The filters
argument filters devices primarily based on the advertising packets they send, rather than the services actually exposed by the devices' gatt servers. So, if the beacon just advertises a url and its name, you're unlikely to find it by filtering for particular service UUIDs.
I say "unlikely" instead of "you won't" because if you've already connected to the device once, your system might cache the set of services the device actually exposes and then use those to match the filter.
If you switch to the namePrefix
argument, you'll need to remember to list all the services you want to use in optionalServices
:
navigator.bluetooth.requestDevice({
filters: [{
namePrefix: 'something',
}],
optionalServices: ['ba42561b-b1d2-440a-8d04-0cefb43faece']
});