-
Notifications
You must be signed in to change notification settings - Fork 19
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
Discuss BLE Interface, BLE MAC Address and general Selection Handling #154
Comments
Maybe a |
iOS not exposing the MAC-adress of a BLE device: |
Regards Configuration: Using a MethodYes. That is the way to go. There is Microsoft.Extensions.Configuration component which is essentially a key/value pair and has adapters to json files, command line parsing etc. using Microsoft.Extensions.Configuration;
public interface IPoweredUpBluetoothAdapter
{
// ...
Task ConfigureAsync(IConfiguration configuration);
// ...
} In the CLI or other systems we would then have a situation that ... // ✅ get your config from somewhere
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(
new Dictionary<string, string>
{
["BlueGigaCOMPort"] = "COM4",
["BlueGigaTracing"] = bool.TrueString,
})
.Build();
// ✅ globally configure the adapter
var adapter = serviceProvider.GetService<IPoweredUpBluetoothAdapter>();
await adapter.ConfigureAsync(configuration); // optionally
// ✅ for each active BLE device/hub to talk to ...
using var scope = serviceProvider.CreateScope(); // use the same adapter
var scopedServiceProvider = scope.ServiceProvider;
// 🕵️♀️ that is a fish to grill as well ... but as part of the iOS selection issue.
scopedServiceProvider.GetService<BluetoothKernel>().BluetoothAddress = bluetoothAddress;
// ✅ start using it
var protocol = scopedServiceProvider.GetService<ILegoWirelessProtocol>(); Thumbs Up for this is accepted solution for that problem |
Regards Configuration: Using the Options PatternNo interface change, only implementations need to add a Option to the constructor class BlueGigaAdapter
{
public BlueGigaAdapter(IOption<BlueGigaOption> option)
// ...
} Invocation is less service provider style (anti-pattern) and more DI like. // ✅ get your config from somewhere
var configuration = new ConfigurationBuilder()
.AddInMemoryCollection(
new Dictionary<string, string>
{
["BlueGigaCOMPort"] = "COM4",
["BlueGigaTracing"] = bool.TrueString,
})
.Build();
// ✅ Init Service Provider including config
var serviceProvider = new ServicesCollection()
.AddPoweredUp()
.AddBlueGigaBLE()
.Configure<BlueGigaOptions>(configuration)
.Build()
// ✅ for each active BLE device/hub to talk to ...
using var scope = serviceProvider.CreateScope(); // use the same adapter
var scopedServiceProvider = scope.ServiceProvider;
// 🕵️♀️ that is a fish to grill as well ... but as part of the iOS selection issue.
scopedServiceProvider.GetService<BluetoothKernel>().BluetoothAddress = bluetoothAddress;
// ✅ start using it
var protocol = scopedServiceProvider.GetService<ILegoWirelessProtocol>(); Thumbs Up for this. Personally I like this more. |
Regards
What is about an abstraction of this like a BLEIdentifier, which can be constructed by a MAC-Address (little or big-endian over a bool-property) or a ulong or a String like "90:84.2B:4C:FF:F0" (or other format like . or - instead of ":") and then internally use a ulong? Also the byte[6] array could be used (but makes little more effort, because byte[] doesn't implement IEquatable or IEqualityComparer) - the class itself must be usable as a TKey in IDictionary<TKey, TValue> (e.g. for Dictionaries based on the BLEIdentifier). Even better would be an internal Hash derived from the value given to the constructor. |
No idea whether it is feasible on iOS but the idea sound good. Would fix all problems at once. The class For the cases we have an externally provided fixed address, we could construct these explicitly. That explicit construction, I have no idea how it would work on iOS. |
As said before: Apple has its very own way to deal with BLE. |
Regards Configuration: Using the Options Pattern |
@dkurok is right about Apple's way to deal the mac and ble. Perhaps when we're discovering devices in the BluetoothAdapter discovery we construct the PoweredUpBluetoothDeviceInfo where we assign an identifier and perhaps an BT stack depenendent object. When then GetDeviceAsync() is called, we just give in this construct, so that the current bt adapter has to handle this by its own implementation:
The bad thing here would be, that a direct connection via known BT MacAddress would not work this way, so this must be handled on a different way. |
That is exactly my thought. Therefore the idea of the interface. The Mac address can then be a detail only a few implentations will expose. iOS object will then carry whatever information. |
Primary Device Identity InterfaceSince iOS is abstracting the identity of the BLE device, each stack should expose its own identity object. Therefore I propose the following changes Addition of a new interface public interface IPoweredUpBluetoothDeviceInfo
{
byte[] ManufacturerData { get; }
string Name { get; set; }
}
public interface IPoweredUpMacAddress
{
byte[] MacAddress { get; }
}
public class WinRTDeviceInfo : IPoweredUpBluetoothDeviceInfo, IPoweredUpMacAddress { }
public class XamarinOnIOSDeviceInfo : IPoweredUpBluetoothDeviceInfo { }
public class XamarinOnAndroidDeviceInfo : IPoweredUpBluetoothDeviceInfo, IPoweredUpMacAddress { }
public class BlueGigaDeviceInfo : IPoweredUpBluetoothDeviceInfo, IPoweredUpMacAddress { } Change to the existing Adapter interface Use the new interface public interface IPoweredUpBluetoothAdapter
{
void Discover(Func<IPoweredUpBluetoothDeviceInfo, Task> discoveryHandler, CancellationToken cancellationToken = default);
Task<IPoweredUpBluetoothDevice> GetDeviceAsync(IPoweredUpBluetoothDeviceInfo deviceInfo);
}
public class BluetoothKernel
{
// ...
// remove: public ulong BluetoothAddress { get; set; }
public IPoweredUpBluetoothDevice BluetoothDeviceInfo { get; set; }
} Finally I like the change. Is that working for team iOS? Must be fixed in v4 timeline. Thumbs Up? |
regards Primary Device Identity Interface: public interface IPoweredUpBluetoothDeviceInfo: IEquatable<IPoweredUpBluetoothDeviceInfo>
{
byte[] ManufacturerData { get; }
string Name { get; set; }
object UniqueIdentifier { get; }
override bool Equals(IPoweredUpBluetoothDeviceInfo obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
//here there may be some change needed depending on what concrete type is used in the real implementation
//byte[] for example must override it, because byte[] doensn't adhere to IComparable/IEquatable
if (this.UniqueIdentifier.Equals(obj.UniqueIdentifier))
{
return true;
}
}
// override object.GetHashCode
public override int GetHashCode()
{
return UniqueIdentifier.GetHashCode();
}
} Rest is nearly identical to above suggestion from @tthiery (just leave out the IPoweredUpMacAddress) |
I do agree with you on making the thing IEquatable, mainly for dictionary support. But that's only if we step away from using ulong as the unique identifier of course (which is probably a good thing). I'm not fond of it being an object maybe, it seems to generic/broad in a definition. You really need to be aware that whatever you are using as the unique identifier should be properly implementing equals and gethashcode (but that might be a very reasonable assumption/choice though). Just a suggestion: maybe we can replace |
Just a small update. I finally made a working setup to be able to deploy to some Apple HW. |
- Abstract identity in an interface independent of Mac Address - Change PoweredUpHost function to use generic state instead of bluetooth address as ulong - Implement interface in existing adapters (simple transformation) - Change BluetoothKernel interface to accept device instead of bluetooth address - Modify existing examples #154 breaking
Hi Friends ... can you have a look at the PR #173 I created. It is the implementation of the Device Identification Abstraction. Further, there is a detail about Mac Address stringification where I need your thought power. I am not sure if all our adapters have they ulong mac address we used so far in the same way (regards byte order etc). Also not regards little and big endianess. |
- Added device identifier for iOS - Reworked device identifier for Xamarin #154
- Abstract identity in an Bluetooth Device independent of Mac Address - Change PoweredUpHost function to use generic state instead of bluetooth address (as ulong) - Implement interface in existing adapters (simple transformation) - Change BluetoothKernel interface to accept device info abstraction instead of bluetooth address - Modify existing examples - Add formatting to the MAC Address DeviceInfo - Adjust Xamarin and iOS device identifiers (#176) #154 Co-authored-by: Berdsen <berdsen.home@gmail.com>
Other?
@dkurok @vuurbeving @Berdsen
The text was updated successfully, but these errors were encountered: