intel-iot-devkit / tinyb

TinyB exposes the BLE GATT API for C++, Java and other languages, using BlueZ over DBus.
MIT License
254 stars 114 forks source link

Need asynchronous advertisement pass-through to the app through TinyB #49

Open dfclark opened 8 years ago

dfclark commented 8 years ago

Hi Petre. Ideally the app would be able to register (and deregister) for callbacks when advertisements are received, which would allow the app to react to these temporally. For example, I have a sensor that transmits its data via the advertisement - because it posts advertisements much more frequently than it takes a sensor reading there is a toggle bit in the advertisement that is flipped when the sensor transmits a new value. The app should be able see every advertisement, take note of this bit, and only process the sensor data when the bit is flipped. Without the callback mechanism the app must poll the list of devices maintained by the BluetoothManager, and then examine the advertisement data attached to each BluetoothDevice object. This is almost workable except that the polling frequency would have to be a set value, like once per second, rather than being able to react to the asynchronous arrival of the advertisements from multiple sensor devices.

petreeftime commented 8 years ago

Hi, could you tell me what platform you are using that updates the MFG? I can't currently test this feature but I would like be able to do this in the future.

dfclark commented 8 years ago

The peripheral device is running proprietary firmware that posts BLE advertisements, including Mfg Data. The app, running on Linux and BlueZ and TinyB, implements a Central that looks for the advertisements from peripheral devices that include mfg data with a specific Mfg ID. Ideally the advertisements would be exposed to the app just as Connected Notifications and Value Notifications are now. I'm thinking an Advertisement Notification method that would be invoked for every advertisement.

dfclark commented 8 years ago

I could supply a device that does this, if that would help.

petreeftime commented 8 years ago

I have an implementation almost done, I'll push it when I return from vacation, and you can test it. A device would be helpful, but I don't know if it's necessary.

dfclark commented 8 years ago

Petre, just let me know if you would like me to send one, and where I would send it. Thanks.

dfclark commented 8 years ago

Hi Petre. I have three questions: 1) Are you back from vacation? Hope you had, or are having, a good one. 2) Do you have an idea of when the implementation will be available? 3) I need some better understanding of the BLE device connection operation inside BlueZ and D-Bus, and whether or not there are configuration params that can be set to tailor the connection effort. Do you know of a resource (documentation, person, ...) that could help provide those insights? Thanks

petreeftime commented 8 years ago

Hi, I was just pushing these changes: https://github.com/intel-iot-devkit/tinyb/pull/54

I tested to see that nothing crashes, but as I said previously, I don't have devices that change MFG, although my Arduino 101 should be able to update ServiceData, which is similar, I will have to check to see if that works.

3) I suggest trying the BlueZ mailing list: http://www.bluez.org/development/lists/

dfclark commented 8 years ago

Thanks Petre. I've obtained the new TinyB package and adapted my code to get notifications of manufacturer's data. However, I find I'm not clear on what the effect of calling enableManufacturerDataNotifications will have within the app, and I am surprised to see that this method is on the BluetoothDevice class.

The scenario I envisioned was that the BLE devices are advertising, and I'm registering for notifications of these advertisements. I expected that this registration would be with the BluetoothManager class, and my app would get a callback for each advertisement handled by the BluetoothManager. Given that the enableManufacturerDataNotifications method is on the BluetoothDevice object it seems that I must register with each BluetoothDevice object for these notifications. So what I'm doing is getting the list of BluetoothDevice objects from the BluetoothManager, and for each I'm calling enableManufacturerDataNotifications. However, I'm never seeing the callback to my delegate that implements the BluetoothNotification<Map<Short, byte[]>> interface.

Am I misunderstanding?

petreeftime commented 8 years ago

No, I don't think there's a way to add it to the manager directly, except to make it call for each device and gather all the requests. To be honest, I was not entirely sure if it would work, it might be something that needs to be supported in BlueZ.

dfclark commented 8 years ago

Not sure I'm understanding. How is enableManufacturerDataNotifications intended to be used?

petreeftime commented 8 years ago

Right now, you enable it per device and it should run the callback with the data that you would get if you ran getManufacturerData instead. I'm not entirely sure why this does not happen.

petreeftime commented 7 years ago

BlueZ added "Advertising Flags" in the latest version, I will update and see if that works instead.

d-f-clark commented 7 years ago

Hi Petre. It's been a while, I thought I'd check and see if you have been able to look back into the async notification of advertisements? Back in late November you were going to take a look. Also, just to be sure, what version of userland BlueZ should be used? 5.43? 5.42? Thanks

d-f-clark commented 7 years ago

Never mind! I've built a new Raspbian image and updated to BlueZ 5.43, along with the latest TinyB, and the async advertisements are arriving! Thanks!

petreeftime commented 7 years ago

I'm no longer working for Intel, so I didn't have time to look into it unfortunately. I'm glad to hear it works now.

framspott94 commented 7 years ago

Hi d-f-clark and petreeftime,

Until now I could not receive any manufacturer data or manufacturer data notification through this library. Therefore I would be very grateful, if there is a java example for it, like the great 'hello world' example. The function get_manufacturerdata() does return an empty map, and notifications are never fired. Could there be an timing issue?

I successfully connected my Raspi to an BLE Beacon (BeaconInside 2nd Gen), but this does not seem to work...

I would be very grateful, if someone could help me through this problem... ;)

All the best

framspott94

impala454 commented 7 years ago

I actually tested this last night on a ruuvi tag and the BluetoothDevice::enable_manufacturer_data_notifications() function does indeed work. As I commented on issue #99, I noticed that on some devices it's the service data that gets updated. I would try both and see if one works. I haven't used a BeaconInside BLE Beacon before though so I can't speak to that device.

mburger81 commented 6 years ago

Can someone help do implmenet advertisment notifications? Was someone able to get it work?

d-f-clark commented 6 years ago

Sure, but his will have to wait until next week.

Sent from my iPhone

On Jan 24, 2018, at 4:58 AM, mburger81 notifications@github.com wrote:

Can someone help do implmenet advertisment notifications? Was someone able to get it work?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub, or mute the thread.

dfclark commented 6 years ago

I have a class called AdvertisementNotification: class AdvertisementNotification implements BluetoothNotification<Map<Short, byte[]>>

with a run() method defined as follows: public void run(Map<Short, byte[]> advertisementsMap) { if (advertisementsMap.size() > 0) { for (Map.Entry<Short, byte[]> entry : advertisementsMap.entrySet()) { Short key = (Short)entry.getKey(); byte [] foobar = (byte[])entry.getValue(); logWriter.debug("run: Advertisement Key = {}, data = {}", key, Conversions.bytesToHex((byte[])entry.getValue())); } } else { logWriter.debug("run: Advertisements Map contained zero advertisements, no keys processed"); } }

I have code that periodically polls the BluetoothManager for known devices: List loggerDevices = BluetoothManager.getBluetoothManager().getDevices();

It creates an instance of AdvertisementNotification: AdvertisementNotification advNote = new AdvertisementNotification();

And then iterates through the list: Iterator itr = loggerDevices.iterator(); while (itr.hasNext()) { BluetoothDevice device = (BluetoothDevice)itr.next();

For each device it pulls out the advertisement and examines it to see if the mfg ID is the one I’m interested in (GWAdvertisement and GWUtilities are proprietary classes): GWAdvertisement adv = GWUtilities.extractAdvertisement(device);

If it turns out that this is a BLE device that I’m interested in, I register that AdvertisementNotification object: device.enableManufacturerDataNotifications(advNote);

Thereafter, when an advertisement is received from that device, the run() method is invoked in the AdvertisementNotification object.

Here’s roughly what the extractAdvertisement() method does:

public static GWAdvertisement extractAdvertisement(BluetoothDevice logger) { GWAdvertisement adv = null; Map<Short, byte[]>advertisements = logger.getManufacturerData(); if (advertisements.isEmpty()) return adv;

     for (Map.Entry<Short, byte[]> entry : advertisements.entrySet()) {

        // Is it a device I’m looking for?
        if (entry.getKey() != 0x00a6)
            return null;

        adv = new GWAdvertisement(entry.getKey(), entry.getValue());
        }

return adv; }

--

From: mburger81 notifications@github.com<mailto:notifications@github.com> Reply-To: intel-iot-devkit/tinyb reply@reply.github.com<mailto:reply@reply.github.com> Date: Wednesday, January 24, 2018 at 07:58 To: intel-iot-devkit/tinyb tinyb@noreply.github.com<mailto:tinyb@noreply.github.com> Author author@noreply.github.com<mailto:author@noreply.github.com> Subject: Re: [intel-iot-devkit/tinyb] Need asynchronous advertisement pass-through to the app through TinyB (#49)

Can someone help do implmenet advertisment notifications? Was someone able to get it work?

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHubhttps://github.com/intel-iot-devkit/tinyb/issues/49#issuecomment-360123549, or mute the threadhttps://github.com/notifications/unsubscribe-auth/AJWcFWHn_eXvz9x2zhT-ENFvDV0N-LiKks5tNyj_gaJpZM4KRmX5.