|
|
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 = "人脸识别系统门禁主机报警信息,dwMajor:0x" + Convert.ToString(struAcsAlarm.dwMajor, 16) + ",dwMinor:0x" +
|
|
|
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++;
|
|
|
//}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|