176 lines
6.2 KiB
C#
176 lines
6.2 KiB
C#
using System;
|
|
using CHCNetSDK = EventByDeploy.CHCNetSDK;
|
|
|
|
namespace HikvisionAttendanceService;
|
|
|
|
/// <summary>
|
|
/// ACS-specific parsing helpers (major/minor codes from HCNetSDK).
|
|
/// </summary>
|
|
internal static class AcsAttendanceParser
|
|
{
|
|
public static string MapMajorCategory(uint dwMajor)
|
|
{
|
|
if (dwMajor == CHCNetSDK.MAJOR_ALARM) return "Alarm";
|
|
if (dwMajor == CHCNetSDK.MAJOR_EXCEPTION) return "Exception";
|
|
if (dwMajor == CHCNetSDK.MAJOR_OPERATION) return "Operation";
|
|
if (dwMajor == CHCNetSDK.MAJOR_EVENT) return "Event";
|
|
return "Unknown";
|
|
}
|
|
|
|
public static bool TryInferSuccessFromMinor(uint dwMajor, uint dwMinor, out bool isSuccess)
|
|
{
|
|
isSuccess = false;
|
|
if (dwMajor != CHCNetSDK.MAJOR_EVENT)
|
|
return false;
|
|
|
|
// Verification / access style minors: *_PASS / *_FAIL / *_TIMEOUT patterns in SDK.
|
|
if (IsPassMinor(dwMinor))
|
|
{
|
|
isSuccess = true;
|
|
return true;
|
|
}
|
|
|
|
if (IsFailOrTimeoutMinor(dwMinor))
|
|
{
|
|
isSuccess = false;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static bool ResolveIsSuccess(uint dwMajor, uint dwMinor, string? eventName)
|
|
{
|
|
if (TryInferSuccessFromMinor(dwMajor, dwMinor, out var ok))
|
|
return ok;
|
|
return GuessSuccessFromEventName(eventName);
|
|
}
|
|
|
|
private static bool GuessSuccessFromEventName(string? eventName)
|
|
{
|
|
if (eventName == null)
|
|
return false;
|
|
|
|
if (eventName.IndexOf("FAIL", StringComparison.OrdinalIgnoreCase) >= 0 ||
|
|
eventName.IndexOf("TIMEOUT", StringComparison.OrdinalIgnoreCase) >= 0 ||
|
|
eventName.IndexOf("INEXISTENCE", StringComparison.OrdinalIgnoreCase) >= 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (eventName.IndexOf("PASS", StringComparison.OrdinalIgnoreCase) >= 0 ||
|
|
eventName.IndexOf("SUCCESS", StringComparison.OrdinalIgnoreCase) >= 0 ||
|
|
eventName.IndexOf("OPEN", StringComparison.OrdinalIgnoreCase) >= 0)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
private static bool IsPassMinor(uint m)
|
|
{
|
|
return m == CHCNetSDK.MINOR_LEGAL_CARD_PASS
|
|
|| m == CHCNetSDK.MINOR_FACE_VERIFY_PASS
|
|
|| m == CHCNetSDK.MINOR_FINGERPRINT_COMPARE_PASS
|
|
|| m == CHCNetSDK.MINOR_CARD_AND_PSW_PASS
|
|
|| m == CHCNetSDK.MINOR_CARD_FINGERPRINT_VERIFY_PASS
|
|
|| m == CHCNetSDK.MINOR_CARD_FINGERPRINT_PASSWD_VERIFY_PASS
|
|
|| m == CHCNetSDK.MINOR_FINGERPRINT_PASSWD_VERIFY_PASS
|
|
|| m == CHCNetSDK.MINOR_FACE_AND_FP_VERIFY_PASS
|
|
|| m == CHCNetSDK.MINOR_FACE_AND_PW_VERIFY_PASS
|
|
|| m == CHCNetSDK.MINOR_FACE_AND_CARD_VERIFY_PASS
|
|
|| m == CHCNetSDK.MINOR_FACE_AND_PW_AND_FP_VERIFY_PASS
|
|
|| m == CHCNetSDK.MINOR_FACE_CARD_AND_FP_VERIFY_PASS
|
|
|| m == CHCNetSDK.MINOR_EMPLOYEENO_AND_FP_VERIFY_PASS
|
|
|| m == CHCNetSDK.MINOR_EMPLOYEENO_AND_FP_AND_PW_VERIFY_PASS
|
|
|| m == CHCNetSDK.MINOR_EMPLOYEENO_AND_FACE_VERIFY_PASS
|
|
|| m == CHCNetSDK.MINOR_COMBINED_VERIFY_PASS;
|
|
}
|
|
|
|
private static bool IsFailOrTimeoutMinor(uint m)
|
|
{
|
|
return m == CHCNetSDK.MINOR_FINGERPRINT_COMPARE_FAIL
|
|
|| m == CHCNetSDK.MINOR_CARD_FINGERPRINT_VERIFY_FAIL
|
|
|| m == CHCNetSDK.MINOR_CARD_FINGERPRINT_VERIFY_TIMEOUT
|
|
|| m == CHCNetSDK.MINOR_FACE_AND_FP_VERIFY_FAIL
|
|
|| m == CHCNetSDK.MINOR_FACE_AND_FP_VERIFY_TIMEOUT
|
|
|| m == CHCNetSDK.MINOR_FACE_VERIFY_FAIL
|
|
|| m == CHCNetSDK.MINOR_FACE_AND_PW_VERIFY_FAIL
|
|
|| m == CHCNetSDK.MINOR_FACE_AND_CARD_VERIFY_FAIL
|
|
|| m == CHCNetSDK.MINOR_FINGERPRINT_INEXISTENCE;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Maps SDK verify mode / card reader kind to a coarse attendance method.
|
|
/// </summary>
|
|
public static string InferMethodFromAcsDetail(
|
|
uint dwMinor,
|
|
byte byCardReaderKind,
|
|
byte byCurrentVerifyMode,
|
|
string eventNameFallback)
|
|
{
|
|
// Prefer explicit minor-driven inference for MAJOR_EVENT.
|
|
string fromMinor = MapMethodFromMinor(dwMinor);
|
|
if (!string.IsNullOrEmpty(fromMinor))
|
|
return fromMinor;
|
|
|
|
// byCardReaderKind: 1 IC, 2 ID, 3 QR, 4 fingerprint head (per SDK comments).
|
|
switch (byCardReaderKind)
|
|
{
|
|
case 4:
|
|
return "Fingerprint";
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
return "Card";
|
|
}
|
|
|
|
// Common verify modes (device-dependent; 0 = unknown).
|
|
switch (byCurrentVerifyMode)
|
|
{
|
|
case 2:
|
|
return "Fingerprint";
|
|
case 3:
|
|
case 4:
|
|
return "Face";
|
|
case 1:
|
|
return "Card";
|
|
}
|
|
|
|
return GuessMethodFromEventName(eventNameFallback);
|
|
}
|
|
|
|
private static string MapMethodFromMinor(uint m)
|
|
{
|
|
if (m == CHCNetSDK.MINOR_FACE_VERIFY_PASS || m == CHCNetSDK.MINOR_FACE_VERIFY_FAIL)
|
|
return "Face";
|
|
if (m == CHCNetSDK.MINOR_FINGERPRINT_COMPARE_PASS || m == CHCNetSDK.MINOR_FINGERPRINT_COMPARE_FAIL)
|
|
return "Fingerprint";
|
|
if (m == CHCNetSDK.MINOR_CARD_AND_PSW_PASS)
|
|
return "Card+Password";
|
|
if (m == CHCNetSDK.MINOR_FACE_AND_FP_VERIFY_PASS || m == CHCNetSDK.MINOR_FACE_AND_FP_VERIFY_FAIL)
|
|
return "Face+Fingerprint";
|
|
if (m == CHCNetSDK.MINOR_FACE_AND_CARD_VERIFY_PASS || m == CHCNetSDK.MINOR_FACE_AND_CARD_VERIFY_FAIL)
|
|
return "Face+Card";
|
|
return "";
|
|
}
|
|
|
|
private static string GuessMethodFromEventName(string? eventName)
|
|
{
|
|
if (string.IsNullOrEmpty(eventName))
|
|
return "Unknown";
|
|
|
|
string n = eventName.ToUpperInvariant();
|
|
if (n.Contains("FACE") && n.Contains("FP"))
|
|
return "Face+Fingerprint";
|
|
if (n.Contains("FACE"))
|
|
return "Face";
|
|
if (n.Contains("FINGERPRINT") || n.Contains("FINGE_RPRINT") || n.Contains("FINGER_PRINT") || n.Contains(" FP"))
|
|
return "Fingerprint";
|
|
if (n.Contains("CARD"))
|
|
return "Card";
|
|
return "Unknown";
|
|
}
|
|
}
|