Skip to content

Commit 7258e93

Browse files
committed
Fix "Same MAC, same name - only difference is LE #1":
Connect to both devices in case a device advertises itself as Bluetooth and BluetoothLE device with the same MAC and name simultaneously
1 parent 17466b4 commit 7258e93

File tree

9 files changed

+109
-20
lines changed

9 files changed

+109
-20
lines changed

Src/Bluetooth/AsqFilter.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ namespace BluetoothDevicePairing.Bluetooth
44
{
55
internal sealed class AsqFilter
66
{
7-
public string Query { get; }
8-
7+
public string Query { get; }
8+
99
private AsqFilter(string query)
1010
{
1111
Query = query;
@@ -15,7 +15,7 @@ public override string ToString()
1515
{
1616
return Query;
1717
}
18-
18+
1919
public static AsqFilter BluetoothDevicesFilter()
2020
{
2121
var paired = PairedBluetoothDevicesFilter();

Src/Bluetooth/Device.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public bool IsConnected
4646

4747
public override string ToString()
4848
{
49-
return $"name:'{Name}' mac:'{Mac}'";
49+
return $"name:'{Name}' mac:'{Mac}' type:'{Type}'";
5050
}
5151

5252
private static DeviceType GetDeviceType(DeviceInformation device)

Src/Bluetooth/MacAddress.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace BluetoothDevicePairing.Bluetooth
66
{
7-
internal sealed class MacAddress
7+
internal sealed class MacAddress : IEquatable<MacAddress>
88
{
99
public MacAddress(DeviceInformation device)
1010
{
@@ -26,5 +26,22 @@ public override string ToString()
2626
{
2727
return Address;
2828
}
29+
30+
public bool Equals(MacAddress other)
31+
{
32+
if (ReferenceEquals(null, other)) return false;
33+
if (ReferenceEquals(this, other)) return true;
34+
return Address == other.Address;
35+
}
36+
37+
public override bool Equals(object obj)
38+
{
39+
return ReferenceEquals(this, obj) || obj is MacAddress other && Equals(other);
40+
}
41+
42+
public override int GetHashCode()
43+
{
44+
return (Address != null ? Address.GetHashCode() : 0);
45+
}
2946
}
3047
}

Src/BluetoothDevicePairing.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@
77
<TargetFramework>net5.0-windows10.0.17763.0</TargetFramework>
88
</PropertyGroup>
99
<ItemGroup>
10-
<PackageReference Include="CommandLineParser" Version="2.8.0" />
10+
<PackageReference Include="CommandLineParser" Version="2.9.0-preview1" />
1111
</ItemGroup>
1212
</Project>

Src/Command/PairDevice.cs

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55

66
namespace BluetoothDevicePairing.Command
77
{
8-
[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")]
8+
[Verb("pair",
9+
HelpText = "Pair and connect to a device. If device is paired but not connected, this command unpairs it first and then pairs and connects")]
910
internal sealed class PairDeviceOptions : PairAndUnpairDeviceOptions
1011
{
1112
[Option("discovery-time", Default = 10,
@@ -33,7 +34,22 @@ public static void Execute(PairDeviceOptions opts)
3334

3435
private static void PairWithMac(MacAddress mac, int discoveryTime)
3536
{
36-
DevicePairer.PairDevice(DeviceFinder.FindDeviceByMac(DeviceDiscoverer.DiscoverBluetoothDevices(discoveryTime), mac));
37+
var devices = DeviceFinder.FindDevicesByMac(DeviceDiscoverer.DiscoverBluetoothDevices(discoveryTime), mac);
38+
39+
if (devices.Count == 1)
40+
{
41+
DevicePairer.PairDevice(devices[0]);
42+
return;
43+
}
44+
45+
if (devices.Count == 2 && devices[0].Type != devices[1].Type && devices[0].Name == devices[1].Name)
46+
{
47+
HandleSituation_2_Bluetooth_devices_with_the_same_mac_and_name_found(devices[0], devices[1]);
48+
return;
49+
}
50+
51+
throw new Exception(
52+
$"{devices.Count} devices with the mac '{mac}' found. Don't know which one to choose");
3753
}
3854

3955
private static void PairWithName(string name, int discoveryTime)
@@ -45,15 +61,20 @@ private static void PairWithName(string name, int discoveryTime)
4561
return;
4662
}
4763

64+
if (devices.Count == 2 && devices[0].Type != devices[1].Type && devices[0].Mac.Equals(devices[1].Mac))
65+
{
66+
HandleSituation_2_Bluetooth_devices_with_the_same_mac_and_name_found(devices[0], devices[1]);
67+
return;
68+
}
69+
4870
if (devices.Count == 2 && devices[0].Type == DeviceType.BluetoothLe &&
4971
devices[1].Type == DeviceType.BluetoothLe)
5072
{
5173
HandleSituation_2_BluetoothLe_devices_with_the_same_name_found(devices[0], devices[1]);
5274
return;
5375
}
5476

55-
throw new Exception(
56-
$"{devices.Count} devices with the name '{name}' found. Don't know which one to choose");
77+
throw new Exception($"{devices.Count} devices with the name '{name}' found. Don't know which one to choose");
5778
}
5879

5980
private static void HandleSituation_2_BluetoothLe_devices_with_the_same_name_found(Device device1,
@@ -75,8 +96,23 @@ private static void HandleSituation_2_BluetoothLe_devices_with_the_same_name_fou
7596
return;
7697
}
7798

78-
throw new Exception(
79-
$"2 unpaired devices with the same name found \"{device1}\" \"{device2}\". Don't know which one to choose");
99+
throw new Exception($"2 unpaired devices with the same name found \"{device1}\" \"{device2}\". Don't know which one to choose.");
100+
}
101+
102+
private static void HandleSituation_2_Bluetooth_devices_with_the_same_mac_and_name_found(Device device1,
103+
Device device2)
104+
{
105+
Console.WriteLine(
106+
$"Two devices with the same mac address and name but different bluetooth types found: \"{device1}\" and \"{device1}\". " +
107+
"It is possible that it is one device which advertises itself as Bluetooth and BluetoothLE simultaneously." +
108+
"Pair both of them.");
109+
110+
// for unknown reasons we first need to pair BluetoothLE one. Otherwise non LE device pairing fail
111+
var leDevice = device1.Type == DeviceType.BluetoothLe ? device1 : device2;
112+
var nonLeDevice = device1.Type == DeviceType.Bluetooth ? device1 : device2;
113+
114+
DevicePairer.PairDevice(leDevice);
115+
DevicePairer.PairDevice(nonLeDevice);
80116
}
81117
}
82118
}

Src/Command/UnPairDevice.cs

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,52 @@ public static void Execute(UnpairDeviceOptions opts)
3333

3434
public static void UnpairByMac(MacAddress mac, int discoveryTime)
3535
{
36-
DevicePairer.UnpairDevice(DeviceFinder.FindDeviceByMac(DeviceDiscoverer.DiscoverPairedBluetoothDevices(discoveryTime), mac));
36+
var devices = DeviceFinder.FindDevicesByMac(DeviceDiscoverer.DiscoverPairedBluetoothDevices(discoveryTime), mac);
37+
38+
if (devices.Count == 1)
39+
{
40+
DevicePairer.UnpairDevice(devices[0]);
41+
return;
42+
}
43+
44+
if (devices.Count == 2 && devices[0].Type != devices[1].Type && devices[0].Name == devices[1].Name)
45+
{
46+
HandleSituation_2_Bluetooth_devices_with_the_same_mac_and_name_found(devices[0], devices[1]);
47+
return;
48+
}
49+
50+
throw new Exception($"{devices.Count} devices found, don't know which one to choose");
3751
}
3852

3953
public static void UnpairByName(string name, int discoveryTime)
4054
{
4155
var devices = DeviceFinder.FindDevicesByName(DeviceDiscoverer.DiscoverPairedBluetoothDevices(discoveryTime), name);
42-
if (devices.Count > 1)
56+
57+
if (devices.Count == 1)
4358
{
44-
throw new Exception($"{devices.Count} devices found, don't know which one to choose");
59+
DevicePairer.UnpairDevice(devices[0]);
60+
return;
4561
}
4662

47-
DevicePairer.UnpairDevice(devices[0]);
63+
if (devices.Count == 2 && devices[0].Type != devices[1].Type && devices[0].Mac.Equals(devices[1].Mac))
64+
{
65+
HandleSituation_2_Bluetooth_devices_with_the_same_mac_and_name_found(devices[0], devices[1]);
66+
return;
67+
}
68+
69+
throw new Exception($"{devices.Count} devices found, don't know which one to choose");
70+
}
71+
72+
private static void HandleSituation_2_Bluetooth_devices_with_the_same_mac_and_name_found(Device device1,
73+
Device device2)
74+
{
75+
Console.WriteLine(
76+
$"Two devices with the same mac address and name but different bluetooth types found: \"{device1}\" and \"{device1}\"." +
77+
"It is possible that it is one device which advertises itself as Bluetooth and BluetoothLE simultaneously." +
78+
"Unpair both of them.");
79+
80+
DevicePairer.UnpairDevice(device1);
81+
DevicePairer.UnpairDevice(device2);
4882
}
4983
}
5084
}

Src/Command/Utils/CommonOptions.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ namespace BluetoothDevicePairing.Command.Utils
55
internal class CommonOptions
66
{
77
[Option("wait-on-error", Default = false,
8-
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")]
8+
HelpText =
9+
"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")]
910
public bool WaitOnError { get; set; }
1011
}
1112

Src/Command/Utils/DeviceFinder.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ namespace BluetoothDevicePairing.Command.Utils
66
{
77
internal sealed class DeviceFinder
88
{
9-
public static Device FindDeviceByMac(List<Device> devices, MacAddress mac)
9+
public static List<Device> FindDevicesByMac(List<Device> devices, MacAddress mac)
1010
{
11-
var res = devices.Find(d => d.Mac.Address == mac.Address);
11+
var res = devices.FindAll(d => d.Mac.Equals(mac));
1212
if (res == null)
1313
{
14-
throw new Exception($"Couldn't find the device with '{mac}' mac address");
14+
throw new Exception($"Couldn't find any devices with '{mac}' mac address");
1515
}
1616

1717
return res;

Src/Program.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ private static int Main(string[] args)
3232
{
3333
Console.ReadLine();
3434
}
35+
3536
return 1;
3637
}
3738
}

0 commit comments

Comments
 (0)