Сопряжение Bluetooth с использованием 32 футов не дает того же результата, что и ручное сопряжение (Windows Mobile 6.5.3)
Я использую библиотеки 32Feet, чтобы установить соединение между MC75 и устройством с микросхемой и выводом.
Кажется, что и сопряжение, и проверка соединения с использованием библиотеки работают правильно, но при создании виртуального com-порта и последующем использовании его в качестве последовательного порта происходит сбой.
Как только спаривание было предположительно установлено, приложение затем тестирует спаривание, используя виртуальный com-порт. Затем существует отдельное приложение, которое использует этот виртуальный com-порт, но не может установить соединение, пока я не удалю и не воссоздаю сопряжение вручную на устройстве Windo ws Mobile.
У кого-нибудь есть предложения?
Ниже приведены некоторые фрагменты кода...
/// <summary>
/// Create the pairing configuration for the bluetooth device.
/// </summary>
/// <param name="bluetoothAddress">Bluetooth device address</param>
/// <param name="passcode">Passcode for the connection</param>
/// <returns>True if the pairing was created.</returns>
private bool CreatePairing(BluetoothAddress bluetoothAddress, string passcode)
{
BluetoothRadio.PrimaryRadio.Mode = RadioMode.Connectable;
bool success = false;
// Get the info of the device and tell it to use the serial port
var device = new BluetoothDeviceInfo(bluetoothAddress);
try
{
Log.InfoFormat("Pairing with device {0}", bluetoothAddress);
// Create an end point with the address using a serial port
var btEndPoint = new BluetoothEndPoint(bluetoothAddress, BluetoothService.SerialPort);
// Ensure the device will use the virtual com port by setting the service state
device.SetServiceState(BluetoothService.SerialPort, true, true);
var bluetoothClient = new BluetoothClient();
Log.Info("Set Service State of bluetooth device.");
// Use the address to specify the pairing reqest
bool pairedState = BluetoothSecurity.PairRequest(device.DeviceAddress, passcode);
Log.Info("Pairing requested");
// Use the end point to make the connection
bluetoothClient.Connect(btEndPoint);
if (bluetoothClient.Connected)
{
Log.Info("Paired device connected");
bluetoothClient.Close();
success = true;
}
else
{
// The connection failed so remove the pairing
BluetoothSecurity.RemoveDevice(bluetoothAddress);
// Remove the com port
device.SetServiceState(BluetoothService.SerialPort, false, true);
}
}
catch (Exception ex)
{
...
}
finally
{
BluetoothRadio.PrimaryRadio.Mode = RadioMode.PowerOff;
}
return success;
}
Это мой метод испытаний
/// <summary>
/// Alternative method of validating the comms port
/// </summary>
/// <returns>True if connection was successful else False.</returns>
private bool ReconnectDevice2()
{
BluetoothRadio.PrimaryRadio.Mode = RadioMode.Connectable;
bool connectionState = false;
try
{
// Set the port number to the value paired
string unitPort = "COM9";
DeviceSerialPort dsp = new DeviceSerialPort(unitPort);
connectionState = dsp.Open();
dsp.Close();
}
}
catch (Exception ex)
{
...
}
finally
{
BluetoothRadio.PrimaryRadio.Mode = RadioMode.PowerOff;
}
return connectionState;
}
Класс DeviceSerialPort
namespace PairingTool
{
using System;
using System.IO.Ports;
using log4net;
/// <summary>
/// Interfaces with a serial port. There should only be one instance of this class for each serial port to be used.
/// </summary>
internal class DeviceSerialPort
{
private static readonly ILog Log = LogManager.GetLogger(typeof(BluetoothForm));
private const string ClassName = "DeviceSerialPort";
internal enum Timeout
{
Short = 6000,
AckWait = 9000,
CommandResponse = 9000,
Download = 9000,
TransactionLoop = 180000,
Authorisation = 600000
}
#region Private Members
/// <summary>
/// Serial port class
/// </summary>
private SerialPort serialPort;
/// <summary>
/// BaudRate set to default for Serial Port Class
/// </summary>
private int baudRate;
/// <summary>
/// DataBits set to default for Serial Port Class
/// </summary>
private int dataBits;
/// <summary>
/// Handshake set to default for Serial Port Class
/// </summary>
private Handshake handshake;
/// <summary>
/// Parity set to default for Serial Port Class
/// </summary>
private Parity parity;
/// <summary>
/// Communication Port name, not default in SerialPort. Defaulted to COM4 as this seems to be the Thyron default
/// </summary>
private string portName;
/// <summary>
/// StopBits set to default for Serial Port Class
/// </summary>
private StopBits stopBits;
/// <summary>
/// continueRead when set to false will interupt the current reading of the port.
/// </summary>
private bool continueRead;
#endregion
#region Properties
/// <summary>
/// Gets or sets BaudRate (Default: 9600)
/// </summary>
internal int BaudRate
{
get { return this.baudRate; }
set { this.baudRate = value; }
}
/// <summary>
/// Gets or sets DataBits (Default: 8)
/// </summary>
internal int DataBits
{
get { return this.dataBits; }
set { this.dataBits = value; }
}
/// <summary>
/// Gets or sets Handshake (Default: None)
/// </summary>
internal Handshake Handshake
{
get { return this.handshake; }
set { this.handshake = value; }
}
/// <summary>
/// Gets or sets Parity (Default: None)
/// </summary>
internal Parity Parity
{
get { return this.parity; }
set { this.parity = value; }
}
/// <summary>
/// Gets or sets PortName (Default: COM1)
/// </summary>
internal string PortName
{
get { return this.portName; }
set { this.portName = value; }
}
/// <summary>
/// Gets or sets StopBits (Default: One}
/// </summary>
internal StopBits StopBits
{
get { return this.stopBits; }
set { this.stopBits = value; }
}
internal string ErrorMessage
{
get;
private set;
}
#endregion
internal DeviceSerialPort()
{
this.serialPort = new SerialPort();
this.baudRate = 19200;
this.dataBits = 8;
this.handshake = Handshake.None;
this.parity = Parity.None;
this.stopBits = StopBits.One;
}
internal DeviceSerialPort(string comPort)
{
this.serialPort = new SerialPort();
this.portName = comPort;
this.baudRate = 19200;
this.dataBits = 8;
this.handshake = Handshake.None;
this.parity = Parity.None;
this.stopBits = StopBits.One;
}
/// <summary>
/// Sets the current settings for the COM port and tries to open it.
/// </summary>
/// <returns>True if successful, false otherwise</returns>
internal bool Open()
{
bool success = false;
// Initialise the port prior to connecting
this.serialPort = new SerialPort(this.portName);
this.serialPort.Close(); // Force the serial port to be closed to ensure a stable state.
this.serialPort.BaudRate = this.baudRate;
this.serialPort.DataBits = this.dataBits;
this.serialPort.Handshake = this.handshake;
this.serialPort.Parity = this.parity;
this.serialPort.PortName = this.portName;
this.serialPort.StopBits = this.stopBits;
this.serialPort.ReadTimeout = (int)Timeout.AckWait;
this.serialPort.WriteTimeout = (int)Timeout.CommandResponse;
try
{
this.serialPort.Open();
success = this.serialPort.IsOpen;
}
catch (InvalidOperationException ex)
{
this.ErrorMessage = "Port is already open.";
Log.Error(this.ErrorMessage);
Log.DebugFormat("Exception {0}, {1} ", ex.Message, ex.StackTrace);
success = false;
}
catch (ArgumentException ex)
{
this.ErrorMessage = "Invalid port name or the port is not supported.";
Log.Error(this.ErrorMessage);
Log.DebugFormat("Exception {0}, {1} ", ex.Message, ex.StackTrace);
success = false;
}
catch (UnauthorizedAccessException ex)
{
this.ErrorMessage = "Access to the port was denied.";
Log.Error(this.ErrorMessage);
Log.DebugFormat("Exception {0}, {1} ", ex.Message, ex.StackTrace);
success = false;
}
catch (System.IO.IOException ex)
{
this.ErrorMessage = "The port was available but a connection could not be made, try again.";
Log.Error(this.ErrorMessage);
Log.DebugFormat("Exception {0}, {1} ", ex.Message, ex.StackTrace);
success = false;
}
catch (Exception ex)
{
this.ErrorMessage = "Unexpected Exception";
Log.Error(this.ErrorMessage);
Log.DebugFormat("Exception {0}, {1} ", ex.Message, ex.StackTrace);
success = false;
}
return success;
}
public bool IsOpen()
{
return this.serialPort.IsOpen;
}
internal void Close()
{
if (this.serialPort != null)
{
Log.Info("Closing the COM port.");
this.serialPort.Close();
}
}
}
}
1 ответ
Проблема не имеет ничего общего с тем, как соединение пар хранится в реестре.
Оказывается, когда вы открываете последовательный порт, вам нужно дать ему стабилизироваться, прежде чем что-либо делать с ним. В идеале, вы получите истинное значение из свойства "IsOpen" только после его стабилизации, но в противном случае вам просто нужно добавить задержку...
this.serialPort.Open();
// Delay to ensure that the serial port is in a stable state
Thread.Sleep(StabilisationDelay);
success = this.serialPort.IsOpen;