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#

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++;
//}
}
}
}
}