You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

348 lines
18 KiB
C#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using ZJ_BYD.ViewModel.FaceLogin;
namespace ZJ_BYD.Untils
{
public class FaceDeviceHelper : Singleton<FaceDeviceHelper>
{
public FaceLoginUserInfo faceLoginUserInfo { get; set; } = new FaceLoginUserInfo();
private CHCNetSDK.NET_DVR_USER_LOGIN_INFO struLoginInfo;
private CHCNetSDK.NET_DVR_DEVICEINFO_V40 DeviceInfo;
private int m_lUserID = -1;
private int m_lAlarmHandle = -1;
private CHCNetSDK.MSGCallBack_V31 m_falarmData_V31 = null;
private static List<CUserInfo> cUserInfos = new List<CUserInfo>();
DateTime dt_ProgramStart;
public void Run()
{
//初始化SDK
bool m_bInitSDK = CHCNetSDK.NET_DVR_Init();
if (m_bInitSDK == false)
{
//faceLoginUserInfo.Msg = "人脸识别系统异常NET_DVR_Init error!";
return;
}
dt_ProgramStart = DateTime.Now.AddSeconds(2);
struLoginInfo = new CHCNetSDK.NET_DVR_USER_LOGIN_INFO
{
sDeviceAddress = Encoding.Default.GetBytes(Program.DeviceIp.PadRight(129, '\0').ToCharArray()),
sUserName = Encoding.Default.GetBytes(Program.DeviceUserName.PadRight(64, '\0').ToCharArray()),
sPassword = Encoding.Default.GetBytes(Program.DevicePwd.PadRight(64, '\0').ToCharArray()),
wPort = Program.DevicePort,
bUseAsynLogin = false //是否异步登录0- 否1- 是
};
DeviceInfo = new CHCNetSDK.NET_DVR_DEVICEINFO_V40();
m_lUserID = CHCNetSDK.NET_DVR_Login_V40(ref struLoginInfo, ref DeviceInfo);
//设置透传报警信息类型
CHCNetSDK.NET_DVR_LOCAL_GENERAL_CFG struLocalCfg = new CHCNetSDK.NET_DVR_LOCAL_GENERAL_CFG
{
byAlarmJsonPictureSeparate = 1//控制JSON透传报警数据和图片是否分离0-不分离(COMM_VCA_ALARM返回)1-分离分离后走COMM_ISAPI_ALARM回调返回
};
Int32 nSize = Marshal.SizeOf(struLocalCfg);
IntPtr ptrLocalCfg = Marshal.AllocHGlobal(nSize);
Marshal.StructureToPtr(struLocalCfg, ptrLocalCfg, false);
if (!CHCNetSDK.NET_DVR_SetSDKLocalCfg(17, ptrLocalCfg)) //NET_DVR_LOCAL_CFG_TYPE_GENERAL
{
faceLoginUserInfo.Msg = "人脸识别系统异常 error:" + CHCNetSDK.NET_DVR_GetLastError();
faceLoginUserInfo.IsSuccess = false;
return;
}
Marshal.FreeHGlobal(ptrLocalCfg);
//设置报警回调函数
if (m_falarmData_V31 == null)
{
m_falarmData_V31 = new CHCNetSDK.MSGCallBack_V31(MsgCallback_V31);
}
CHCNetSDK.NET_DVR_SetDVRMessageCallBack_V31(m_falarmData_V31, IntPtr.Zero);
IntPtr ptrOutBuf = Marshal.AllocHGlobal(1024);
IntPtr ptrStatusBuffer = Marshal.AllocHGlobal(1024);
for (int i = 0; i < 1024; i++)
{
Marshal.WriteByte(ptrOutBuf, i, 0);
Marshal.WriteByte(ptrStatusBuffer, i, 0);
}
CHCNetSDK.NET_DVR_XML_CONFIG_INPUT struInput = new CHCNetSDK.NET_DVR_XML_CONFIG_INPUT();
CHCNetSDK.NET_DVR_XML_CONFIG_OUTPUT struOuput = new CHCNetSDK.NET_DVR_XML_CONFIG_OUTPUT();
string sUrl = "GET /ISAPI/AccessControl/UserInfo/Count?format=json";
IntPtr ptrURL = Marshal.StringToHGlobalAnsi(sUrl);
struInput.dwSize = (uint)Marshal.SizeOf(struInput);
struInput.lpRequestUrl = ptrURL;
struInput.dwRequestUrlLen = (uint)sUrl.Length;
struOuput.dwSize = (uint)Marshal.SizeOf(struOuput);
struOuput.lpOutBuffer = ptrOutBuf;
struOuput.dwOutBufferSize = 1024;
struOuput.lpStatusBuffer = ptrStatusBuffer;
struOuput.dwStatusSize = 1024;
IntPtr ptrInput = Marshal.AllocHGlobal(Marshal.SizeOf(struInput));
Marshal.StructureToPtr(struInput, ptrInput, false);
IntPtr ptrOuput = Marshal.AllocHGlobal(Marshal.SizeOf(struOuput));
Marshal.StructureToPtr(struOuput, ptrOuput, false);
if (!CHCNetSDK.NET_DVR_STDXMLConfig(m_lUserID, ptrInput, ptrOuput))
{
string strTemp = string.Format("Error Code={0}", CHCNetSDK.NET_DVR_GetLastError());
faceLoginUserInfo.Msg = strTemp;
faceLoginUserInfo.IsSuccess = false;
return;
}
string aa = Marshal.PtrToStringAnsi(struOuput.lpOutBuffer);
sUrl = "POST /ISAPI/AccessControl/UserInfo/Search?format=json";
ptrURL = Marshal.StringToHGlobalAnsi(sUrl);
int nRet = CHCNetSDK.NET_DVR_StartRemoteConfig(m_lUserID, CHCNetSDK.NET_DVR_JSON_CONFIG, ptrURL, sUrl.Length, null, IntPtr.Zero);
if (nRet < 0)
{
var msg = "NET_DVR_StartRemoteConfig fail [url:POST /ISAPI/AccessControl/UserInfo/Search?format=json] error:" + CHCNetSDK.NET_DVR_GetLastError();
faceLoginUserInfo.Msg = msg;
faceLoginUserInfo.IsSuccess = false;
return;
}
CUserInfoSearchCondCfg JsonUserInfoSearchCondCfg = new CUserInfoSearchCondCfg
{
UserInfoSearchCond = new CUserInfoSearchCond()
};
JsonUserInfoSearchCondCfg.UserInfoSearchCond.searchID = "1";
JsonUserInfoSearchCondCfg.UserInfoSearchCond.searchResultPosition = 0;
JsonUserInfoSearchCondCfg.UserInfoSearchCond.maxResults = 30;
string strUserInfoSearchCondCfg = JsonConvert.SerializeObject(JsonUserInfoSearchCondCfg);
IntPtr ptrUserInfoSearchCondCfg = Marshal.StringToHGlobalAnsi(strUserInfoSearchCondCfg);
IntPtr ptrJsonData = Marshal.AllocHGlobal(4096);
for (int i = 0; i < 4096; i++)
{
Marshal.WriteByte(ptrJsonData, i, 0);
}
int dwState = (int)CHCNetSDK.NET_SDK_SENDWITHRECV_STATUS.NET_SDK_CONFIG_STATUS_SUCCESS;
uint dwReturned = 0;
while (true)
{
dwState = CHCNetSDK.NET_DVR_SendWithRecvRemoteConfig(m_lUserID, ptrUserInfoSearchCondCfg, (uint)strUserInfoSearchCondCfg.Length, ptrJsonData, 4096, ref dwReturned);
if (dwState == (int)CHCNetSDK.NET_SDK_SENDWITHRECV_STATUS.NET_SDK_CONFIG_STATUS_NEEDWAIT)
{
Thread.Sleep(10);
continue;
}
else if (dwState == (int)CHCNetSDK.NET_SDK_SENDWITHRECV_STATUS.NET_SDK_CONFIG_STATUS_FAILED)
{
faceLoginUserInfo.Msg = $"获取用户失败:{CHCNetSDK.NET_DVR_GetLastError()}";
faceLoginUserInfo.IsSuccess = false;
continue;
}
else if (dwState == (int)CHCNetSDK.NET_SDK_SENDWITHRECV_STATUS.NET_SDK_CONFIG_STATUS_SUCCESS)
{
byte[] bUserInfoSearch = new byte[1024 * 10];
Marshal.Copy(ptrJsonData, bUserInfoSearch, 0, (int)dwReturned);
string strUserInfoSearch = Encoding.UTF8.GetString(bUserInfoSearch);
CUserInfoSearchCfg JsonUserInfoSearchCfg = new CUserInfoSearchCfg();
JsonUserInfoSearchCfg = JsonConvert.DeserializeObject<CUserInfoSearchCfg>(strUserInfoSearch);
if (JsonUserInfoSearchCfg.UserInfoSearch == null)
{
//null说明返回的Json报文不是UserInfoSearch而是ResponseStatus
CResponseStatus JsonResponseStatus = new CResponseStatus();
JsonResponseStatus = JsonConvert.DeserializeObject<CResponseStatus>(strUserInfoSearch);
if (JsonResponseStatus.statusCode == 1)
{
faceLoginUserInfo.Msg = $"获取用户成功:{CHCNetSDK.NET_DVR_GetLastError()}";
}
else
{
faceLoginUserInfo.Msg = $"获取用户失败,状态码={JsonResponseStatus.statusCode}!";
faceLoginUserInfo.IsSuccess = false;
continue;
}
}
else
{
//解析UserInfoSearch报文
if (JsonUserInfoSearchCfg.UserInfoSearch.totalMatches == 0)
{
faceLoginUserInfo.Msg = "没有该人员信息";
faceLoginUserInfo.IsSuccess = false;
continue;
}
cUserInfos = JsonUserInfoSearchCfg.UserInfoSearch.UserInfo;
}
break;
}
else if (dwState == (int)CHCNetSDK.NET_SDK_SENDWITHRECV_STATUS.NET_SDK_CONFIG_STATUS_FINISH)
{
faceLoginUserInfo.Msg = "Get User Finish";
break;
}
else if (dwState == (int)CHCNetSDK.NET_SDK_SENDWITHRECV_STATUS.NET_SDK_CONFIG_STATUS_EXCEPTION)
{
faceLoginUserInfo.Msg = $"人脸识别系统异常:{CHCNetSDK.NET_DVR_GetLastError()}!";
faceLoginUserInfo.IsSuccess = false;
continue;
}
else
{
faceLoginUserInfo.Msg = $"人脸识别系统异常unknown status error{CHCNetSDK.NET_DVR_GetLastError()}!";
faceLoginUserInfo.IsSuccess = false;
continue;
}
}
Marshal.FreeHGlobal(ptrUserInfoSearchCondCfg);
Marshal.FreeHGlobal(ptrJsonData);
if (m_lUserID != -1)
{
CHCNetSDK.NET_DVR_StopRemoteConfig(m_lUserID);
}
Marshal.FreeHGlobal(ptrOutBuf);
Marshal.FreeHGlobal(ptrStatusBuffer);
Marshal.FreeHGlobal(ptrInput);
Marshal.FreeHGlobal(ptrOuput);
Marshal.FreeHGlobal(ptrURL);
CHCNetSDK.NET_DVR_SETUPALARM_PARAM struAlarmParam = new CHCNetSDK.NET_DVR_SETUPALARM_PARAM();
struAlarmParam.dwSize = (uint)Marshal.SizeOf(struAlarmParam);
struAlarmParam.byLevel = 1; //0- 一级布防,1- 二级布防
struAlarmParam.byAlarmInfoType = 1;//智能交通设备有效,新报警信息类型
struAlarmParam.byFaceAlarmDetection = 1;//1-人脸侦测
m_lAlarmHandle = CHCNetSDK.NET_DVR_SetupAlarmChan_V41(m_lUserID, ref struAlarmParam);
if (m_lAlarmHandle < 0)
{
LogHelper.WriteLog($"人脸识别系统异常,布防失败:{CHCNetSDK.NET_DVR_GetLastError()}!");//布防失败,输出错误号
faceLoginUserInfo.IsSuccess = false;
}
}
private bool MsgCallback_V31(int lCommand, ref CHCNetSDK.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser)
{
//通过lCommand来判断接收到的报警信息类型不同的lCommand对应不同的pAlarmInfo内容
AlarmMessageHandle(lCommand, ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
return true; //回调函数需要有返回,表示正常接收到数据
}
private void AlarmMessageHandle(int lCommand, ref CHCNetSDK.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser)
{
//通过lCommand来判断接收到的报警信息类型不同的lCommand对应不同的pAlarmInfo内容
switch (lCommand)
{
case CHCNetSDK.COMM_ALARM_ACS://门禁主机报警上传
ProcessCommAlarm_AcsAlarm(ref pAlarmer, pAlarmInfo, dwBufLen, pUser);
break;
default:
{
//报警设备IP地址
_ = Encoding.UTF8.GetString(pAlarmer.sDeviceIP).TrimEnd('\0');
//报警信息类型
string stringAlarm = "人脸识别系统报警上传信息类型0x" + Convert.ToString(lCommand, 16);
LogHelper.WriteLog(stringAlarm);
}
break;
}
}
private void ProcessCommAlarm_AcsAlarm(ref CHCNetSDK.NET_DVR_ALARMER pAlarmer, IntPtr pAlarmInfo, uint dwBufLen, IntPtr pUser)
{
CHCNetSDK.NET_DVR_ACS_ALARM_INFO struAcsAlarm = new CHCNetSDK.NET_DVR_ACS_ALARM_INFO();
uint dwSize = (uint)Marshal.SizeOf(struAcsAlarm);
struAcsAlarm = (CHCNetSDK.NET_DVR_ACS_ALARM_INFO)Marshal.PtrToStructure(pAlarmInfo, typeof(CHCNetSDK.NET_DVR_ACS_ALARM_INFO));
//报警设备IP地址
string strIP = Encoding.UTF8.GetString(pAlarmer.sDeviceIP).TrimEnd('\0');
#region 保存抓拍图片
//if ((struAcsAlarm.dwPicDataLen != 0) && (struAcsAlarm.pPicData != IntPtr.Zero))
//{
// string str = ".\\picture\\Device_Acs_CapturePic_[" + strIP + "]_lUerID_[" + pAlarmer.lUserID + "]_" + iFileNumber + ".jpg";
// FileStream fs = new FileStream(str, FileMode.Create);
// int iLen = (int)struAcsAlarm.dwPicDataLen;
// byte[] by = new byte[iLen];
// Marshal.Copy(struAcsAlarm.pPicData, by, 0, iLen);
// fs.Write(by, 0, iLen);
// fs.Close();
// iFileNumber++;
//}
#endregion
//报警时间:年月日时分秒
string strTimeYear = (struAcsAlarm.struTime.dwYear).ToString();
string strTimeMonth = (struAcsAlarm.struTime.dwMonth).ToString("d2");
string strTimeDay = (struAcsAlarm.struTime.dwDay).ToString("d2");
string strTimeHour = (struAcsAlarm.struTime.dwHour).ToString("d2");
string strTimeMinute = (struAcsAlarm.struTime.dwMinute).ToString("d2");
string strTimeSecond = (struAcsAlarm.struTime.dwSecond).ToString("d2");
string strTime = strTimeYear + "-" + strTimeMonth + "-" + strTimeDay + " " + strTimeHour + ":" + strTimeMinute + ":" + strTimeSecond;
string stringAlarm = "人脸识别系统门禁主机报警信息dwMajor0x" + Convert.ToString(struAcsAlarm.dwMajor, 16) + "dwMinor0x" +
Convert.ToString(struAcsAlarm.dwMinor, 16) + ",卡号:" + Encoding.UTF8.GetString(struAcsAlarm.struAcsEventInfo.byCardNo).TrimEnd('\0')
+ ",读卡器编号:" + struAcsAlarm.struAcsEventInfo.dwCardReaderNo + ",报警触发时间:" + strTime +
",事件流水号:" + struAcsAlarm.struAcsEventInfo.dwSerialNo;
if (struAcsAlarm.byAcsEventInfoExtend == 1)
{
CHCNetSDK.NET_DVR_ACS_EVENT_INFO_EXTEND struInfoExtend = new CHCNetSDK.NET_DVR_ACS_EVENT_INFO_EXTEND();
uint dwSizeEx = (uint)Marshal.SizeOf(struInfoExtend);
struInfoExtend = (CHCNetSDK.NET_DVR_ACS_EVENT_INFO_EXTEND)Marshal.PtrToStructure(struAcsAlarm.pAcsEventInfoExtend, typeof(CHCNetSDK.NET_DVR_ACS_EVENT_INFO_EXTEND));
stringAlarm = stringAlarm + ", 工号:" + Encoding.UTF8.GetString(struInfoExtend.byEmployeeNo).TrimEnd('\0') +
", 人员类型:" + struInfoExtend.byUserType;
string ID = Encoding.UTF8.GetString(struInfoExtend.byEmployeeNo).TrimEnd('\0');
if (ID.Length > 0)
{
CUserInfo info = cUserInfos.Find(c => c.employeeNo == ID);
TimeSpan ts = DateTime.Now - dt_ProgramStart;
if (info != null && ts.TotalSeconds > 1 && !faceLoginUserInfo.IsLogin)
{
faceLoginUserInfo.employeeNo = info.employeeNo;
faceLoginUserInfo.name = info.name;
faceLoginUserInfo.password = info.password;
faceLoginUserInfo.IsSuccess = true;
}
}
}
if (struAcsAlarm.byAcsEventInfoExtendV20 == 1)
{
CHCNetSDK.NET_DVR_ACS_EVENT_INFO_EXTEND_V20 struInfoExtendV20 = new CHCNetSDK.NET_DVR_ACS_EVENT_INFO_EXTEND_V20();
uint dwSizeEx = (uint)Marshal.SizeOf(struInfoExtendV20);
struInfoExtendV20 = (CHCNetSDK.NET_DVR_ACS_EVENT_INFO_EXTEND_V20)Marshal.PtrToStructure(struAcsAlarm.pAcsEventInfoExtendV20, typeof(CHCNetSDK.NET_DVR_ACS_EVENT_INFO_EXTEND_V20));
stringAlarm = stringAlarm + ", 温度:" + struInfoExtendV20.fCurrTemperature + ", 是否异常温度:" + struInfoExtendV20.byIsAbnomalTemperature
+ ", 是否需要核验:" + struInfoExtendV20.byRemoteCheck;
if (struInfoExtendV20.byRemoteCheck == 2)
{
//建议另外建线程或者使用消息队列进行处理和下发核验结果给设备,避免阻塞回调
//ACS_remoteCheck(struAcsAlarm.struAcsEventInfo.dwSerialNo);
}
////保存热成像图片
//if ((struInfoExtendV20.dwThermalDataLen != 0) && (struInfoExtendV20.pThermalData != IntPtr.Zero))
//{
// string str = ".\\picture\\Device_Acs_ThermalData_[" + strIP + "]_lUerID_[" + pAlarmer.lUserID + "]_" + iFileNumber + ".jpg";
// FileStream fs = new FileStream(str, FileMode.Create);
// int iLen = (int)struInfoExtendV20.dwThermalDataLen;
// byte[] by = new byte[iLen];
// Marshal.Copy(struInfoExtendV20.pThermalData, by, 0, iLen);
// fs.Write(by, 0, iLen);
// fs.Close();
// iFileNumber++;
//}
}
}
}
}