247 lines
10 KiB
C#
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;
|
|
}
|
|
}
|