Skip to content

Commit

Permalink
Fix "Same MAC, same name - only difference is LE #1":
Browse files Browse the repository at this point in the history
Connect to both devices in case a device advertises itself as Bluetooth and BluetoothLE device with the same MAC and name simultaneously
  • Loading branch information
PolarGoose committed Dec 7, 2020
1 parent 17466b4 commit 7258e93
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 20 deletions.
6 changes: 3 additions & 3 deletions Src/Bluetooth/AsqFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ namespace BluetoothDevicePairing.Bluetooth
{
internal sealed class AsqFilter
{
public string Query { get; }
public string Query { get; }

private AsqFilter(string query)
{
Query = query;
Expand All @@ -15,7 +15,7 @@ public override string ToString()
{
return Query;
}

public static AsqFilter BluetoothDevicesFilter()
{
var paired = PairedBluetoothDevicesFilter();
Expand Down
2 changes: 1 addition & 1 deletion Src/Bluetooth/Device.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public bool IsConnected

public override string ToString()
{
return $"name:'{Name}' mac:'{Mac}'";
return $"name:'{Name}' mac:'{Mac}' type:'{Type}'";
}

private static DeviceType GetDeviceType(DeviceInformation device)
Expand Down
19 changes: 18 additions & 1 deletion Src/Bluetooth/MacAddress.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace BluetoothDevicePairing.Bluetooth
{
internal sealed class MacAddress
internal sealed class MacAddress : IEquatable<MacAddress>
{
public MacAddress(DeviceInformation device)
{
Expand All @@ -26,5 +26,22 @@ public override string ToString()
{
return Address;
}

public bool Equals(MacAddress other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return Address == other.Address;
}

public override bool Equals(object obj)
{
return ReferenceEquals(this, obj) || obj is MacAddress other && Equals(other);
}

public override int GetHashCode()
{
return (Address != null ? Address.GetHashCode() : 0);
}
}
}
2 changes: 1 addition & 1 deletion Src/BluetoothDevicePairing.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
<TargetFramework>net5.0-windows10.0.17763.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.8.0" />
<PackageReference Include="CommandLineParser" Version="2.9.0-preview1" />
</ItemGroup>
</Project>
48 changes: 42 additions & 6 deletions Src/Command/PairDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

namespace BluetoothDevicePairing.Command
{
[Verb("pair", HelpText = "Pair and connect to a device. If device is paired but not connected, this command unpairs it first and then pairs and connects")]
[Verb("pair",
HelpText = "Pair and connect to a device. If device is paired but not connected, this command unpairs it first and then pairs and connects")]
internal sealed class PairDeviceOptions : PairAndUnpairDeviceOptions
{
[Option("discovery-time", Default = 10,
Expand Down Expand Up @@ -33,7 +34,22 @@ public static void Execute(PairDeviceOptions opts)

private static void PairWithMac(MacAddress mac, int discoveryTime)
{
DevicePairer.PairDevice(DeviceFinder.FindDeviceByMac(DeviceDiscoverer.DiscoverBluetoothDevices(discoveryTime), mac));
var devices = DeviceFinder.FindDevicesByMac(DeviceDiscoverer.DiscoverBluetoothDevices(discoveryTime), mac);

if (devices.Count == 1)
{
DevicePairer.PairDevice(devices[0]);
return;
}

if (devices.Count == 2 && devices[0].Type != devices[1].Type && devices[0].Name == devices[1].Name)
{
HandleSituation_2_Bluetooth_devices_with_the_same_mac_and_name_found(devices[0], devices[1]);
return;
}

throw new Exception(
$"{devices.Count} devices with the mac '{mac}' found. Don't know which one to choose");
}

private static void PairWithName(string name, int discoveryTime)
Expand All @@ -45,15 +61,20 @@ private static void PairWithName(string name, int discoveryTime)
return;
}

if (devices.Count == 2 && devices[0].Type != devices[1].Type && devices[0].Mac.Equals(devices[1].Mac))
{
HandleSituation_2_Bluetooth_devices_with_the_same_mac_and_name_found(devices[0], devices[1]);
return;
}

if (devices.Count == 2 && devices[0].Type == DeviceType.BluetoothLe &&
devices[1].Type == DeviceType.BluetoothLe)
{
HandleSituation_2_BluetoothLe_devices_with_the_same_name_found(devices[0], devices[1]);
return;
}

throw new Exception(
$"{devices.Count} devices with the name '{name}' found. Don't know which one to choose");
throw new Exception($"{devices.Count} devices with the name '{name}' found. Don't know which one to choose");
}

private static void HandleSituation_2_BluetoothLe_devices_with_the_same_name_found(Device device1,
Expand All @@ -75,8 +96,23 @@ private static void HandleSituation_2_BluetoothLe_devices_with_the_same_name_fou
return;
}

throw new Exception(
$"2 unpaired devices with the same name found \"{device1}\" \"{device2}\". Don't know which one to choose");
throw new Exception($"2 unpaired devices with the same name found \"{device1}\" \"{device2}\". Don't know which one to choose.");
}

private static void HandleSituation_2_Bluetooth_devices_with_the_same_mac_and_name_found(Device device1,
Device device2)
{
Console.WriteLine(
$"Two devices with the same mac address and name but different bluetooth types found: \"{device1}\" and \"{device1}\". " +
"It is possible that it is one device which advertises itself as Bluetooth and BluetoothLE simultaneously." +
"Pair both of them.");

// for unknown reasons we first need to pair BluetoothLE one. Otherwise non LE device pairing fail
var leDevice = device1.Type == DeviceType.BluetoothLe ? device1 : device2;
var nonLeDevice = device1.Type == DeviceType.Bluetooth ? device1 : device2;

DevicePairer.PairDevice(leDevice);
DevicePairer.PairDevice(nonLeDevice);
}
}
}
42 changes: 38 additions & 4 deletions Src/Command/UnPairDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,52 @@ public static void Execute(UnpairDeviceOptions opts)

public static void UnpairByMac(MacAddress mac, int discoveryTime)
{
DevicePairer.UnpairDevice(DeviceFinder.FindDeviceByMac(DeviceDiscoverer.DiscoverPairedBluetoothDevices(discoveryTime), mac));
var devices = DeviceFinder.FindDevicesByMac(DeviceDiscoverer.DiscoverPairedBluetoothDevices(discoveryTime), mac);

if (devices.Count == 1)
{
DevicePairer.UnpairDevice(devices[0]);
return;
}

if (devices.Count == 2 && devices[0].Type != devices[1].Type && devices[0].Name == devices[1].Name)
{
HandleSituation_2_Bluetooth_devices_with_the_same_mac_and_name_found(devices[0], devices[1]);
return;
}

throw new Exception($"{devices.Count} devices found, don't know which one to choose");
}

public static void UnpairByName(string name, int discoveryTime)
{
var devices = DeviceFinder.FindDevicesByName(DeviceDiscoverer.DiscoverPairedBluetoothDevices(discoveryTime), name);
if (devices.Count > 1)

if (devices.Count == 1)
{
throw new Exception($"{devices.Count} devices found, don't know which one to choose");
DevicePairer.UnpairDevice(devices[0]);
return;
}

DevicePairer.UnpairDevice(devices[0]);
if (devices.Count == 2 && devices[0].Type != devices[1].Type && devices[0].Mac.Equals(devices[1].Mac))
{
HandleSituation_2_Bluetooth_devices_with_the_same_mac_and_name_found(devices[0], devices[1]);
return;
}

throw new Exception($"{devices.Count} devices found, don't know which one to choose");
}

private static void HandleSituation_2_Bluetooth_devices_with_the_same_mac_and_name_found(Device device1,
Device device2)
{
Console.WriteLine(
$"Two devices with the same mac address and name but different bluetooth types found: \"{device1}\" and \"{device1}\"." +
"It is possible that it is one device which advertises itself as Bluetooth and BluetoothLE simultaneously." +
"Unpair both of them.");

DevicePairer.UnpairDevice(device1);
DevicePairer.UnpairDevice(device2);
}
}
}
3 changes: 2 additions & 1 deletion Src/Command/Utils/CommonOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ namespace BluetoothDevicePairing.Command.Utils
internal class CommonOptions
{
[Option("wait-on-error", Default = false,
HelpText = "wait for an user input in case of an error. This flag can be useful if you want a console to not disappear to see an error message in case a command failed")]
HelpText =
"wait for an user input in case of an error. This flag can be useful if you want a console to not disappear to see an error message in case a command failed")]
public bool WaitOnError { get; set; }
}

Expand Down
6 changes: 3 additions & 3 deletions Src/Command/Utils/DeviceFinder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ namespace BluetoothDevicePairing.Command.Utils
{
internal sealed class DeviceFinder
{
public static Device FindDeviceByMac(List<Device> devices, MacAddress mac)
public static List<Device> FindDevicesByMac(List<Device> devices, MacAddress mac)
{
var res = devices.Find(d => d.Mac.Address == mac.Address);
var res = devices.FindAll(d => d.Mac.Equals(mac));
if (res == null)
{
throw new Exception($"Couldn't find the device with '{mac}' mac address");
throw new Exception($"Couldn't find any devices with '{mac}' mac address");
}

return res;
Expand Down
1 change: 1 addition & 0 deletions Src/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ private static int Main(string[] args)
{
Console.ReadLine();
}

return 1;
}
}
Expand Down

0 comments on commit 7258e93

Please sign in to comment.