-
Notifications
You must be signed in to change notification settings - Fork 37
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
Report all Advertisements #20
Comments
@Fungusware I encountered this same situation. The solution is to call using (var adapter = await BlueZManager.GetAdapterAsync("hci0")) {
adapter.DeviceFound += async (sender, args) => {
var device = args.Device;
var props = await device.GetAllAsync();
// Do whatever you need to do with the device properties.
DoStuffWithProps(device, props);
// Create a watcher so that you can be notified when the device's properties change.
var watcher = await device.WatchPropertiesAsync(changes => {
// Call a method that will update your existing properties object with the changes.
UpdateDeviceProperties(props, changes);
// Do whatever you need to do with the updated device properties.
DoStuffWithProps(device, props);
});
// TODO: watcher is an IDisposable, so keep it somewhere so that it can be disposed when you cancel discovery!
};
// Start discovery.
await adapter.StartDiscoveryAsync();
try {
// Wait until discovery is cancelled.
await Task.Delay(-1, someCancellationToken);
}
finally {
// TODO: dispose of any watchers that have been created.
}
} |
Special thanks! This has solved my issue, I'm checking stability as I had been getting crashes after a few minutes with my previous method. Will update once the tests have completed. |
Something to consider as well: I don't know if it is at all possible for the |
Indeed it is possible, I dealt with it as mentioned. One thing I noticed, is that after a few hours of running, the change notification stop coming through and I had to restart my console app host. I'm guessing just restarting the listener would be enough. I'll try that out. |
Yeah I saw the same thing - I get some sort of DBus exception about too many connections. My workaround has just been to run the app as a service with systemd and have it restart automatically when it crashes 🤷 |
I think another solution would be to set the correct property in the await adapter.SetDiscoveryFilterAsync(properties) function. According to the API https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/adapter-api.txt#n107, you can set this parameter. bool Discoverable (Default: false)
I'm looking now to see how to pass these properties in without causing an error. I've had success with a node.js library that does this. So i'm sure it works. |
Does anyone know how to properly format and add properties that are passed into the Start adapter.SetDiscoveryFilterAsync(Properties) method? Here is a post showing the api implemented in C. I'm not sure how to port it C#. https://stackoverflow.com/questions/50675797/bluez-d-bus-c-application-ble Data is passed in via a dictionary, but i'm not sure how the object should be formed. Since i couldn't figure this out, I just removed the device on add each time and that works using adapter.RemoveDeviceAsync. since the device is removed, the adapter has to rescan. using (await adapter.WatchDevicesAddedAsync(async device => I did the same here using (await adapter.WatchDevicesAddedAsync(async device => Now, I get every advertising packet when it posts. |
@walkerlaron would you be able to post the full source code (or at least more of it), I cannot get any results using this method. |
using System; namespace Scan
} |
Yeah still failing with the exception.
|
I managed to pass some Discovery Filters using the following :
These options worked nicely and reduced the amount non-useful advertiements I was recieving. I haven't tried all of the properties yet though. |
Odd, i tried similar code before and received errors. I tried this again today with your code and didn't get errors. So there must be something that I'm missing from my old code version. I didn't see where the DuplicateData Tag worked, but i'll debug a bit more later today when I have time. I'm not getting the error you posted regardding max connections. I've been runnning for several days now with a version of the snippet i posted earlier the only change i have is... while (true)
so I scan for three minutes, stop scanning, sleep for 10 minutes and start over. In my case, working on a Beacon like use case for my device. |
I know this is an older post but I wanted to chime in to say that this worked for me. I think the proper way to do this though is to use the experimental AdvertisementMonitor API (https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/doc/advertisement-monitor-api.txt) however this is not exposed in this library and I can't seem to get it working on my RBPi4B under Ubuntu (
I'll keep hacking away at it on my end. I am using a branch for which I've upgraded this library ( I am trying to write a .NET Version of This sensor works by exporting the Temperature and Humidity as ManufacturerData in an advertisement. This issue on the ble_monitor project page was invaluable: custom-components/ble_monitor#961 Here's a copy of BT Snoop:
Its a bit confusing because apparently If you convert the "Company" into Hex you get
The string can be decoded in the following way:
The Unknown values have not changed since I've started monitoring this; and the linked blue_monitor issue didn't seem to have an idea what they were for either. The Temperature is a 16bit Little-endian value that contains the current reading multiplied by 10 in C; so the above example:
The Humidity % is represented with 8bits above and can be simply converted: 0x21 -> 33% In a perfect world I'd love to have the library just take the MAC Address as an argument and spit me out the raw Advertisement Data (ideally filtered down to just ManufacturerData). I would then pipe this information into a post processing pipeline to decode. This is more or less how ble_monitor works (but in Python). My intent would be to then take that decoded processing pipeline and then ingest it into the InfluxDB. Historically many of these applications (including ble_monitor) used Here's what I've got so far and am continuing to hack on it: using Tmds.DBus;
using HashtagChris.DotNetBlueZ;
namespace dotnet_ble_monitor
{
class Program
{
static async Task Main(string[] args)
{
using (var adapter = (await BlueZManager.GetAdaptersAsync()).FirstOrDefault())
{
try
{
Console.WriteLine("Bluez DBUS Examples");
adapter.DeviceFound += adapter_DeviceFoundAsync;
var props = new Dictionary<string, object>();
props.Add("Pattern", "BC:C7:DA:6D:8D:12");
await adapter.SetDiscoveryFilterAsync(props);
await adapter.StartDiscoveryAsync();
Console.WriteLine("Waiting for events. Use Control-C to quit.");
Console.WriteLine();
await Task.Delay(-1);
}
catch (Exception ex)
{
Console.Error.WriteLine(ex);
}
finally
{
await adapter.StopDiscoveryAsync();
}
}
}
private static async Task adapter_DeviceFoundAsync(Adapter sender, DeviceFoundEventArgs eventArgs)
{
try
{
Console.WriteLine("A device was found!");
var deviceProperties = await eventArgs.Device.GetAllAsync();
Console.WriteLine($"{deviceProperties.Name} ({deviceProperties.Address}) was the device");
var watcher = eventArgs.Device.WatchPropertiesAsync(device_PropertiesChangedAsync);
return;
}
catch (Exception ex)
{
Console.Error.WriteLine(ex);
}
}
private static void device_PropertiesChangedAsync(PropertyChanges obj)
{
Console.WriteLine($"A Data Change was Encountered");
Dictionary<System.UInt16, System.Object> manufacturerData = (Dictionary<System.UInt16, System.Object>)obj.Changed.Where(kvp => kvp.Key.Equals("ManufacturerData")).First().Value;
foreach (var kvp in manufacturerData)
{
Console.WriteLine($"Manufacturer Data Changed: {kvp.Key}, {kvp.Value}");
}
}
}
} I've noticed that behind the scenes Discovery stops after awhile (I believe 60 seconds). Is the intent really to have it continue to try and perform discovery? Is there a way to continue to monitor without having to continually re-enable discovery? |
Does anyone have an idea how to listen to ALL advertisements from all devices, not just the first time it is discovered?
The text was updated successfully, but these errors were encountered: