diff --git a/README.md b/README.md index 798fd60..a75a90b 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,14 @@ Windows 10 1809 (10.0.17763) or higher
* Discover devices: `BluetoothDevicePairing.exe discover` * Pair and connect to a device using its mac address: `BluetoothDevicePairing.exe pair --mac 12:34:56:78:9A:BC` * Pair and connect to a device using its name: `BluetoothDevicePairing.exe pair --name "name of device"` +* Pair and connect to a device using its name/mac and device type: `BluetoothDevicePairing.exe pair --name "name of device" --type BluetoothLE` * Unpair a device using its mac address: `BluetoothDevicePairing.exe unpair --mac 12:34:56:78:9A:BC` * Unpair a device using its name: `BluetoothDevicePairing.exe unpair --name "name of device"` +* Unpair a device using its name/mac and device type: `BluetoothDevicePairing.exe unpair --mac 12:34:56:78:9A:BC --type Bluetooth` # Tips and tricks * Bluetooth LE devices use mac address randomisation, therefore it is not reliable to pair them using mac address. Use pairing by name instead. +* Some devices advertize itself as Bluetooth and BluetoothLE simultaneously while having the same mac and name. To work with such devices explicitly specify to which type of device you want to connect using `--type` parameter. # Build * Use `Visual Studio 2019` to open the solution file and work with the code diff --git a/Src/Command/DiscoverDevices.cs b/Src/Command/DiscoverDevices.cs index 925bab4..45adc6e 100644 --- a/Src/Command/DiscoverDevices.cs +++ b/Src/Command/DiscoverDevices.cs @@ -30,7 +30,7 @@ private static void PrintDevice(Device d) private static string GetType(Device d) { - return d.Type == DeviceType.BluetoothLe ? "LE" : ""; + return d.Type == Bluetooth.DeviceType.BluetoothLe ? "LE" : ""; } private static string GetPairedStatus(Device d) diff --git a/Src/Command/PairDevice.cs b/Src/Command/PairDevice.cs index 10f9cf7..1bef31e 100644 --- a/Src/Command/PairDevice.cs +++ b/Src/Command/PairDevice.cs @@ -20,11 +20,11 @@ public static void Execute(PairDeviceOptions opts) { if (!string.IsNullOrEmpty(opts.Mac)) { - PairWithMac(new MacAddress(opts.Mac), opts.DiscoveryTime); + PairWithMac(new MacAddress(opts.Mac), opts.DiscoveryTime, opts.Type); } else if (!string.IsNullOrEmpty(opts.DeviceName)) { - PairWithName(opts.DeviceName, opts.DiscoveryTime); + PairWithName(opts.DeviceName, opts.DiscoveryTime, opts.Type); } else { @@ -32,9 +32,9 @@ public static void Execute(PairDeviceOptions opts) } } - private static void PairWithMac(MacAddress mac, int discoveryTime) + private static void PairWithMac(MacAddress mac, int discoveryTime, Utils.DeviceType deviceType) { - var devices = DeviceFinder.FindDevicesByMac(DeviceDiscoverer.DiscoverBluetoothDevices(discoveryTime), mac); + var devices = DeviceFinder.FindDevicesByMac(DeviceDiscoverer.DiscoverBluetoothDevices(discoveryTime), mac, deviceType); if (devices.Count == 1) { @@ -42,33 +42,26 @@ private static void PairWithMac(MacAddress mac, int discoveryTime) return; } - if (devices.Count == 2 && devices[0].Type != devices[1].Type && devices[0].Name == devices[1].Name) + if (devices.Count == 2) { - HandleSituation_2_Bluetooth_devices_with_the_same_mac_and_name_found(devices[0], devices[1]); - return; + throw new Exception( + $"2 devices with the mac '{mac}' found \"{devices[0]}\" and \"{devices[1]}\". Don't know which one to choose.\n"); } 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) + private static void PairWithName(string name, int discoveryTime, Utils.DeviceType deviceType) { - var devices = DeviceFinder.FindDevicesByName(DeviceDiscoverer.DiscoverBluetoothDevices(discoveryTime), name); + var devices = DeviceFinder.FindDevicesByName(DeviceDiscoverer.DiscoverBluetoothDevices(discoveryTime), name, deviceType); if (devices.Count == 1) { DevicePairer.PairDevice(devices[0]); 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) + if (devices.Count == 2 && devices[0].Type == Bluetooth.DeviceType.BluetoothLe && devices[1].Type == Bluetooth.DeviceType.BluetoothLe) { HandleSituation_2_BluetoothLe_devices_with_the_same_name_found(devices[0], devices[1]); return; @@ -98,21 +91,5 @@ private static void HandleSituation_2_BluetoothLe_devices_with_the_same_name_fou 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); - } } } diff --git a/Src/Command/UnPairDevice.cs b/Src/Command/UnPairDevice.cs index 945d206..ef34eb6 100644 --- a/Src/Command/UnPairDevice.cs +++ b/Src/Command/UnPairDevice.cs @@ -19,11 +19,11 @@ public static void Execute(UnpairDeviceOptions opts) { if (!string.IsNullOrEmpty(opts.Mac)) { - UnpairByMac(new MacAddress(opts.Mac), opts.DiscoveryTime); + UnpairByMac(new MacAddress(opts.Mac), opts.DiscoveryTime, opts.Type); } else if (!string.IsNullOrEmpty(opts.DeviceName)) { - UnpairByName(opts.DeviceName, opts.DiscoveryTime); + UnpairByName(opts.DeviceName, opts.DiscoveryTime, opts.Type); } else { @@ -31,54 +31,26 @@ public static void Execute(UnpairDeviceOptions opts) } } - public static void UnpairByMac(MacAddress mac, int discoveryTime) + public static void UnpairByMac(MacAddress mac, int discoveryTime, Utils.DeviceType deviceType) { - 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) + var devices = DeviceFinder.FindDevicesByMac(DeviceDiscoverer.DiscoverPairedBluetoothDevices(discoveryTime), mac, deviceType); + if (devices.Count > 1) { - 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"); } - throw new Exception($"{devices.Count} devices found, don't know which one to choose"); + DevicePairer.UnpairDevice(devices[0]); } - public static void UnpairByName(string name, int discoveryTime) + public static void UnpairByName(string name, int discoveryTime, Utils.DeviceType deviceType) { - var devices = DeviceFinder.FindDevicesByName(DeviceDiscoverer.DiscoverPairedBluetoothDevices(discoveryTime), name); - - if (devices.Count == 1) - { - DevicePairer.UnpairDevice(devices[0]); - return; - } - - if (devices.Count == 2 && devices[0].Type != devices[1].Type && devices[0].Mac.Equals(devices[1].Mac)) + var devices = DeviceFinder.FindDevicesByName(DeviceDiscoverer.DiscoverPairedBluetoothDevices(discoveryTime), name, deviceType); + if (devices.Count > 1) { - 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"); } - 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); + DevicePairer.UnpairDevice(devices[0]); } } } diff --git a/Src/Command/Utils/CommonOptions.cs b/Src/Command/Utils/CommonOptions.cs index a7997a3..f5757d2 100644 --- a/Src/Command/Utils/CommonOptions.cs +++ b/Src/Command/Utils/CommonOptions.cs @@ -19,5 +19,10 @@ internal class PairAndUnpairDeviceOptions : CommonOptions [Option("name", SetName = "name", HelpText = "name of a bluetooth device (case sensitive)")] public string DeviceName { get; set; } + + [Option("type", Default = DeviceType.Any, + HelpText = + "type of bluetooth device. You can use this flag if you want to explicitly specify what type of bluetooth devices you want to work with. Possible values (case sensitive): Bluetooth, BluetoothLE, Any")] + public DeviceType Type { get; set; } } } diff --git a/Src/Command/Utils/DeviceFinder.cs b/Src/Command/Utils/DeviceFinder.cs index cf2758b..f819c58 100644 --- a/Src/Command/Utils/DeviceFinder.cs +++ b/Src/Command/Utils/DeviceFinder.cs @@ -6,24 +6,24 @@ namespace BluetoothDevicePairing.Command.Utils { internal sealed class DeviceFinder { - public static List FindDevicesByMac(List devices, MacAddress mac) + public static List FindDevicesByMac(List devices, MacAddress mac, DeviceType deviceType) { - var res = devices.FindAll(d => d.Mac.Equals(mac)); + var res = devices.FindAll(d => d.Mac.Equals(mac) && DeviceTypeExtensions.Equals(deviceType, d.Type)); if (res == null) { - throw new Exception($"Couldn't find any devices with '{mac}' mac address"); + throw new Exception($"Couldn't find any devices with '{mac}' mac address and device type '{deviceType}'"); } return res; } - public static List FindDevicesByName(List devices, string name) + public static List FindDevicesByName(List devices, string name, DeviceType deviceType) { - var res = devices.FindAll(d => d.Name == name); + var res = devices.FindAll(d => d.Name == name && DeviceTypeExtensions.Equals(deviceType, d.Type)); if (res.Count == 0) { - throw new Exception($"Couldn't find any devices with '{name}' name"); + throw new Exception($"Couldn't find any devices with '{name}' name and device type '{deviceType}'"); } return res; diff --git a/Src/Command/Utils/DeviceType.cs b/Src/Command/Utils/DeviceType.cs new file mode 100644 index 0000000..d9410a1 --- /dev/null +++ b/Src/Command/Utils/DeviceType.cs @@ -0,0 +1,28 @@ +namespace BluetoothDevicePairing.Command.Utils +{ + enum DeviceType + { + Bluetooth, + BluetoothLE, + Any + } + + static class DeviceTypeExtensions + { + public static bool Equals(DeviceType type1, Bluetooth.DeviceType type2) + { + if (type1 == DeviceType.Any) + { + return true; + } + + if ( type1 == DeviceType.Bluetooth && type2 == Bluetooth.DeviceType.Bluetooth + || type1 == DeviceType.BluetoothLE && type2 == Bluetooth.DeviceType.BluetoothLe) + { + return true; + } + + return false; + } + } +}