hikvision-sync-service/AcsAttendanceParser.cs

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";
}
}