BjsbController.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. package com.ruoyi.web.controller.hk;
  2. import com.ruoyi.common.core.domain.AjaxResult;
  3. import com.sun.jna.Native;
  4. import com.sun.jna.Pointer;
  5. import org.springframework.web.bind.annotation.GetMapping;
  6. import org.springframework.web.bind.annotation.RequestMapping;
  7. import org.springframework.web.bind.annotation.RestController;
  8. import java.io.UnsupportedEncodingException;
  9. /**
  10. * @Author: tjf
  11. * @Date: 2025/6/6 星期五 16:03
  12. * @Describe:
  13. */
  14. @RestController
  15. @RequestMapping("/system/user")
  16. public class BjsbController {
  17. static HCNetSDK hCNetSDK = null;
  18. static int lUserID = -1;//用户句柄
  19. static int lAlarmHandle = -1;
  20. /**
  21. * 根据不同操作系统选择不同的库文件和库路径
  22. *
  23. * @return
  24. */
  25. private static boolean createSDKInstance() {
  26. if (hCNetSDK == null) {
  27. synchronized (HCNetSDK.class) {
  28. String strDllPath = "";
  29. try {
  30. //System.setProperty("jna.debug_load", "true");
  31. if (osSelect.isWindows())
  32. //win系统加载库路径
  33. strDllPath = System.getProperty("user.dir") + "\\lib\\HCNetSDK.dll";
  34. else if (osSelect.isLinux())
  35. //Linux系统加载库路径
  36. strDllPath = System.getProperty("user.dir") + "/libOne/libhcnetsdk.so";
  37. hCNetSDK = (HCNetSDK) Native.loadLibrary(strDllPath, HCNetSDK.class);
  38. } catch (Exception ex) {
  39. System.out.println("loadLibrary: " + strDllPath + " Error: " + ex.getMessage());
  40. return false;
  41. }
  42. }
  43. }
  44. return true;
  45. }
  46. /**
  47. * 获取表计数据
  48. */
  49. @GetMapping("/getBj")
  50. public AjaxResult getBj() {
  51. if (hCNetSDK == null) {
  52. if (!createSDKInstance()) {
  53. System.out.println("Load SDK fail");
  54. return AjaxResult.error("Load SDK fail");
  55. }
  56. }
  57. //linux系统建议调用以下接口加载组件库
  58. if (osSelect.isLinux()) {
  59. HCNetSDK.BYTE_ARRAY ptrByteArray1 = new HCNetSDK.BYTE_ARRAY(256);
  60. HCNetSDK.BYTE_ARRAY ptrByteArray2 = new HCNetSDK.BYTE_ARRAY(256);
  61. //这里是库的绝对路径,请根据实际情况修改,注意改路径必须有访问权限
  62. String strPath1 = System.getProperty("user.dir") + "/lib/libcrypto.so.1.1";
  63. String strPath2 = System.getProperty("user.dir") + "/lib/libssl.so.1.1";
  64. System.arraycopy(strPath1.getBytes(), 0, ptrByteArray1.byValue, 0, strPath1.length());
  65. ptrByteArray1.write();
  66. hCNetSDK.NET_DVR_SetSDKInitCfg(HCNetSDK.NET_SDK_INIT_CFG_LIBEAY_PATH, ptrByteArray1.getPointer());
  67. System.arraycopy(strPath2.getBytes(), 0, ptrByteArray2.byValue, 0, strPath2.length());
  68. ptrByteArray2.write();
  69. hCNetSDK.NET_DVR_SetSDKInitCfg(HCNetSDK.NET_SDK_INIT_CFG_SSLEAY_PATH, ptrByteArray2.getPointer());
  70. String strPathCom = System.getProperty("user.dir") + "/lib/";
  71. HCNetSDK.NET_DVR_LOCAL_SDK_PATH struComPath = new HCNetSDK.NET_DVR_LOCAL_SDK_PATH();
  72. System.arraycopy(strPathCom.getBytes(), 0, struComPath.sPath, 0, strPathCom.length());
  73. struComPath.write();
  74. hCNetSDK.NET_DVR_SetSDKInitCfg(HCNetSDK.NET_SDK_INIT_CFG_SDK_PATH, struComPath.getPointer());
  75. }
  76. /*初始化*/
  77. hCNetSDK.NET_DVR_Init();
  78. /*加载日志*/
  79. //hCNetSDK.NET_DVR_SetLogToFile(3, "./sdklog", false);
  80. //分离模式(建议):对应报警信息类型COMM_ISAPI_ALARM,pAlarmInfo对应结构体NET_DVR_ALARM_ISAPI_INFO,将报警事件信息数据(XML或者JSON格式的字符串)和二进制图片数据分离,分别在结构体的pAlarmData、pPicPackData指针指向的内存里面返回。设备上传的报警信息包含图片数据,图片数据有二进制传输方式和URL传输方式两种,如果URL方式则对应pPicPackData为空,报警事件信息数据(XML或者JSON格式的字符串)里面包含HTTP协议的URL字段。
  81. HCNetSDK.NET_DVR_LOCAL_GENERAL_CFG struNET_DVR_LOCAL_GENERAL_CFG = new HCNetSDK.NET_DVR_LOCAL_GENERAL_CFG();
  82. //控制JSON透传报警数据和图片是否分离,0-不分离,1-分离(分离后走COMM_ISAPI_ALARM回调返回)
  83. struNET_DVR_LOCAL_GENERAL_CFG.byAlarmJsonPictureSeparate = 1;
  84. struNET_DVR_LOCAL_GENERAL_CFG.write();
  85. Pointer pStrNET_DVR_LOCAL_GENERAL_CFG = struNET_DVR_LOCAL_GENERAL_CFG.getPointer();
  86. if (!hCNetSDK.NET_DVR_SetSDKLocalCfg(17, pStrNET_DVR_LOCAL_GENERAL_CFG)) {
  87. AjaxResult.error("报警主机NET_DVR_SetSDKLocalCfg失败");
  88. }
  89. //设置连接时间与重连时间
  90. hCNetSDK.NET_DVR_SetConnectTime(2000, 1);
  91. hCNetSDK.NET_DVR_SetReconnect(10000, true);
  92. //设备登录
  93. lUserID = loginDevice("10.9.137.190", (short) 8000, "admin", "hik12345"); //登录设备
  94. if (lUserID == -1) {
  95. return AjaxResult.error("请先注册报警主机");
  96. }
  97. //设置报警回调函数
  98. HCNetSDK.FMSGCallBack_V31 fMSFCallBack_v31 = new FMSGCallBack_V31();
  99. boolean flag = hCNetSDK.NET_DVR_SetDVRMessageCallBack_V50(0, fMSFCallBack_v31, null);
  100. if (!flag) {
  101. AjaxResult.error("报警主机设置回调函数失败!");
  102. }
  103. //启用布防
  104. HCNetSDK.NET_DVR_SETUPALARM_PARAM_V50 struAlarmParam = new HCNetSDK.NET_DVR_SETUPALARM_PARAM_V50();
  105. struAlarmParam.byAlarmTypeURL = 1;
  106. struAlarmParam.write();
  107. lAlarmHandle = hCNetSDK.NET_DVR_SetupAlarmChan_V50(lUserID, struAlarmParam, null, 0);
  108. if (lAlarmHandle == -1) {
  109. return AjaxResult.error("报警主机布防失败,错误号:" + hCNetSDK.NET_DVR_GetLastError());
  110. } else {
  111. return AjaxResult.success("报警主机布防成功");
  112. }
  113. }
  114. /**
  115. * @description: 报警信息回调函数
  116. **/
  117. public class FMSGCallBack_V31 implements HCNetSDK.FMSGCallBack_V31 {
  118. /**
  119. * @param lCommand 上传消息类型
  120. * @param pAlarmer 报警设备信息
  121. * @param pAlarmInfo 报警信息
  122. * @param dwBufLen 报警信息缓存大小
  123. * @param pUser 用户数据
  124. * @return
  125. */
  126. @Override
  127. public boolean invoke(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) throws UnsupportedEncodingException {
  128. alarmDataHandle(lCommand, pAlarmer, pAlarmInfo, dwBufLen, pUser);
  129. return true;
  130. }
  131. //报警信息回调函数
  132. public void alarmDataHandle(int lCommand, HCNetSDK.NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) throws UnsupportedEncodingException {
  133. //报警时间
  134. String sAlarmType = "lCommand=0x" + Integer.toHexString(lCommand);
  135. System.out.println(pAlarmInfo);
  136. //退出程序时调用NET_DVR_Logout注销设备
  137. Logout();
  138. //lCommand是传的报警类型
  139. /* switch (lCommand) {
  140. case HCNetSDK.COMM_ISAPI_ALARM:
  141. HCNetSDK.NET_DVR_ALARM_ISAPI_INFO struISAPIAlarm = new HCNetSDK.NET_DVR_ALARM_ISAPI_INFO();
  142. //解析JSON数据
  143. if (struISAPIAlarm.dwAlarmDataLen > 0)
  144. {
  145. printf("COMM_ISAPI_ALARM报警事件信息数据: \n%s\n", UTF8ToAnsi(struISAPIAlarm.pAlarmData));
  146. }
  147. break;
  148. default:
  149. break;
  150. }*/
  151. }
  152. }
  153. /**
  154. * 登录设备,支持 V40 和 V30 版本,功能一致。
  155. *
  156. * @param ip 设备IP地址
  157. * @param port SDK端口,默认为设备的8000端口
  158. * @param user 设备用户名
  159. * @param psw 设备密码
  160. * @return 登录成功返回用户ID,失败返回-1
  161. */
  162. public static int loginDevice(String ip, short port, String user, String psw) {
  163. // 创建设备登录信息和设备信息对象
  164. HCNetSDK.NET_DVR_USER_LOGIN_INFO loginInfo = new HCNetSDK.NET_DVR_USER_LOGIN_INFO();
  165. HCNetSDK.NET_DVR_DEVICEINFO_V40 deviceInfo = new HCNetSDK.NET_DVR_DEVICEINFO_V40();
  166. // 设置设备IP地址
  167. byte[] deviceAddress = new byte[HCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
  168. byte[] ipBytes = ip.getBytes();
  169. System.arraycopy(ipBytes, 0, deviceAddress, 0, Math.min(ipBytes.length, deviceAddress.length));
  170. loginInfo.sDeviceAddress = deviceAddress;
  171. // 设置用户名和密码
  172. byte[] userName = new byte[HCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
  173. byte[] password = psw.getBytes();
  174. System.arraycopy(user.getBytes(), 0, userName, 0, Math.min(user.length(), userName.length));
  175. System.arraycopy(password, 0, loginInfo.sPassword, 0, Math.min(password.length, loginInfo.sPassword.length));
  176. loginInfo.sUserName = userName;
  177. // 设置端口和登录模式
  178. loginInfo.wPort = port;
  179. loginInfo.bUseAsynLogin = false; // 同步登录
  180. loginInfo.byLoginMode = 0; // 使用SDK私有协议
  181. // 执行登录操作
  182. int userID = hCNetSDK.NET_DVR_Login_V40(loginInfo, deviceInfo);
  183. if (userID == -1) {
  184. System.err.println("登录失败,错误码为: " + hCNetSDK.NET_DVR_GetLastError());
  185. } else {
  186. System.out.println(ip + " 设备登录成功!");
  187. // 处理通道号逻辑
  188. int startDChan = deviceInfo.struDeviceV30.byStartDChan;
  189. System.out.println("预览起始通道号: " + startDChan);
  190. }
  191. return userID; // 返回登录结果
  192. }
  193. /**
  194. * 报警主机注销用户,释放资源
  195. */
  196. public static AjaxResult Logout() {
  197. //报警撤防
  198. if (lAlarmHandle > -1) {
  199. if (hCNetSDK.NET_DVR_CloseAlarmChan_V30(lAlarmHandle)) {
  200. lAlarmHandle = -1;
  201. //注销
  202. if (lUserID > -1) {
  203. if (hCNetSDK.NET_DVR_Logout(lUserID)) {
  204. hCNetSDK.NET_DVR_Cleanup();
  205. lUserID = -1;
  206. return AjaxResult.success("报警主机注销用户,撤防成功");
  207. } else {
  208. System.out.println("报警主机注销失败,错误号:" + hCNetSDK.NET_DVR_GetLastError());
  209. }
  210. }
  211. } else {
  212. System.out.println("报警主机撤防失败,错误号:" + hCNetSDK.NET_DVR_GetLastError());
  213. }
  214. }
  215. return AjaxResult.error("报警主机注销用户失败,错误号:" + hCNetSDK.NET_DVR_GetLastError());
  216. }
  217. }