package com.ruoyi.web.controller.hk; import com.ruoyi.common.core.domain.AjaxResult; import com.sun.jna.Native; import com.sun.jna.Pointer; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.io.UnsupportedEncodingException; /** * @Author: tjf * @Date: 2025/6/6 星期五 16:03 * @Describe: */ @RestController @RequestMapping("/system/user") public class BjsbController { static HCNetSDK hCNetSDK = null; static int lUserID = -1;//用户句柄 static int lAlarmHandle = -1; /** * 根据不同操作系统选择不同的库文件和库路径 * * @return */ private static boolean createSDKInstance() { if (hCNetSDK == null) { synchronized (HCNetSDK.class) { String strDllPath = ""; try { //System.setProperty("jna.debug_load", "true"); if (osSelect.isWindows()) //win系统加载库路径 strDllPath = System.getProperty("user.dir") + "\\lib\\HCNetSDK.dll"; else if (osSelect.isLinux()) //Linux系统加载库路径 strDllPath = System.getProperty("user.dir") + "/libOne/libhcnetsdk.so"; hCNetSDK = (HCNetSDK) Native.loadLibrary(strDllPath, HCNetSDK.class); } catch (Exception ex) { System.out.println("loadLibrary: " + strDllPath + " Error: " + ex.getMessage()); return false; } } } return true; } /** * 获取表计数据 */ @GetMapping("/getBj") public AjaxResult getBj() { if (hCNetSDK == null) { if (!createSDKInstance()) { System.out.println("Load SDK fail"); return AjaxResult.error("Load SDK fail"); } } //linux系统建议调用以下接口加载组件库 if (osSelect.isLinux()) { HCNetSDK.BYTE_ARRAY ptrByteArray1 = new HCNetSDK.BYTE_ARRAY(256); HCNetSDK.BYTE_ARRAY ptrByteArray2 = new HCNetSDK.BYTE_ARRAY(256); //这里是库的绝对路径,请根据实际情况修改,注意改路径必须有访问权限 String strPath1 = System.getProperty("user.dir") + "/lib/libcrypto.so.1.1"; String strPath2 = System.getProperty("user.dir") + "/lib/libssl.so.1.1"; System.arraycopy(strPath1.getBytes(), 0, ptrByteArray1.byValue, 0, strPath1.length()); ptrByteArray1.write(); hCNetSDK.NET_DVR_SetSDKInitCfg(HCNetSDK.NET_SDK_INIT_CFG_LIBEAY_PATH, ptrByteArray1.getPointer()); System.arraycopy(strPath2.getBytes(), 0, ptrByteArray2.byValue, 0, strPath2.length()); ptrByteArray2.write(); hCNetSDK.NET_DVR_SetSDKInitCfg(HCNetSDK.NET_SDK_INIT_CFG_SSLEAY_PATH, ptrByteArray2.getPointer()); String strPathCom = System.getProperty("user.dir") + "/lib/"; HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH(); System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length()); struComPath.write(); hCNetSDK.NET_DVR_SetSDKInitCfg(HCNetSDK.NET_SDK_INIT_CFG_SDK_PATH, struComPath.getPointer()); } /*初始化*/ hCNetSDK.NET_DVR_Init(); /*加载日志*/ //hCNetSDK.NET_DVR_SetLogToFile(3, "./sdklog", false); //分离模式(建议):对应报警信息类型COMM_ISAPI_ALARM,pAlarmInfo对应结构体NET_DVR_ALARM_ISAPI_INFO,将报警事件信息数据(XML或者JSON格式的字符串)和二进制图片数据分离,分别在结构体的pAlarmData、pPicPackData指针指向的内存里面返回。设备上传的报警信息包含图片数据,图片数据有二进制传输方式和URL传输方式两种,如果URL方式则对应pPicPackData为空,报警事件信息数据(XML或者JSON格式的字符串)里面包含HTTP协议的URL字段。 HCNetSDK.NET_DVR_LOCAL_GENERAL_CFG struNET_DVR_LOCAL_GENERAL_CFG = new HCNetSDK.NET_DVR_LOCAL_GENERAL_CFG(); //控制JSON透传报警数据和图片是否分离,0-不分离,1-分离(分离后走COMM_ISAPI_ALARM回调返回) struNET_DVR_LOCAL_GENERAL_CFG.byAlarmJsonPictureSeparate = 1; struNET_DVR_LOCAL_GENERAL_CFG.write(); Pointer pStrNET_DVR_LOCAL_GENERAL_CFG = struNET_DVR_LOCAL_GENERAL_CFG.getPointer(); if (!hCNetSDK.NET_DVR_SetSDKLocalCfg(17, pStrNET_DVR_LOCAL_GENERAL_CFG)) { AjaxResult.error("报警主机NET_DVR_SetSDKLocalCfg失败"); } //设置连接时间与重连时间 hCNetSDK.NET_DVR_SetConnectTime(2000, 1); hCNetSDK.NET_DVR_SetReconnect(10000, true); //设备登录 lUserID = loginDevice("10.9.137.190", (short) 8000, "admin", "hik12345"); //登录设备 if (lUserID == -1) { return AjaxResult.error("请先注册报警主机"); } //设置报警回调函数 HCNetSDK.FMSGCallBack_V31 fMSFCallBack_v31 = new FMSGCallBack_V31(); boolean flag = hCNetSDK.NET_DVR_SetDVRMessageCallBack_V50(0, fMSFCallBack_v31, null); if (!flag) { AjaxResult.error("报警主机设置回调函数失败!"); } //启用布防 HCNetSDK.NET_DVR_SETUPALARM_PARAM_V50 struAlarmParam = new HCNetSDK.NET_DVR_SETUPALARM_PARAM_V50(); struAlarmParam.byAlarmTypeURL = 1; struAlarmParam.write(); lAlarmHandle = hCNetSDK.NET_DVR_SetupAlarmChan_V50(lUserID, struAlarmParam, null, 0); if (lAlarmHandle == -1) { return AjaxResult.error("报警主机布防失败,错误号:" + hCNetSDK.NET_DVR_GetLastError()); } else { return AjaxResult.success("报警主机布防成功"); } } /** * @description: 报警信息回调函数 **/ public class FMSGCallBack_V31 implements HCNetSDK.FMSGCallBack_V31 { /** * @param lCommand 上传消息类型 * @param pAlarmer 报警设备信息 * @param pAlarmInfo 报警信息 * @param dwBufLen 报警信息缓存大小 * @param pUser 用户数据 * @return */ @Override public boolean invoke(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) throws UnsupportedEncodingException { alarmDataHandle(lCommand, pAlarmer, pAlarmInfo, dwBufLen, pUser); return true; } //报警信息回调函数 public void alarmDataHandle(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) throws UnsupportedEncodingException { //报警时间 String sAlarmType = "lCommand=0x" + Integer.toHexString(lCommand); System.out.println(pAlarmInfo); //退出程序时调用NET_DVR_Logout注销设备 Logout(); //lCommand是传的报警类型 /* switch (lCommand) { case HCNetSDK.COMM_ISAPI_ALARM: HCNetSDK.NET_DVR_ALARM_ISAPI_INFO struISAPIAlarm = new HCNetSDK.NET_DVR_ALARM_ISAPI_INFO(); //解析JSON数据 if (struISAPIAlarm.dwAlarmDataLen > 0) { printf("COMM_ISAPI_ALARM报警事件信息数据: \n%s\n", UTF8ToAnsi(struISAPIAlarm.pAlarmData)); } break; default: break; }*/ } } /** * 登录设备,支持 V40 和 V30 版本,功能一致。 * * @param ip 设备IP地址 * @param port SDK端口,默认为设备的8000端口 * @param user 设备用户名 * @param psw 设备密码 * @return 登录成功返回用户ID,失败返回-1 */ public static int loginDevice(String ip, short port, String user, String psw) { // 创建设备登录信息和设备信息对象 HCNetSDK.NET_DVR_USER_LOGIN_INFO loginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO(); HCNetSDK.NET_DVR_DEVICEINFO_V40 deviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40(); // 设置设备IP地址 byte[] deviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN]; byte[] ipBytes = ip.getBytes(); System.arraycopy(ipBytes, 0, deviceAddress, 0, Math.min(ipBytes.length, deviceAddress.length)); loginInfo.sDeviceAddress = deviceAddress; // 设置用户名和密码 byte[] userName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN]; byte[] password = psw.getBytes(); System.arraycopy(user.getBytes(), 0, userName, 0, Math.min(user.length(), userName.length)); System.arraycopy(password, 0, loginInfo.sPassword, 0, Math.min(password.length, loginInfo.sPassword.length)); loginInfo.sUserName = userName; // 设置端口和登录模式 loginInfo.wPort = port; loginInfo.bUseAsynLogin = false; // 同步登录 loginInfo.byLoginMode = 0; // 使用SDK私有协议 // 执行登录操作 int userID = hCNetSDK.NET_DVR_Login_V40(loginInfo, deviceInfo); if (userID == -1) { System.err.println("登录失败,错误码为: " + hCNetSDK.NET_DVR_GetLastError()); } else { System.out.println(ip + " 设备登录成功!"); // 处理通道号逻辑 int startDChan = deviceInfo.struDeviceV30.byStartDChan; System.out.println("预览起始通道号: " + startDChan); } return userID; // 返回登录结果 } /** * 报警主机注销用户,释放资源 */ public static AjaxResult Logout() { //报警撤防 if (lAlarmHandle > -1) { if (hCNetSDK.NET_DVR_CloseAlarmChan_V30(lAlarmHandle)) { lAlarmHandle = -1; //注销 if (lUserID > -1) { if (hCNetSDK.NET_DVR_Logout(lUserID)) { hCNetSDK.NET_DVR_Cleanup(); lUserID = -1; return AjaxResult.success("报警主机注销用户,撤防成功"); } else { System.out.println("报警主机注销失败,错误号:" + hCNetSDK.NET_DVR_GetLastError()); } } } else { System.out.println("报警主机撤防失败,错误号:" + hCNetSDK.NET_DVR_GetLastError()); } } return AjaxResult.error("报警主机注销用户失败,错误号:" + hCNetSDK.NET_DVR_GetLastError()); } }