Skip to content
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

Inject GATT descriptors #29

Merged
merged 1 commit into from
Jan 15, 2020
Merged

Conversation

svogl
Copy link

@svogl svogl commented Oct 11, 2019

We have a number of known BLE devices the we (re-)connect to often. Speeding up the connection setup phase is good for the user experience (less delay, less potential for packet loss), so we have extended noble a little to report the GATT data structures for services and characteristics and to initialize its inner workings with this data.

In order to not change default behavour, there are two new events one can listen for when discovering GATT entries, simply register them before the actual discovery call:

 peripheral.on('servicesDiscovered', (peripheral, services) => { ... }
 service.on('characteristicsDiscovered', (characteristics) => {...}

returns an array of services resp. characteristics including low-level information that can be used to initialize noble:

 const servs = [
        { "startHandle": 1, "endHandle": 4, "uuid": "1801" },
        { "startHandle": 5, "endHandle": 9, "uuid": "1800" },
        { "startHandle": 10, "endHandle": 29, "uuid": "180a" }]
 let serviceObjs =  noble.addServices(peripheralUuid, servs)

 const enviroChara = [
  { "startHandle": 53, "properties": 18, "valueHandle": 54, "uuid": "2a6d", "propsDecoded": ["read", "notify"], "rawProps": 18, "endHandle": 57 },
  { "startHandle": 58, "properties": 18, "valueHandle": 59, "uuid": "2a6e", "propsDecoded": ["read", "notify"], "rawProps": 18, "endHandle": 62 }]

 let characteristicsObjs = noble.addCharacteristics(peripheral.uuid, enviroService.uuid, enviroChara);

addServices returns an array of service objects, addCharacteristics an array of Characteristic objects that can be used to discover, subscribe for data etc.

@rzr
Copy link

rzr commented Oct 11, 2019

Thanks, can you try to split this change set into several pull requests on upstream too ?
Then update commit messages with "Forwarded: $url" meta info

Reviewers welcome too

Copy link

@mrstegeman mrstegeman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thoughts:

  1. I don't care for the naming of the new events. It seems like the original events were just misspelled, so adding these new events with the names the originals should have had is confusing. Why not just add the service/characteristic objects as additional data to the existing events? That should retain backwards compatibility while being more clear.
  2. Can you update the README and maybe add an example in examples/?
  3. It seems strange for a developer to have to reinitialize an object manually. Is there a way that noble could (optionally) cache these data structures internally, rather than forcing the developer to hold on to internal objects they can't do much with?

@svogl
Copy link
Author

svogl commented Oct 17, 2019

Thanks for your thoughts @mrstegeman, let me add my own:

  1. I don't care either, so if you have suggestions ( gatt.serviceDisvover? ) head on. I did not add it the original reasons as this is implementation specific (not every backend might expose it) and it is not necessary for normal operation, bloating objects and potentially causing confusion for normal app developers
  2. will add something later, sure
  3. Caching would be ideal, of course, but depends on the use-case; some devices change their GATT-descriptions on the fly for example, so this is a non-trivial subsystem on its own. We just wanted to get one (our) use case solved so other people can pick up work from here.
    S

}
console.log()

let temperatureChara = undefined
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it well named ?

Copy link

@rzr rzr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it would be better to have all temperature related code into a separate file ?

Please also submit upstream 1st

@svogl
Copy link
Author

svogl commented Oct 21, 2019

Maybe it would be better to have all temperature related code into a separate file ?

I intended to write a small but functional example. I don't think the effort of extracting 7 lines or so is worth a separate file. The point here is the difference in timing of the same task under different conditions (with cache / without).

Please also submit upstream 1st

I'm commiting to my fork which you are seeing automatically. This is fine for me, esp. as this allows you and others to comment here. I'd like to push an agreed-upon version upstream and not double work on every commit.

@rzr
Copy link

rzr commented Oct 22, 2019

I suggested to isolate temperature in separate place to make it scalable for other types...

@svogl
Copy link
Author

svogl commented Oct 22, 2019

Well then let me suggest to use an environment variable, that way you can change it on the fly, as in
SENSOR='Pressure' node cache-gatt-discovery.js

If you have something else in mind, suggestion welcome :)

@@ -88,7 +94,7 @@ let findServices = function (noble, peripheral) {

peripheral.discoverServices([], (error, services) => {

let temperatureCharacteristic = undefined
let sensorCharacteristic = undefined
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be set explicitly ?

@@ -8,7 +8,13 @@
var noble = require('../index');
const fs = require('fs');

// the sensor value to scan for, number of bits and factor for displaying it
const CHANNEL = process.env['CHANNEL'] ? process.env['CHANNEL'] : 'Temperature'
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or just "Unknown"

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer a working example... at least for parts of the universe ;)

Copy link

@rzr rzr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this, what about other reviewers ?

@readeral
Copy link

Seems excellent - anything else holding this back?

@rzr
Copy link

rzr commented Nov 14, 2019

Unless there is any negative feedback I can merge this next month

cc: @mrstegeman, @gfwilliams

also @readeral have you considered to join the abandonware co-maintainers team see

https://abandonware.github.io/

@mrstegeman
Copy link

My primary request at this point is that the README is updated with the new events and APIs.

…ered, characteristicsDiscovered) that enables

caching of gatt information.
The cached objects can be used to initialize a device via addServices() and addCharacteristics(), which return an
array of Noble objects ready for connecting in the usual way.

examples/cache-gatt-discovery.js provides an example for collecting GATT data and persisting the information,
examples/cache-gatt-reconnect.js uses the data to connect to the device using the cached data.
@rzr rzr merged commit 0d15d19 into abandonware:master Jan 15, 2020
@rzr
Copy link

rzr commented Jan 15, 2020

Please review other PR then I plan to release something in a couple of weeks

@svogl svogl deleted the inject-gatt-descriptors branch January 18, 2020 15:35
rzr pushed a commit that referenced this pull request Jan 18, 2020
(serviceDiscovered, characteristicsDiscovered) that enables
caching of gatt information.
The cached objects can be used to initialize a device via addServices() and addCharacteristics(), which return an
array of Noble objects ready for connecting in the usual way.

examples/cache-gatt-discovery.js provides an example for collecting GATT data and persisting the information,
examples/cache-gatt-reconnect.js uses the data to connect to the device using the cached data.

Author: Simon Vogl <simon@voxel.at>
Relate-to: #29
Change-Id: I68bc5208529f872e5f60d7c0315a6346d24df2fb
rzr pushed a commit that referenced this pull request Feb 20, 2020
(serviceDiscovered, characteristicsDiscovered) that enables
caching of gatt information.
The cached objects can be used to initialize a device via addServices() and addCharacteristics(), which return an
array of Noble objects ready for connecting in the usual way.

examples/cache-gatt-discovery.js provides an example for collecting GATT data and persisting the information,
examples/cache-gatt-reconnect.js uses the data to connect to the device using the cached data.

Author: Simon Vogl <simon@voxel.at>
Relate-to: #29
Change-Id: I68bc5208529f872e5f60d7c0315a6346d24df2fb
rzr pushed a commit that referenced this pull request Apr 3, 2020
(serviceDiscovered, characteristicsDiscovered) that enables
caching of gatt information.
The cached objects can be used to initialize a device via addServices() and addCharacteristics(), which return an
array of Noble objects ready for connecting in the usual way.

examples/cache-gatt-discovery.js provides an example for collecting GATT data and persisting the information,
examples/cache-gatt-reconnect.js uses the data to connect to the device using the cached data.

Author: Simon Vogl <simon@voxel.at>
Relate-to: #29
Change-Id: I68bc5208529f872e5f60d7c0315a6346d24df2fb
@pursual
Copy link

pursual commented Sep 9, 2020

The mac bindings do not call characteristicsDiscovered. They also do not have this._bindings.addCharacteristics or this._bindings.addServices

bitcloud pushed a commit to cospired/noble that referenced this pull request Sep 21, 2020
(serviceDiscovered, characteristicsDiscovered) that enables
caching of gatt information.
The cached objects can be used to initialize a device via addServices() and addCharacteristics(), which return an
array of Noble objects ready for connecting in the usual way.

examples/cache-gatt-discovery.js provides an example for collecting GATT data and persisting the information,
examples/cache-gatt-reconnect.js uses the data to connect to the device using the cached data.

Author: Simon Vogl <simon@voxel.at>
Relate-to: abandonware#29
Change-Id: I68bc5208529f872e5f60d7c0315a6346d24df2fb
sandoval pushed a commit to sandoval/noble that referenced this pull request Jan 6, 2021
(serviceDiscovered, characteristicsDiscovered) that enables
caching of gatt information.
The cached objects can be used to initialize a device via addServices() and addCharacteristics(), which return an
array of Noble objects ready for connecting in the usual way.

examples/cache-gatt-discovery.js provides an example for collecting GATT data and persisting the information,
examples/cache-gatt-reconnect.js uses the data to connect to the device using the cached data.

Author: Simon Vogl <simon@voxel.at>
Relate-to: abandonware#29
Change-Id: I68bc5208529f872e5f60d7c0315a6346d24df2fb
rzr pushed a commit that referenced this pull request Jan 26, 2021
(serviceDiscovered, characteristicsDiscovered) that enables
caching of gatt information.
The cached objects can be used to initialize a device via addServices() and addCharacteristics(), which return an
array of Noble objects ready for connecting in the usual way.

examples/cache-gatt-discovery.js provides an example for collecting GATT data and persisting the information,
examples/cache-gatt-reconnect.js uses the data to connect to the device using the cached data.

Author: Simon Vogl <simon@voxel.at>
Relate-to: #29
Change-Id: I68bc5208529f872e5f60d7c0315a6346d24df2fb
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants