AIParkingApplication/AIParkingApplication/C3DeviceController.cs

247 lines
10 KiB
C#

using System;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace AIParkingApplication
{
public delegate void C3DeviceEvent(int doorId, string cardNumber);
public class C3DeviceController : IDoorControlAccess
{
private string ipAddress;
private int port;
private IntPtr oneTimeConnectedParamHandler;
private string connectionString;
private bool isReconnected;
private int reconnectCounter;
public event C3DeviceEvent OnNewCardReceived;
public C3DeviceController(string ipAddress, int port = C3Constant.DEFAULT_C3_PORT)
{
this.ipAddress = ipAddress;
this.port = port;
connectionString = $"protocol=TCP,ipaddress={this.ipAddress},port={this.port},timeout=2000,passwd=";
oneTimeConnectedParamHandler = IntPtr.Zero;
isReconnected = true;
reconnectCounter = 0;
}
~C3DeviceController()
{
Disconnect();
}
[DllImport(C3Constant.PLCOMMPRO_DLL, EntryPoint = C3Constant.ENTRY_POINT_CONNECT)]
public static extern IntPtr Connect(string Parameters);
[DllImport(C3Constant.PLCOMMPRO_DLL, EntryPoint = C3Constant.ENTRY_POINT_PULL_LAST_ERROR)]
public static extern int PullLastError();
[DllImport(C3Constant.PLCOMMPRO_DLL, EntryPoint = C3Constant.ENTRY_POINT_DISCONNECT)]
public static extern void Disconnect(IntPtr h);
[DllImport(C3Constant.PLCOMMPRO_DLL, EntryPoint = C3Constant.ENTRY_POINT_CONTROL_DEVICE)]
public static extern int ControlDevice(IntPtr h, int operationid, int param1, int param2, int param3, int param4, string options);
[DllImport(C3Constant.PLCOMMPRO_DLL, EntryPoint = C3Constant.ENTRY_POINT_GET_RT_LOG)]
public static extern int GetRTLog(IntPtr h, ref byte buffer, int buffersize);
public ActionResult Connect()
{
if (Util.IsPingable(ipAddress, out long replyTime))
{
oneTimeConnectedParamHandler = Connect(connectionString);
if (oneTimeConnectedParamHandler != IntPtr.Zero)
{
var result = new ActionResult
{
HasError = false,
Message = string.Format(C3Constant.CONNECTED_SUCCESSFULLY, DateTime.Now.GetTimeFormatted(), ipAddress)
};
return result;
}
else
{
var result = new ActionResult
{
HasError = true,
Message = string.Format(C3Constant.FAILED_TO_CONNECT, DateTime.Now.GetTimeFormatted(), ipAddress, PullLastError())
};
return result;
}
}
else
{
var result = new ActionResult
{
HasError = true,
Message = string.Format(C3Constant.FAILED_TO_PING, DateTime.Now.GetTimeFormatted(), ipAddress)
};
return result;
}
}
public ActionResult OpenDoor(int doorId)
{
if (oneTimeConnectedParamHandler != IntPtr.Zero)
{
int controlDeviceResult = ControlDevice(oneTimeConnectedParamHandler, 1, doorId, 1, 1, 0, "");
if (controlDeviceResult >= 0)
{
var result = new ActionResult
{
HasError = false,
Message = string.Format(C3Constant.OPENNED_DOOR_SUCCESSFULLY, DateTime.Now.GetTimeFormatted(), ipAddress)
};
return result;
}
else
{
var result = new ActionResult
{
HasError = true,
Message = string.Format(C3Constant.FAILED_TO_OPEN_DOOR, DateTime.Now.GetTimeFormatted(), ipAddress)
};
return result;
}
}
else
{
var result = new ActionResult
{
HasError = true,
Message = string.Format(C3Constant.NOT_CONNECTTED, DateTime.Now.GetTimeFormatted(), ipAddress)
};
return result;
}
}
public async Task GetLogToReceiveNewCard()
{
while (true)
{
await Task.Delay(1000);
ActionResult getRTLogResult = GetRTLog(out int doorId, out string cardNumber);
if (doorId != C3Constant.DEFAULT_DOOR_ID && cardNumber != C3Constant.DEFAULT_CARD_NUMBER)
{
OnNewCardReceived?.Invoke(doorId, cardNumber);
}
}
}
private ActionResult GetRTLog(out int doorId, out string cardNumber)
{
doorId = C3Constant.DEFAULT_DOOR_ID;
cardNumber = C3Constant.DEFAULT_CARD_NUMBER;
if (!Util.IsPingable(ipAddress, out long replyTime))
{
isReconnected = false;
var result = new ActionResult
{
HasError = true,
Message = string.Format(C3Constant.FAILED_TO_PING, DateTime.Now.GetTimeFormatted(), ipAddress)
};
return result;
}
try
{
int buffersize = 256;
byte[] buffer = new byte[buffersize];
int resultRTLog = GetRTLog(oneTimeConnectedParamHandler, ref buffer[0], buffersize);
if (resultRTLog >= 0)
{
string bufferString = Encoding.Default.GetString(buffer);
string[] data = bufferString.Split(',');
reconnectCounter = 0;
cardNumber = data[2];
int.TryParse(data[3], out doorId);
var result = new ActionResult
{
HasError = false
};
return result;
}
else
{
reconnectCounter += 1;
if (!isReconnected && reconnectCounter >= C3Constant.MAX_TIME_GET_LOG_BEFORE_RECONNECT)
{
ActionResult reconnectResult = Connect();
if (!reconnectResult.HasError)
{
isReconnected = true;
reconnectCounter = 0;
reconnectResult.Message = string.Format(C3Constant.RECONNECTED_SUCCESSFULLY, DateTime.Now.GetTimeFormatted(), ipAddress);
}
return reconnectResult;
}
var result = new ActionResult
{
HasError = true,
Message = string.Format(C3Constant.FAILED_TO_READ_LOG, DateTime.Now.GetTimeFormatted(), ipAddress)
};
return result;
}
}
catch (Exception ex)
{
doorId = C3Constant.DEFAULT_DOOR_ID;
cardNumber = C3Constant.DEFAULT_CARD_NUMBER;
var result = new ActionResult
{
HasError = true,
Message = string.Format(C3Constant.WRONG_FORMAT_DATA, DateTime.Now.GetTimeFormatted(), ipAddress, ex.Message)
};
return result;
}
}
public ActionResult Disconnect()
{
Disconnect(oneTimeConnectedParamHandler);
oneTimeConnectedParamHandler = IntPtr.Zero;
var result = new ActionResult
{
HasError = false,
Message = string.Format(C3Constant.DISCONNECTED_SUCCESSFULLY, DateTime.Now.GetTimeFormatted(), ipAddress)
};
return result;
}
}
public static class C3Constant
{
#region DLL Entry Point
public const string PLCOMMPRO_DLL = "plcommpro.dll";
public const string ENTRY_POINT_CONNECT = "Connect";
public const string ENTRY_POINT_PULL_LAST_ERROR = "PullLastError";
public const string ENTRY_POINT_DISCONNECT = "Disconnect";
public const string ENTRY_POINT_CONTROL_DEVICE = "ControlDevice";
public const string ENTRY_POINT_GET_RT_LOG = "GetRTLog";
#endregion
public const int DEFAULT_C3_PORT = 4370;
public const string CONNECTED_SUCCESSFULLY = "{0}\t{1}\tKết nối thành công hệ thống đóng mở cửa";
public const string FAILED_TO_CONNECT = "{0}\t{1}\tKhông thể kết nối tới thiết bị C3\tError Code: {2}";
public const string NOT_CONNECTTED = "{0}\t{1}\tChưa kết nối tới thiết bị C3";
public const string FAILED_TO_PING = "{0}\t{1}\tKhông thể PING tới thiết bị C3";
public const string DISCONNECTED_SUCCESSFULLY = "{0}\t{1}\tĐã ngắt kết nối thành công tới thiết bị C3";
public const string OPENNED_DOOR_SUCCESSFULLY = "{0}\t{1}\tMở cửa thành công!";
public const string FAILED_TO_OPEN_DOOR = "{0}\t{1}\tKhông thể mở cửa!";
public const string WRONG_FORMAT_DATA = "{0}\t{1}\tĐịnh dạng dữ liệu đọc từ thiết bị sai!\tErrorMessage:{2}";
public const string FAILED_TO_READ_LOG = "{0}\t{1}\tKhông đọc được dữ liệu RTLog từ thiết bị C3";
public const string RECONNECTED_SUCCESSFULLY = "{0}\t{1}\tĐã kết nối lại tới thiết bị C3";
public const string DEFAULT_CARD_NUMBER = "0";
public const int DEFAULT_DOOR_ID = 0;
public const string DATETIME_FORMAT = "HH:mm:ss dd/MM/yyyy";
public const int MAX_TIME_GET_LOG_BEFORE_RECONNECT = 5;
}
}