package com.netsdk.demo.accessControl; import com.netsdk.demo.customize.PrintStruct; import com.netsdk.demo.customize.healthCodeEx.callback.RegisterServiceCallBack; import com.netsdk.demo.customize.healthCodeEx.entity.DeviceInfo; import com.netsdk.demo.customize.healthCodeEx.entity.ListenInfo; import com.netsdk.demo.customize.healthCodeEx.module.AutoRegisterModule; import com.netsdk.demo.customize.healthCodeEx.module.LoginModule; import com.netsdk.demo.util.Base64Util; import com.netsdk.demo.util.CaseMenu; import com.netsdk.lib.NetSDKLib; import com.netsdk.lib.NetSDKLib.*; import com.netsdk.lib.ToolKits; import com.netsdk.lib.enumeration.ENUMERROR; import com.netsdk.lib.structure.BYTE_32; import com.netsdk.lib.structure.NET_DEV_EVENT_USERMANAGER_FOR_TWSDK_INFO; import com.netsdk.lib.structure.NET_TIME_EX; import com.netsdk.lib.structure.NET_USERMANAGER_IMAGE_INFO; import com.sun.jna.Memory; import com.sun.jna.NativeLong; import com.sun.jna.Pointer; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.*; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import java.util.Map; import java.util.Scanner; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import static com.netsdk.lib.Utils.getOsPrefix; public class AccessNew { static NetSDKLib netsdkApi = NetSDKLib.NETSDK_INSTANCE; // 设备信息 private static String m_strIp = "172.5.99.171";//172.5.111.16 172.10.6.187 private static int m_nPort = 37777; private static String m_strUser = "admin"; private static String m_strPassword = "admin123"; // 接口调用超时时间 private static final int TIME_OUT = 6 * 1000; private static NetSDKLib.NET_DEVICEINFO_Ex deviceinfo = new NetSDKLib.NET_DEVICEINFO_Ex(); private static LLong loginHandle = new LLong(0); // 登陆句柄 private static LLong m_hAttachHandle = new LLong(0); // 订阅句柄 // 设备断线回调: 通过 CLIENT_Init 设置该回调函数,当设备出现断线时,SDK会调用该函数 public class fDisConnectCB implements NetSDKLib.fDisConnect { public void invoke(LLong lLoginID, String pchDVRIP, int nDVRPort, Pointer dwUser) { System.out.printf("Device[%s] Port[%d] Disconnect!\n", pchDVRIP, nDVRPort); } } // 网络连接恢复,设备重连成功回调 // 通过 CLIENT_SetAutoReconnect 设置该回调函数,当已断线的设备重连成功时,SDK会调用该函数 public class HaveReConnect implements NetSDKLib.fHaveReConnect { public void invoke(LLong loginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) { System.out.printf("ReConnect Device[%s] Port[%d]\n", pchDVRIP, nDVRPort); } } private fDisConnectCB m_DisConnectCB = new fDisConnectCB(); private HaveReConnect haveReConnect = new HaveReConnect(); // 用户存储注册上来的设备信息的缓存 Map 项目中请替换成其他中间件 private final Map deviceInfoMap = new ConcurrentHashMap<>(); // 主动注册监听句柄 private NetSDKLib.LLong m_hListenHandle = new NetSDKLib.LLong(0); /////////////// 注册地址(服务器 这里是运行此Demo的电脑IP) 监听端口 ////////////////////// private final String serverIpAddr = "10.33.121.53"; private final int serverPort = 9500; // 注意不要和其他程序发生冲突 private String username = "admin"; private String password = "admin321"; /** * 主动注册 */ public void autoRegisterLogin() { // 开启监听 serverStartListen(); // 登录设备 Scanner sc = new Scanner(System.in); System.out.println("请输入设备的注册 Serial:"); String key = sc.nextLine().trim(); DeviceInfo deviceInfo = deviceInfoMap.get(key); if (deviceInfo == null) { System.out.println("注册上报的设备中没有该 Serial"); return; } // 注册设备的IP String ipAddr = deviceInfo.ipAddress; // 注册设备的端口 int port = deviceInfo.port; // 账号 String username = this.username; // 密码 String password = this.password; loginHandle = LoginModule.AutoRegisterLoginWithHighSecurity(key, ipAddr, port, username, password, deviceInfo.m_stDeviceInfo); if (loginHandle.longValue() == 0) { System.err.println("主动注册登录失败:" + ENUMERROR.getErrorMessage()); return; } loginHandle.setValue(loginHandle.longValue()); // 清除此注册信息 请等待重新上报后再重新登录 deviceInfoMap.remove(key); } private volatile Boolean taskIsOpen = false; /** * 开启监听 */ public void serverStartListen() { m_hListenHandle = AutoRegisterModule.ServerStartListen(serverIpAddr, serverPort, RegisterServiceCallBack.getInstance()); if (m_hListenHandle.longValue() == 0) return; taskIsOpen = true; new Thread(this::eventListTask).start(); } // 获取监听回调数据并放入缓存 public void eventListTask() { while (taskIsOpen) { try { // 稍微延迟一下,避免循环的太快 Thread.sleep(10); // 阻塞获取 ListenInfo listenInfo = RegisterServiceCallBack.ServerInfoQueue.poll(50, TimeUnit.MILLISECONDS); if (listenInfo == null) continue; // 结果放入缓存 if (!deviceInfoMap.containsKey(listenInfo.devSerial)) { deviceInfoMap.put(listenInfo.devSerial, new DeviceInfo(listenInfo.devIpAddress, listenInfo.devPort)); System.out.println("...有新设备上报注册信息... Serial:" + listenInfo.devSerial); } } catch (InterruptedException e) { e.printStackTrace(); } } } public void InitTest() { // 初始化SDK库,必须调用 netsdkApi.CLIENT_Init(m_DisConnectCB, null); // 设置断线重连回调接口,设置过断线重连成功回调函数后,当设备出现断线情况,SDK内部会自动进行重连操作 // 此操作为可选操作,但建议用户进行设置 netsdkApi.CLIENT_SetAutoReconnect(haveReConnect, null); // 设置登录超时时间和尝试次数,可选 int waitTime = 5000; // 登录请求响应超时时间设置为5S int tryTimes = 3; // 登录时尝试建立链接3次 netsdkApi.CLIENT_SetConnectTime(waitTime, tryTimes); // 设置更多网络参数,NET_PARAM的nWaittime,nConnectTryNum成员与CLIENT_SetConnectTime // 接口设置的登录设备超时时间和尝试次数意义相同,可选 NetSDKLib.NET_PARAM netParam = new NetSDKLib.NET_PARAM(); netParam.nConnectTime = 10000; // 登录时尝试建立链接的超时时间 netsdkApi.CLIENT_SetNetworkParam(netParam); // 打开日志,可选 NetSDKLib.LOG_SET_PRINT_INFO setLog = new NetSDKLib.LOG_SET_PRINT_INFO(); File path = new File("./sdklog/"); if (!path.exists()) { path.mkdir(); } String logPath = path.getAbsoluteFile().getParent() + "/sdklog/sdklog.log"; System.out.println(logPath); setLog.bSetFilePath = 1; System.arraycopy(logPath.getBytes(), 0, setLog.szLogFilePath, 0, logPath.getBytes().length); setLog.bSetPrintStrategy = 1; setLog.nPrintStrategy = 0; boolean bLogopen = netsdkApi.CLIENT_LogOpen(setLog); if (!bLogopen) { System.err.println("Failed to open NetSDK log !!!"); } deviceLogin(); } /** * 登录设备 两种登录方式 TCP登录 主动注册 */ public void deviceLogin() { Scanner sc = new Scanner(System.in); System.out.println("请输入登录方式 1 TCP登录 2 主动注册:"); String key = sc.nextLine().trim(); if ("1".equals(key)) { tcpLogin(); } else if ("2".equals(key)) { autoRegisterLogin(); } else { System.out.println("输入信息错误..."); } } // 登录 高安全 TCP public static NetSDKLib.LLong tcpLogin() { System.out.println("设备地址:" + m_strIp+ "\n端口号:" + m_nPort + "\n用户名:" + m_strUser + "\n密码:" + m_strPassword); NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY pstInParam = new NetSDKLib.NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY(); // 输入结构体参数 System.arraycopy(m_strIp.getBytes(), 0, pstInParam.szIP, 0, m_strIp.length()); pstInParam.nPort = m_nPort; System.arraycopy(m_strUser.getBytes(), 0, pstInParam.szUserName, 0, m_strUser.length()); System.arraycopy(m_strPassword.getBytes(), 0, pstInParam.szPassword, 0, m_strPassword.length()); pstInParam.emSpecCap = NetSDKLib.EM_LOGIN_SPAC_CAP_TYPE.EM_LOGIN_SPEC_CAP_TCP; NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY pstOutParam = new NetSDKLib.NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY(); // 输出结构体参数 pstOutParam.stuDeviceInfo = deviceinfo; // 设备信息 登陆成功后会刷新这个实例 loginHandle = netsdkApi.CLIENT_LoginWithHighLevelSecurity(pstInParam, pstOutParam); if (loginHandle.longValue() == 0) { System.err.printf("Login Device[%s] Port[%d]Failed. Last Error[%s]\n", m_strIp, m_nPort, ENUMERROR.getErrorMessage()); EndTest(); } else { System.out.println("Login Success [ " + m_strIp + " ]"); } return loginHandle; } public static void EndTest() { System.out.println("End Test"); if (loginHandle.longValue() != 0) { netsdkApi.CLIENT_Logout(loginHandle); } System.out.println("See You..."); // 工程关闭时,释放SDK资源 netsdkApi.CLIENT_Cleanup(); System.exit(0); } // 获取当前时间 public String getDate() { SimpleDateFormat simpleDate = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss"); String date = simpleDate.format(new java.util.Date()).replace(" ", "_") .replace(":", "-"); return date; } /** * 获取接口错误码 * * @return */ public static String getErrorCode() { return " { error code: ( 0x80000000|" + (netsdkApi.CLIENT_GetLastError() & 0x7fffffff) + " ). 参考 NetSDKLib.java }"; } /************************************************************************************************ * 获取或推送比对成功及失败记录(包括比对照片, 这个是通过触发事件,接收信息 ************************************************************************************************/ /** * 订阅 */ public void realLoadPicture() { int bNeedPicture = 1; // 是否需要图片 int ChannelId = 0; // -1代表全通道 m_hAttachHandle = netsdkApi.CLIENT_RealLoadPictureEx(loginHandle, ChannelId, NetSDKLib.EVENT_IVS_ALL, bNeedPicture, fAnalyzerDataCB.getInstance(), null, null); if (m_hAttachHandle.longValue() != 0) { System.out.println("智能订阅成功."); } else { System.err.println("智能订阅失败." + getErrorCode()); return; } } /** * 取消订阅 * */ public void stopRealLoadPicture() { if (0 != m_hAttachHandle.longValue()) { netsdkApi.CLIENT_StopLoadPic(m_hAttachHandle); m_hAttachHandle.setValue(0); System.out.println("停止智能订阅."); } } static int count=0; /** * 智能报警事件回调 */ public static class fAnalyzerDataCB implements NetSDKLib.fAnalyzerDataCallBack { private fAnalyzerDataCB() { } private static class fAnalyzerDataCBHolder { private static final fAnalyzerDataCB instance = new fAnalyzerDataCB(); } public static fAnalyzerDataCB getInstance() { return fAnalyzerDataCBHolder.instance; } @Override public int invoke(LLong lAnalyzerHandle, int dwAlarmType, Pointer pAlarmInfo, Pointer pBuffer, int dwBufSize, Pointer dwUser, int nSequence, Pointer reserved) { System.out.println("dwAlarmType:" + dwAlarmType); File path = new File("./AccessPicture/"); if (!path.exists()) { path.mkdir(); } switch (dwAlarmType) { case NetSDKLib.EVENT_IVS_ACCESS_CTL: // /< 门禁事件 { DEV_EVENT_ACCESS_CTL_INFO msg = new DEV_EVENT_ACCESS_CTL_INFO(); ToolKits.GetPointerData(pAlarmInfo, msg); System.out.println("事件名称 :" + new String(msg.szName).trim()); if (msg.emEventType == 1) { System.out.println("门禁事件类型 : 进门!"); } else if (msg.emEventType == 2) { System.out.println("门禁事件类型 : 出门!"); } if (msg.bStatus == 1) { System.out.println("刷卡结果 : 成功!"); } else if (msg.bStatus == 0) { System.out.println("刷卡结果 : 失败!"); } System.out.println("卡类型:" + msg.emCardType); System.out.println("开门方式:" + msg.emOpenMethod); System.out.println("卡号 :" + new String(msg.szCardNo).trim()); System.out.println("开门用户 :" + new String(msg.szUserID).trim()); System.out.println("开门失败原因错误码:" + msg.nErrorCode); System.out.println("考勤状态:" + msg.emAttendanceState); System.out.println("卡命名 :" + new String(msg.szCardName).trim()); System.out.println("相似度:" + msg.uSimilarity); System.out.println("证件号:" + new String(msg.szCitizenIDNo).trim()); System.out.println("当前事件是否为采集卡片:" + msg.emCardState); System.out.println("szSN:" + new String(msg.szSN).trim()); String facePicPath = ""; for (int i = 0; i < msg.nImageInfoCount; i++) { facePicPath = path + "\\" + System.currentTimeMillis() + "人脸图.jpg"; // 保存图片地址 byte[] faceBuf = pBuffer.getByteArray( msg.stuImageInfo[i].nOffSet, msg.stuImageInfo[i].nLength); ByteArrayInputStream byteArrInputFace = new ByteArrayInputStream( faceBuf); try { BufferedImage bufferedImage = ImageIO .read(byteArrInputFace); if (bufferedImage != null) { ImageIO.write(bufferedImage, "jpg", new File( facePicPath)); System.out.println("人脸图保存路径:" + facePicPath); } } catch (IOException e2) { e2.printStackTrace(); } } break; } case NetSDKLib.EVENT_IVS_FACEDETECT: { // 目标检测事件 DEV_EVENT_FACEDETECT_INFO msg = new DEV_EVENT_FACEDETECT_INFO(); ToolKits.GetPointerData(pAlarmInfo, msg); Calendar cal = Calendar.getInstance(); count++; System.out.println("count:"+count); Date date1 = cal.getTime(); System.out.println("start:"+new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss:SSS").format(date1)); break; //System.out.println("人的运动速度 :" + msg.stuObject.Speed); } case NetSDKLib.EVENT_IVS_USERMANAGER_FOR_TWSDK:{ // 用户信息上报事件(对应 NET_DEV_EVENT_USERMANAGER_FOR_TWSDK_INFO) System.out.println("用户信息上报事件" ); NET_DEV_EVENT_USERMANAGER_FOR_TWSDK_INFO msg=new NET_DEV_EVENT_USERMANAGER_FOR_TWSDK_INFO(); ToolKits.GetPointerData(pAlarmInfo, msg); NET_TIME_EX stuUTC = msg.stuUTC; System.out.println("事件发生的时间:"+stuUTC.toStringTime()); byte[] szUserID = msg.szUserID; byte[] szUserName = msg.szUserName; try { System.out.println("用户ID:"+new String(szUserID,encode)); System.out.println("用户名:"+new String(szUserName,encode)); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } int nType = msg.nType; /** * 消息类型 0: 未知 1: 人员新增消息 2: 人员修改消息 3:人员删除消息(删除时仅UserID有效) */ System.out.println("消息类型:"+nType); int nCardListNum = msg.nCardListNum; System.out.println("卡片数量:"+nCardListNum); BYTE_32[] szCardList = msg.szCardList; for(int i=0;i