-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathWin32BluetoothAuthentication.cs
150 lines (126 loc) · 5.54 KB
/
Win32BluetoothAuthentication.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
using RemoteController.Bluetooth.Core;
using RemoteController.Win32;
using System;
using System.Runtime.InteropServices;
using Win32Native = RemoteController.Win32.NativeMethods;
namespace RemoteController.Bluetooth.Win32
{
internal sealed class Win32BluetoothAuthentication
{
string _pin;
IntPtr _handle = IntPtr.Zero;
BluetoothAuthenticationCallbackEx _callback;
public ulong Address { get; set; }
public Win32BluetoothAuthentication(BluetoothAddress address, string pin)
{
Address = address;
_pin = pin;
BLUETOOTH_DEVICE_INFO device = BLUETOOTH_DEVICE_INFO.Create();
device.Address = address;
Win32Native.BluetoothGetDeviceInfo(IntPtr.Zero, ref device);
_callback = new BluetoothAuthenticationCallbackEx(Callback);
int result = Win32Native.BluetoothRegisterForAuthenticationEx(ref device, out _handle, _callback, IntPtr.Zero);
}
private bool Callback(IntPtr pvParam, ref BLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS pAuthCallbackParams)
{
switch (pAuthCallbackParams.authenticationMethod)
{
case BluetoothAuthenticationMethod.Passkey:
case BluetoothAuthenticationMethod.NumericComparison:
BLUETOOTH_AUTHENTICATE_RESPONSE__NUMERIC_COMPARISON_PASSKEY_INFO nresponse = new BLUETOOTH_AUTHENTICATE_RESPONSE__NUMERIC_COMPARISON_PASSKEY_INFO
{
authMethod = pAuthCallbackParams.authenticationMethod,
bthAddressRemote = pAuthCallbackParams.deviceInfo.Address,
numericComp_passkey = pAuthCallbackParams.Numeric_Value_Passkey
};
return Win32Native.BluetoothSendAuthenticationResponseEx(IntPtr.Zero, ref nresponse) == 0;
case BluetoothAuthenticationMethod.Legacy:
BLUETOOTH_AUTHENTICATE_RESPONSE__PIN_INFO response = new BLUETOOTH_AUTHENTICATE_RESPONSE__PIN_INFO();
response.authMethod = pAuthCallbackParams.authenticationMethod;
response.bthAddressRemote = pAuthCallbackParams.deviceInfo.Address;
response.pinInfo.pin = new byte[16];
System.Text.Encoding.ASCII.GetBytes(_pin).CopyTo(response.pinInfo.pin, 0);
response.pinInfo.pinLength = _pin.Length;
return Win32Native.BluetoothSendAuthenticationResponseEx(IntPtr.Zero, ref response) == 0;
}
return false;
}
#region IDisposable Support
private bool disposedValue = false; // To detect redundant calls
void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
// TODO: dispose managed state (managed objects).
}
Win32Native.BluetoothUnregisterAuthentication(_handle);
disposedValue = true;
}
}
~Win32BluetoothAuthentication()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(false);
}
// This code added to correctly implement the disposable pattern.
public void Dispose()
{
// Do not change this code. Put cleanup code in Dispose(bool disposing) above.
Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
[StructLayout(LayoutKind.Sequential, Size = 52)]
internal struct BLUETOOTH_AUTHENTICATE_RESPONSE__PIN_INFO // see above
{
internal ulong bthAddressRemote;
internal BluetoothAuthenticationMethod authMethod;
internal BLUETOOTH_PIN_INFO pinInfo;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
private byte[] _padding;
internal byte negativeResponse;
}
[StructLayout(LayoutKind.Sequential, Size = 52)]
internal struct BLUETOOTH_AUTHENTICATE_RESPONSE__OOB_DATA_INFO // see above
{
internal ulong bthAddressRemote;
internal BluetoothAuthenticationMethod authMethod;
internal BLUETOOTH_OOB_DATA_INFO oobInfo;
internal byte negativeResponse;
}
[StructLayout(LayoutKind.Sequential, Size = 52)]
internal struct BLUETOOTH_AUTHENTICATE_RESPONSE__NUMERIC_COMPARISON_PASSKEY_INFO // see above
{
internal ulong bthAddressRemote;
internal BluetoothAuthenticationMethod authMethod;
internal uint numericComp_passkey;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 28)]
private byte[] _padding;
internal byte negativeResponse;
}
/// <summary>
/// The BLUETOOTH_PIN_INFO structure contains information used for authentication via PIN.
/// </summary>
[StructLayout(LayoutKind.Sequential, Size = 20)]
internal struct BLUETOOTH_PIN_INFO
{
public const int BTH_MAX_PIN_SIZE = 16;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = BTH_MAX_PIN_SIZE)]
internal byte[] pin;
internal int pinLength;
}
/// <summary>
/// The BLUETOOTH_OOB_DATA_INFO structure contains data used to authenticate prior to establishing an Out-of-Band device pairing.
/// </summary>
[StructLayout(LayoutKind.Sequential, Size = 32)]
internal struct BLUETOOTH_OOB_DATA_INFO
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
internal byte[] C;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
internal byte[] R;
}
}