Чтение RFID на считывателе Hikvision DS-K1 F 100D 8E с использованием SDK (HCUsbSDK)C#

Место общения программистов C#
Ответить Пред. темаСлед. тема
Anonymous
 Чтение RFID на считывателе Hikvision DS-K1 F 100D 8E с использованием SDK (HCUsbSDK)

Сообщение Anonymous »

Мой проект C# должен взаимодействовать с устройством чтения Hikvision DS-K1F100-D8E с помощью HCUsbSDK. Изначально ридер работает только с IVMS-4000, и я хочу научить его работать в режиме эмуляции клавиатуры.
Что уже работает:
Приложение инициализирует SDK с помощью USB_SDK_Init(). Если инициализация прошла успешно, происходит переход к следующему шагу; в противном случае он извлекает код ошибки и регистрирует его.
Перечисление устройств. Приложение выводит список подключенных USB-устройств, используя метод обратного вызова USB_SDK_EnumDevice.
Программа ищет устройство с именем «DS-K1F100-D8E». Если устройство найдено, информация об устройстве сохраняется.
Войти на устройство.
Приложение включается в систему с помощью функции USB_SDK_Login(). В случае успешного входа в систему программа получает имя устройства, серийный номер и версию программного обеспечения.
Управление ресурсами. Независимо от успеха или неудачи, приложение выключает устройство и очищает SDK, чтобы освободить ресурсы.
Код:
//Program.cs
using System;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Attempting to initialize SDK...");

if (!SDKManager.Initialize())
{
return;
}

var device = DeviceManager.EnumerateAndFindDevice("DS-K1F100-D8E");
if (device == null)
{
Console.WriteLine("Device not found.");
return;
}

var userId = (int)DeviceManager.LoginToDevice(device.Value); // Explicit cast to int
if (userId == -1)
{
return;
}

try
{
// Create an instance of the CardReader class
CardReader reader = new CardReader();
reader.UserID = userId; // Set the UserID

// Example of card activation with a 5-second wait
bool success = reader.ActivateCard(5);
if (success)
{
Console.WriteLine("Card activation was successful.");
}
else
{
Console.WriteLine("Card activation failed.");
}
}
finally
{
// Logout and cleanup resources regardless of card activation result
ResourceManager.LogoutAndCleanup(userId);
}
}
}

//Structures.cs
using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct USB_SDK_DEVICE_INFO
{
public uint dwSize;
public uint dwVID;
public uint dwPID;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] szManufacturer;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] szDeviceName;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
public byte[] szSerialNumber;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 68)]
public byte[] byRes;

public void Init()
{
szManufacturer = new byte[32];
szDeviceName = new byte[32];
szSerialNumber = new byte[48];
byRes = new byte[68];
}
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct USB_SDK_USER_LOGIN_INFO
{
public uint dwSize;
public uint dwTimeout;
public uint dwVID;
public uint dwPID;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] szUserName;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
public byte[] szPassword;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
public byte[] szSerialNumber;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)]
public byte[] byRes;

public void Init()
{
szUserName = new byte[32];
szPassword = new byte[16];
szSerialNumber = new byte[48];
byRes = new byte[80];
}
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct USB_SDK_DEVICE_REG_RES
{
public uint dwSize;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public byte[] szDeviceName;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
public byte[] szSerialNumber;
public uint dwSoftwareVersion;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
public byte[] byRes;

public void Init()
{
szDeviceName = new byte[32];
szSerialNumber = new byte[48];
byRes = new byte[40];
}
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct USB_SDK_WAIT_SECOND
{
public uint dwSize;
public byte byWait;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 27)]
public byte[] byRes;

public void Init()
{
byRes = new byte[27];
}
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct USB_SDK_ACTIVATE_CARD_RES
{
public uint dwSize;
public byte byCardType;
public byte bySerialLen;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
public byte[] bySerial;
public byte bySelectVerifyLen;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public byte[] bySelectVerify;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)]
public byte[] byRes;

public void Init()
{
bySerial = new byte[10];
bySelectVerify = new byte[3];
byRes = new byte[12];
}
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct USB_CONFIG_INPUT_INFO
{
public IntPtr lpCondBuffer;
public uint dwCondBufferSize;
public IntPtr lpInBuffer;
public uint dwInBufferSize;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 48)]
public byte[] byRes;

public void Init()
{
byRes = new byte[48];
}
}

[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct USB_CONFIG_OUTPUT_INFO
{
public IntPtr lpOutBuffer;
public uint dwOutBufferSize;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 56)]
public byte[] byRes;

public void Init()
{
byRes = new byte[56];
}
}

//SdkManager.cs
using System;
using System.Runtime.InteropServices;

public static class SDKManager
{
[DllImport("HCUsbSDK.dll", CallingConvention = CallingConvention.StdCall)]
private static extern bool USB_SDK_Init();

[DllImport("HCUsbSDK.dll", CallingConvention = CallingConvention.StdCall)]
private static extern int USB_SDK_GetLastError();

[DllImport("HCUsbSDK.dll", CallingConvention = CallingConvention.StdCall)]
private static extern bool USB_SDK_Cleanup();

[DllImport("HCUsbSDK.dll", CallingConvention = CallingConvention.StdCall)]
private static extern bool USB_SDK_SetLogToFile(uint logLevel, string logDir, bool autoDel);

public static bool Initialize()
{
USB_SDK_SetLogToFile(3, "C:\\Logs", true);

bool initResult = USB_SDK_Init();
if (!initResult)
{
int errorCode = USB_SDK_GetLastError();
Console.WriteLine($"SDK initialization error. Error code: {errorCode}");
return false;
}
Console.WriteLine("SDK successfully initialized.");
return true;
}

public static bool Cleanup()
{
Console.WriteLine("Attempting to cleanup resources...");
bool cleanupResult = USB_SDK_Cleanup();
if (!cleanupResult)
{
int errorCode = USB_SDK_GetLastError();
Console.WriteLine($"Resource cleanup error. Error code: {errorCode}");
return false;
}
Console.WriteLine("Resources successfully cleaned up.");
return true;
}

public const uint USB_SDK_GET_ACTIVATE_CARD = 0x0104; // Card activation command

public static int GetLastError()
{
return USB_SDK_GetLastError();
}
}

//DeviceManager.cs
using System;
using System.Runtime.InteropServices;
using System.Text;

public static class DeviceManager
{
[DllImport("HCUsbSDK.dll", CallingConvention = CallingConvention.StdCall)]
private static extern bool USB_SDK_EnumDevice(EnumDeviceCallBack cbEnumDeviceCallBack, IntPtr pUser);

[DllImport("HCUsbSDK.dll", CallingConvention = CallingConvention.StdCall)]
private static extern long USB_SDK_Login(ref USB_SDK_USER_LOGIN_INFO loginInfo, ref USB_SDK_DEVICE_REG_RES deviceInfo);

[DllImport("HCUsbSDK.dll", CallingConvention = CallingConvention.StdCall)]
private static extern bool USB_SDK_Logout(int lUserID);

private static USB_SDK_DEVICE_INFO? targetDevice = null;

public static USB_SDK_DEVICE_INFO? EnumerateAndFindDevice(string deviceName)
{
Console.WriteLine("Attempting to enumerate devices...");
bool enumResult = USB_SDK_EnumDevice(DeviceEnumCallback, IntPtr.Zero);
if (!enumResult)
{
int errorCode = SDKManager.GetLastError();
Console.WriteLine($"Device enumeration error. Error code: {errorCode}");
return null;
}
Console.WriteLine("Devices successfully enumerated.");
return targetDevice;
}

private static void DeviceEnumCallback(ref USB_SDK_DEVICE_INFO deviceInfo, IntPtr pUser)
{
string foundDeviceName = Encoding.ASCII.GetString(deviceInfo.szDeviceName).TrimEnd('\0');
string serialNumber = Encoding.ASCII.GetString(deviceInfo.szSerialNumber).TrimEnd('\0');

Console.WriteLine($"Device found: {foundDeviceName}, Serial number: {serialNumber}");

if (foundDeviceName == "DS-K1F100-D8E")
{
targetDevice = deviceInfo;
}
}

public static long LoginToDevice(USB_SDK_DEVICE_INFO device)
{
Console.WriteLine("Attempting to connect to the device...");

USB_SDK_USER_LOGIN_INFO loginInfo = new USB_SDK_USER_LOGIN_INFO
{
dwSize = (uint)Marshal.SizeOf(typeof(USB_SDK_USER_LOGIN_INFO)),
dwTimeout = 5000,
dwVID = device.dwVID,
dwPID = device.dwPID,
szUserName = Encoding.ASCII.GetBytes("admin".PadRight(32, '\0')),
szPassword = Encoding.ASCII.GetBytes("12345".PadRight(16, '\0')),
szSerialNumber = device.szSerialNumber,
byRes = new byte[80]
};

USB_SDK_DEVICE_REG_RES deviceInfo = new USB_SDK_DEVICE_REG_RES
{
dwSize = (uint)Marshal.SizeOf(typeof(USB_SDK_DEVICE_REG_RES)),
byRes = new byte[40]
};

long userId = USB_SDK_Login(ref loginInfo, ref deviceInfo);
if (userId == -1)
{
int errorCode = SDKManager.GetLastError();
Console.WriteLine($"Device connection error. Error code: {errorCode}");
return -1;
}

string deviceName = Encoding.ASCII.GetString(deviceInfo.szDeviceName).TrimEnd('\0');
string serialNumber = Encoding.ASCII.GetString(deviceInfo.szSerialNumber).TrimEnd('\0');

Console.WriteLine($"Successfully connected. UserID = {userId}");
Console.WriteLine($"Device name: {deviceName}");
Console.WriteLine($"Device serial number: {serialNumber}");
Console.WriteLine($"Software version: {deviceInfo.dwSoftwareVersion:X}");

return userId;
}

public static bool Logout(long userId)
{
return USB_SDK_Logout((int)userId);
}
}

//CardReader.cs
using System;
using System.Runtime.InteropServices;

public class CardReader
{
[DllImport("HCUsbSDK.dll", CharSet = CharSet.Ansi, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool USB_SDK_GetDeviceConfig(
int lUserID,
int dwCommand,
ref USB_CONFIG_INPUT_INFO lpInput,
ref USB_CONFIG_OUTPUT_INFO lpOutput);

public int UserID { get; set; }

public bool ActivateCard(int waitSeconds)
{
if (waitSeconds < 0 || waitSeconds > 255)
{
Console.WriteLine("Wait time must be between 0-255 seconds.");
return false;
}

Console.WriteLine("Starting card activation process...");

USB_SDK_WAIT_SECOND waitSecond = new USB_SDK_WAIT_SECOND
{
dwSize = (uint)Marshal.SizeOf(typeof(USB_SDK_WAIT_SECOND)),
byWait = (byte)waitSeconds,
byRes = new byte[27]
};

Console.WriteLine($"waitSecond.byWait: {waitSecond.byWait}");
Console.WriteLine($"Size of waitSecond: {waitSecond.dwSize} bytes");

USB_SDK_ACTIVATE_CARD_RES activateCardRes = new USB_SDK_ACTIVATE_CARD_RES
{
dwSize = (uint)Marshal.SizeOf(typeof(USB_SDK_ACTIVATE_CARD_RES)),
bySerial = new byte[10],
bySelectVerify = new byte[3],
byRes = new byte[12]
};

Console.WriteLine($"activateCardRes.dwSize: {activateCardRes.dwSize}");
Console.WriteLine($"activateCardRes.byCardType: {activateCardRes.byCardType}");

USB_CONFIG_INPUT_INFO inputInfo = new USB_CONFIG_INPUT_INFO
{
dwInBufferSize = (uint)Marshal.SizeOf(waitSecond),
lpInBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(waitSecond)),
byRes = new byte[48]
};
Marshal.StructureToPtr(waitSecond, inputInfo.lpInBuffer, false);

USB_CONFIG_OUTPUT_INFO outputInfo = new USB_CONFIG_OUTPUT_INFO
{
dwOutBufferSize = (uint)Marshal.SizeOf(activateCardRes),
lpOutBuffer = Marshal.AllocHGlobal(Marshal.SizeOf(activateCardRes)),
byRes = new byte[56]
};

try
{
if (inputInfo.lpInBuffer == IntPtr.Zero || outputInfo.lpOutBuffer == IntPtr.Zero)
{
Console.WriteLine("Error: Failed to allocate memory for buffers.");
return false;
}

Console.WriteLine("Sending card activation command...");

bool result = USB_SDK_GetDeviceConfig(UserID, (int)SDKManager.USB_SDK_GET_ACTIVATE_CARD, ref inputInfo, ref outputInfo);

if (!result)
{
int errorCode = SDKManager.GetLastError();
Console.WriteLine($"Card activation failed. Error code: {errorCode}");

if (errorCode == 44)
{
Console.WriteLine("Error related to structure size. Please verify the transmitted data.");
}

return false;
}

activateCardRes = Marshal.PtrToStructure(outputInfo.lpOutBuffer);

Console.WriteLine("Card activated successfully.");
Console.WriteLine($"Card type: {activateCardRes.byCardType}");

if (activateCardRes.bySerial != null && activateCardRes.bySerialLen > 0)
{
Console.WriteLine($"Serial number: {BitConverter.ToString(activateCardRes.bySerial, 0, activateCardRes.bySerialLen)}");
}

if (activateCardRes.bySelectVerify != null && activateCardRes.bySelectVerifyLen > 0)
{
Console.WriteLine($"Verification code: {BitConverter.ToString(activateCardRes.bySelectVerify, 0, activateCardRes.bySelectVerifyLen)}");
}

return true;
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex.Message}");
return false;
}
finally
{
Console.WriteLine("Releasing memory...");
if (inputInfo.lpInBuffer != IntPtr.Zero)
{
Marshal.FreeHGlobal(inputInfo.lpInBuffer);
}
if (outputInfo.lpOutBuffer != IntPtr.Zero)
{
Marshal.FreeHGlobal(outputInfo.lpOutBuffer);
}

Console.WriteLine("Card activation process finished.");
}
}
}

//ResourceManager.cs
public static class ResourceManager
{
public static void LogoutAndCleanup(long userId)
{
Console.WriteLine("Attempting to logout...");
bool logoutResult = DeviceManager.Logout(userId);
if (!logoutResult)
{
int errorCode = SDKManager.GetLastError();
Console.WriteLine($"Logout error. Error code: {errorCode}");
}
else
{
Console.WriteLine("Successful logout.");
}

if (!SDKManager.Cleanup())
{
int errorCode = SDKManager.GetLastError();
Console.WriteLine($"Resource cleanup error. Error code: {errorCode}");
}
else
{
Console.WriteLine("Resources successfully cleaned up.");
}
}
}


Пожалуйста, помогите мне разобраться...
What is not possible to implement:
activation of the card. The application sends the USB_SDK_GET_ACTIVATE_CARD command using USB_SDK_GetDeviceConfig().
This command involves sending an input buffer (USB_SDK_WAIT_SECOND) and receiving an output buffer (USB_SDK_ACTIVATE_CARD_RES).
If the card activation fails, the error code is retrieved and logged. I have an error code - 44 referring to the "External Structure size error", which indicates a possible discrepancy between the structure sizes in the SDK and the C# implementation. I tried to do everything according to the SDK documentation, but I still can't figure out the cause of the error.
Error 44 indicates a mismatch in the size of the structure passed between the C# application and the SDK. It follows from the documentation that the SDK expects the sizes of the following structures to be correct: The value of USB_SDK_WAIT_SECOND should be 32 bytes. The value of USB_SDK_ACTIVATE_CARD_RES must be 32 bytes. As soon as I did not try to do this, but I always get the error 44. Pack = 1 does not help to align the structures


Подробнее здесь: https://stackoverflow.com/questions/789 ... k-hcusbsdk
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «C#»