init
This commit is contained in:
@@ -0,0 +1,422 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Ports;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using DTS.Common.DASResource;
|
||||
using DTS.Common.Interface.Connection;
|
||||
using DTS.Common.Utilities.Logging;
|
||||
|
||||
namespace DTS.Common.WINUSBConnection
|
||||
{
|
||||
public class UsbRecAsyncResult : IAsyncResult
|
||||
{
|
||||
public object AsyncState { get; set; }
|
||||
public WaitHandle AsyncWaitHandle { get; set; }
|
||||
public bool CompletedSynchronously { get; set; }
|
||||
public bool IsCompleted { get; set; }
|
||||
public byte[] buffer { get; set; }
|
||||
public int Offset { get; set; }
|
||||
public int Size { get; set; }
|
||||
}
|
||||
|
||||
public class CDCUSBConnection : IConnection
|
||||
{
|
||||
/// <summary>
|
||||
/// returns true if the das has been soft disconnected or not
|
||||
/// </summary>
|
||||
public bool IsSoftDisconnected { get; private set; } = false;
|
||||
/// <summary>
|
||||
/// connect the das
|
||||
/// :note does nothing for CDCUSB, we don't have a soft disconnect option
|
||||
/// </summary>
|
||||
public void SoftConnect()
|
||||
{
|
||||
}
|
||||
/// <summary>
|
||||
/// disconnect the das
|
||||
/// :note does nothing for CDCUSB, we don't have a soft disconnect option
|
||||
/// </summary>
|
||||
public void SoftDisconnect()
|
||||
{
|
||||
|
||||
}
|
||||
void IConnection.KeepAliveErrorReceived()
|
||||
{
|
||||
|
||||
}
|
||||
public string GetConnectionData() { return ""; }
|
||||
public const int DTS_VENDOR_ID = 0x1CB9;
|
||||
public const string DTS_VENDOR_ID_STR = "VID_1CB9";
|
||||
private const string DTS_TSR2_CDCUSB_PRODUCT_ID_STR = "PID_001A";
|
||||
private static List<string> _regKeys;
|
||||
private static readonly object KEY_LOCK = new object();
|
||||
public static IList<string> RegKeys
|
||||
{
|
||||
get
|
||||
{
|
||||
lock (KEY_LOCK)
|
||||
{
|
||||
if (null != _regKeys) return _regKeys;
|
||||
_regKeys = new List<string>();
|
||||
ReadTSR2CDCUSBRegKeys();
|
||||
}
|
||||
return _regKeys;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Searches the system registry for a key that corresponds to the Peak CAN USB
|
||||
/// vendor and product ID.
|
||||
/// </summary>
|
||||
internal static void ReadTSR2CDCUSBRegKeys()
|
||||
{
|
||||
var ourKey = ReadOurNameRegistryKey();
|
||||
if (null == ourKey) { return; }
|
||||
foreach (var subKey in ourKey.GetSubKeyNames())
|
||||
{
|
||||
RegKeys.Add(subKey);
|
||||
}
|
||||
}
|
||||
internal static Microsoft.Win32.RegistryKey ReadOurNameRegistryKey()
|
||||
{
|
||||
var key = Microsoft.Win32.Registry.LocalMachine;
|
||||
const string ourName = @"SYSTEM\CurrentControlSet\Enum\USB\" + DTS_VENDOR_ID_STR + "&" + DTS_TSR2_CDCUSB_PRODUCT_ID_STR;
|
||||
key = key.OpenSubKey(ourName);
|
||||
|
||||
return key;
|
||||
}
|
||||
/// <summary>
|
||||
/// current upload rate in b/s
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public double GetCurrentUploadRate() { return 0D; }
|
||||
/// <summary>
|
||||
/// current download rate in b/s
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public double GetCurrentDownloadRate() { return 0D; }
|
||||
public event EventHandler OnDisconnected;
|
||||
private int _baudRate = 9600;
|
||||
private Parity _parity = Parity.None;
|
||||
private StopBits _stopBits = StopBits.One;
|
||||
private const int DATA_BITS = 8;
|
||||
public string PortName { get; set; }
|
||||
private readonly SerialPort _comPort = new SerialPort();
|
||||
|
||||
private string _devicePathname;
|
||||
protected bool _Connected;
|
||||
protected volatile bool Disposed;
|
||||
protected volatile bool Disposing;
|
||||
|
||||
public bool Connected => _Connected;
|
||||
|
||||
public string ConnectString => _devicePathname;
|
||||
|
||||
public System.Net.Sockets.SocketFlags Flags { get; set; }
|
||||
|
||||
private class AUSBRecFix
|
||||
{
|
||||
public readonly AsyncCallback Callback;
|
||||
public readonly UsbRecAsyncResult USBResult;
|
||||
|
||||
public AUSBRecFix(AsyncCallback callback, UsbRecAsyncResult usbResult)
|
||||
{
|
||||
Callback = callback;
|
||||
USBResult = usbResult;
|
||||
}
|
||||
}
|
||||
|
||||
public CDCUSBConnection()
|
||||
{
|
||||
Disposed = false;
|
||||
Disposing = false;
|
||||
_Connected = false;
|
||||
}
|
||||
|
||||
~CDCUSBConnection()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
|
||||
// Use SupressFinalize in case a subclass
|
||||
// of this type implements a finalizer.
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
// make sure we're not already disposed
|
||||
if (Disposed)
|
||||
return;
|
||||
|
||||
if (disposing)
|
||||
{
|
||||
Disposing = true;
|
||||
}
|
||||
|
||||
if (_comPort.IsOpen)
|
||||
{
|
||||
_comPort.Close();
|
||||
_Connected = false;
|
||||
}
|
||||
|
||||
Disposed = true;
|
||||
Disposing = false;
|
||||
}
|
||||
|
||||
public void Create(string connectString)
|
||||
{
|
||||
//Create(connectString); - this is recursive!
|
||||
}
|
||||
|
||||
public void Create(string connectString, string hostIPAddress)
|
||||
{
|
||||
foreach (var regKey in RegKeys)
|
||||
{
|
||||
if (!connectString.Contains(regKey.ToLower())) continue;
|
||||
var ourKey = ReadOurNameRegistryKey();
|
||||
ourKey = ourKey.OpenSubKey(regKey);
|
||||
ourKey = ourKey?.OpenSubKey("Device Parameters");
|
||||
var value = (string)ourKey?.GetValue("PortName");
|
||||
PortName = value;
|
||||
break;
|
||||
}
|
||||
_devicePathname = connectString;
|
||||
}
|
||||
|
||||
#region Disconnect
|
||||
|
||||
public IAsyncResult BeginDisconnect(bool reuseSocket,
|
||||
AsyncCallback cb,
|
||||
Object state)
|
||||
{
|
||||
var rar = new UsbRecAsyncResult
|
||||
{
|
||||
AsyncState = state,
|
||||
AsyncWaitHandle = new ManualResetEvent(false),
|
||||
CompletedSynchronously = false,
|
||||
IsCompleted = false,
|
||||
buffer = null,
|
||||
Offset = 0,
|
||||
Size = 0
|
||||
};
|
||||
if (!ThreadPool.QueueUserWorkItem(NetCallbackFix, new AUSBRecFix(cb, rar)))
|
||||
{
|
||||
throw new Exception(DASResource.Strings.CDCUSBConnection_BeginDisconnect_Err1);
|
||||
}
|
||||
return rar;
|
||||
}
|
||||
|
||||
public void EndDisconnect(IAsyncResult ar)
|
||||
{
|
||||
var rar = ar as UsbRecAsyncResult;
|
||||
|
||||
if (_comPort.IsOpen)
|
||||
{
|
||||
_comPort.Close();
|
||||
_Connected = false;
|
||||
_comPort.Dispose();
|
||||
}
|
||||
|
||||
((ManualResetEvent)rar?.AsyncWaitHandle)?.Set();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Accept
|
||||
|
||||
public IAsyncResult BeginAccept(AsyncCallback callback,
|
||||
object state)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public IConnection EndAccept(IAsyncResult asyncResult)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Listen
|
||||
|
||||
public void Listen(int backlog)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Bind
|
||||
|
||||
public void Bind(int port)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Connect
|
||||
|
||||
public IAsyncResult BeginConnect(AsyncCallback cb, object state)
|
||||
{
|
||||
var rar = new UsbRecAsyncResult
|
||||
{
|
||||
AsyncState = state,
|
||||
AsyncWaitHandle = new ManualResetEvent(false),
|
||||
CompletedSynchronously = false,
|
||||
IsCompleted = false,
|
||||
buffer = null,
|
||||
Offset = 0,
|
||||
Size = 0
|
||||
};
|
||||
if (!ThreadPool.QueueUserWorkItem(NetCallbackFix, new AUSBRecFix(cb, rar)))
|
||||
{
|
||||
// "USBConnection.BeginConnect: Unable to enqueue function"
|
||||
throw new Exception(DASResource.Strings.CDCUSBConnection_BeginConnect_Err1);
|
||||
}
|
||||
return rar;
|
||||
}
|
||||
|
||||
private void NetCallbackFix(object obj)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Disposed) return;
|
||||
var ausbrf = obj as AUSBRecFix;
|
||||
ausbrf?.Callback(ausbrf.USBResult);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
APILogger.Log(@"PcanUsbConnection.NetCallbackFix: Exception " + ex.Message + @" " + ex.StackTrace);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void EndConnect(IAsyncResult ar)
|
||||
{
|
||||
var rar = ar as UsbRecAsyncResult;
|
||||
|
||||
if (_comPort.IsOpen)
|
||||
{
|
||||
_comPort.Close();
|
||||
_Connected = false;
|
||||
}
|
||||
|
||||
_comPort.BaudRate = _baudRate;
|
||||
_comPort.DataBits = DATA_BITS;
|
||||
_comPort.StopBits = _stopBits;
|
||||
_comPort.Parity = _parity;
|
||||
_comPort.PortName = PortName;
|
||||
|
||||
try
|
||||
{
|
||||
_comPort.Open();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
_Connected = false;
|
||||
}
|
||||
|
||||
_Connected = true;
|
||||
|
||||
((ManualResetEvent)rar?.AsyncWaitHandle)?.Set();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Send
|
||||
|
||||
public IAsyncResult BeginSend(byte[] buffer, int offset, int size,
|
||||
AsyncCallback cb, object state)
|
||||
{
|
||||
var rar = new UsbRecAsyncResult
|
||||
{
|
||||
AsyncState = state,
|
||||
AsyncWaitHandle = new ManualResetEvent(false),
|
||||
CompletedSynchronously = false,
|
||||
IsCompleted = false,
|
||||
buffer = buffer,
|
||||
Offset = offset,
|
||||
Size = size
|
||||
};
|
||||
if (!ThreadPool.QueueUserWorkItem(NetCallbackFix, new AUSBRecFix(cb, rar)))
|
||||
{
|
||||
// "WINUSBConnection.BeginSend: Unable to enqueue function"
|
||||
throw new Exception(DASResource.Strings.CDCUSBConnection_BeginSend_Err1);
|
||||
}
|
||||
return rar;
|
||||
}
|
||||
|
||||
public int EndSend(IAsyncResult ar)
|
||||
{
|
||||
var rar = ar as UsbRecAsyncResult;
|
||||
if (null == rar)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
_comPort.Write(rar.buffer, 0, rar.Size);
|
||||
|
||||
((ManualResetEvent)rar.AsyncWaitHandle).Set();
|
||||
return rar.Size;
|
||||
}
|
||||
|
||||
public Task<int> SendAsync(byte[] sendBuffer, int bufferStartOffset, int bufferSizeToSend)
|
||||
{
|
||||
return Task<int>.Factory.FromAsync(
|
||||
(callback, state) => BeginSend(sendBuffer, bufferStartOffset, bufferSizeToSend, callback, state),
|
||||
EndSend, state: null
|
||||
);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Receive
|
||||
|
||||
public IAsyncResult BeginReceive(byte[] buffer, int offset, int size,
|
||||
AsyncCallback cb, object state)
|
||||
{
|
||||
var rar = new UsbRecAsyncResult
|
||||
{
|
||||
AsyncState = state,
|
||||
AsyncWaitHandle = new ManualResetEvent(false),
|
||||
CompletedSynchronously = false,
|
||||
IsCompleted = false,
|
||||
buffer = buffer,
|
||||
Offset = offset,
|
||||
Size = size
|
||||
};
|
||||
if (!ThreadPool.QueueUserWorkItem(NetCallbackFix, new AUSBRecFix(cb, rar)))
|
||||
{
|
||||
// "WINUSBConnection.BeginReceive: Unable to enqueue function"
|
||||
throw new Exception(DASResource.Strings.CDCUSBConnection_BeginReceive_Err1);
|
||||
}
|
||||
return rar;
|
||||
}
|
||||
|
||||
//private DateTime _lastHeartbeat;
|
||||
public int EndReceive(IAsyncResult ar)
|
||||
{
|
||||
var rar = ar as UsbRecAsyncResult;
|
||||
int bytesRead;
|
||||
|
||||
do
|
||||
{
|
||||
bytesRead = _comPort.Read(rar.buffer, 0, rar.Size);
|
||||
if (0 == bytesRead)
|
||||
{
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
|
||||
} while (0 == bytesRead);
|
||||
|
||||
((ManualResetEvent)rar.AsyncWaitHandle).Set();
|
||||
return bytesRead;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user