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 { 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 cUserInfos = new List(); 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(strUserInfoSearch); if (JsonUserInfoSearchCfg.UserInfoSearch == null) { //null说明返回的Json报文不是UserInfoSearch,而是ResponseStatus CResponseStatus JsonResponseStatus = new CResponseStatus(); JsonResponseStatus = JsonConvert.DeserializeObject(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++; //} } } } }