internal static extern Int32 BluetoothSendAuthenticationResponse(IntPtr hRadio, ref BLUETOOTH_DEVICE_INFO pbtdi, string pszPasskey);
internal static extern int BluetoothUpdateDeviceRecord(ref BLUETOOTH_DEVICE_INFO pbtdi);
internal static extern UInt32 BluetoothRegisterForAuthenticationEx( ref BLUETOOTH_DEVICE_INFO pbtdi, out BluetoothAuthenticationRegistrationHandle phRegHandle, BluetoothAuthenticationCallbackEx pfnCallback, IntPtr pvParam);
internal static extern int BluetoothSetServiceState(IntPtr hRadio, ref BLUETOOTH_DEVICE_INFO pbtdi, ref Guid pGuidService, int dwServiceFlags);
internal static extern int BluetoothGetDeviceInfo(IntPtr hRadio, ref BLUETOOTH_DEVICE_INFO pbtdi);
internal static extern int BluetoothEnumerateInstalledServices(IntPtr hRadio, ref BLUETOOTH_DEVICE_INFO pbtdi, ref int pcServices, byte[] pGuidServices);
internal static extern bool BluetoothDisplayDeviceProperties(IntPtr hwndParent, ref BLUETOOTH_DEVICE_INFO pbtdi);
internal static extern int BluetoothAuthenticateDeviceEx(IntPtr hwndParentIn, IntPtr hRadioIn, ref BLUETOOTH_DEVICE_INFO pbtdiInout, byte[] pbtOobData, BluetoothAuthenticationRequirements authenticationRequirement);
internal static extern int BluetoothAuthenticateDevice(IntPtr hwndParent, IntPtr hRadio, ref BLUETOOTH_DEVICE_INFO pbtdi, string pszPasskey, int ulPasskeyLength);
//TODO PairRequest XmlDocs for XP and CE pre 5.0. /// <summary> /// Intiates pairing for a remote device. /// </summary> /// <param name="device">Remote device with which to pair.</param> /// <param name="pin">Chosen PIN code, must be between 1 and 16 ASCII characters.</param> /// <remarks><para>On Windows CE platforms this calls <c>BthPairRequest</c>, /// its MSDN remarks say: /// </para> /// <para>“BthPairRequest passes the parameters to the <c>BthSetPIN</c> /// function and creates an ACL connection. Once the connection is established, /// it calls the <c>BthAuthenticate</c> function to authenticate the device.” /// </para> /// <para>On Windows XP/Vista platforms this calls <c>BluetoothAuthenticateDevice</c>, /// if the pin argument is set to null a Wizard is displayed to accept a PIN from the user, /// otherwise the function executes in transparent mode. /// </para> /// <para>See also /// <see cref="M:InTheHand.Net.Bluetooth.BluetoothSecurity.SetPin(InTheHand.Net.BluetoothAddress,System.String)"/> /// </para> /// </remarks> /// <returns>Whether the operation was successful.</returns> public bool PairRequest(BluetoothAddress device, string pin) { if (device == null) { throw new ArgumentNullException("device"); } if (device.ToInt64() == 0) { throw new ArgumentNullException("device", "A non-blank address must be specified."); } #if NETCF if (pin == null) { throw new ArgumentNullException("pin"); } bool success = false; IBluetoothDeviceInfo bdi = new WindowsBluetoothDeviceInfo(device); if (System.Environment.OSVersion.Version.Major >= 5) { byte[] pinbytes = System.Text.Encoding.ASCII.GetBytes(pin); int len = pin.Length; int result = NativeMethods.BthPairRequest(device.ToByteArray(), len, pinbytes); if (result == 0) { success = true; } } else { //BthPairRequest is CE 5.0 onwards so we will do it with individual steps //preset outgoing pin success = SetPin(device, pin); if (success) { int hresult; ushort handle = 0; //connect to device try { hresult = NativeMethods.BthCreateACLConnection(device.ToByteArray(), out handle); if (hresult != 0) { success = false; } else { //force authentication hresult = NativeMethods.BthAuthenticate(device.ToByteArray()); if (hresult != 0) { success = false; } } } finally { if (handle != 0) { //close connection hresult = NativeMethods.BthCloseConnection(handle); } } } } if (success) { //setup UI pairing (registry) RegistryKey rkDevices = Registry.LocalMachine.CreateSubKey(NativeMethods.ceRegistryRoot + "\\Device"); RegistryKey rkNewDevice = rkDevices.CreateSubKey(device.ToString()); rkNewDevice.SetValue("name", bdi.DeviceName); rkNewDevice.SetValue("trusted", 1); rkNewDevice.SetValue("class", bdi.ClassOfDevice.GetHashCode()); //#if V2 RegistryKey rkServices = rkNewDevice.CreateSubKey("Services"); ServiceRecord[] recs = bdi.GetServiceRecords(BluetoothService.SerialPort); //byte[][] recs = bdi.GetServiceRecordsUnparsedWindowsRaw(BluetoothService.SerialPort); if (recs.Length > 0) { byte[] servRecord = recs[0].SourceBytes; RegistryKey rkSerial = rkServices.CreateSubKey(BluetoothService.SerialPort.ToString()); rkSerial.SetValue("sdprecord", servRecord); rkSerial.SetValue("Name", "Serial Port"); rkSerial.SetValue("enabled", 1); int channel = ServiceRecordHelper.GetRfcommChannelNumber(recs[0]); if (channel != -1) { rkSerial.SetValue("channel", 0x14b0000 + channel); } else { System.Diagnostics.Debug.Fail("PairRequest CE, peer SPP record missing channel."); } rkSerial.Close(); } rkServices.Close(); //#endif rkNewDevice.Close(); rkDevices.Close(); } return(success); #else //use other constructor to ensure struct size is set BLUETOOTH_DEVICE_INFO bdi = new BLUETOOTH_DEVICE_INFO(device.ToInt64()); //string length, but allow for null pins for UI int length = 0; if (pin != null) { length = pin.Length; } int result = NativeMethods.BluetoothAuthenticateDevice(IntPtr.Zero, IntPtr.Zero, ref bdi, pin, length); if (result != 0) { //determine error cause from "result"... // ERROR_INVALID_PARAMETER 87 // WAIT_TIMEOUT 258 // ERROR_NOT_AUTHENTICATED 1244 Debug.WriteLine("PairRequest/BAD failed with: " + result); return(false); } return(true); #endif }