|
|
@@ -4,15 +4,17 @@ package com.supervision.web.ConnectSDK.carDoor.hik;
|
|
|
import com.supervision.web.ConnectSDK.carDoor.CommonMethod.ConfigFileUtil;
|
|
|
import com.supervision.web.ConnectSDK.carDoor.NetSDKDemo.HCNetSDK;
|
|
|
import com.sun.jna.Pointer;
|
|
|
+import com.supervision.web.carGateManage.entity.NameList;
|
|
|
import org.dom4j.Document;
|
|
|
import org.dom4j.DocumentHelper;
|
|
|
import org.dom4j.Element;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
-import org.springframework.beans.factory.annotation.Qualifier;
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
+import java.util.Calendar;
|
|
|
+import java.util.Date;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.Map;
|
|
|
import java.util.UUID;
|
|
|
@@ -38,70 +40,111 @@ public class VechileListManage {
|
|
|
public ISAPI isapi;
|
|
|
|
|
|
// 车辆授权名单下发
|
|
|
- public void addVechileList(int lUserID) throws Exception {
|
|
|
+ public void addVechileList(int lUserID, NameList nameList) throws Exception {
|
|
|
if (fVehicleCrtlCB == null) {
|
|
|
- fVehicleCrtlCB = new FVehicleCrtlCB();
|
|
|
+ fVehicleCrtlCB = new FVehicleCrtlCB(); // 初始化回调
|
|
|
}
|
|
|
- int lHandle =
|
|
|
- hCNetSDK.NET_DVR_StartRemoteConfig(lUserID, HCNetSDK.NET_DVR_VEHICLELIST_CTRL_START, null, 0,
|
|
|
- fVehicleCrtlCB, Pointer.NULL);
|
|
|
- if (lHandle <= -1) {
|
|
|
|
|
|
+ // 启动远程配置
|
|
|
+ int lHandle = hCNetSDK.NET_DVR_StartRemoteConfig(
|
|
|
+ lUserID,
|
|
|
+ HCNetSDK.NET_DVR_VEHICLELIST_CTRL_START,
|
|
|
+ null,
|
|
|
+ 0,
|
|
|
+ fVehicleCrtlCB,
|
|
|
+ Pointer.NULL
|
|
|
+ );
|
|
|
+
|
|
|
+ if (lHandle <= -1) {
|
|
|
logger.info("NET_DVR_StartRemoteConfig failed errorCode:" + hCNetSDK.NET_DVR_GetLastError());
|
|
|
return;
|
|
|
}
|
|
|
- HCNetSDK.NET_DVR_VEHICLE_CONTROL_LIST_INFO struVehicleControl =
|
|
|
- new HCNetSDK.NET_DVR_VEHICLE_CONTROL_LIST_INFO();
|
|
|
- struVehicleControl.read();
|
|
|
- struVehicleControl.dwSize = struVehicleControl.size();
|
|
|
- struVehicleControl.dwChannel = 1; //通道号,出入口抓拍机,一体机默认1
|
|
|
- String sLicense = "浙A12345"; //车牌号码
|
|
|
- struVehicleControl.sLicense = sLicense.getBytes("GBK"); //车牌号码
|
|
|
- struVehicleControl.byListType = 0; //名单属性:0- 授权名单,1- 非授权名单
|
|
|
- struVehicleControl.byPlateType = 0; //0- 标准民用车与军车车牌 //参考SDK使用手册中车牌类型枚举类型
|
|
|
- /**
|
|
|
- * VCA_BLUE_PLATE
|
|
|
- * 0- 蓝色车牌
|
|
|
- * VCA_YELLOW_PLATE
|
|
|
- * 1- 黄色车牌
|
|
|
- * VCA_WHITE_PLATE
|
|
|
- * 2- 白色车牌
|
|
|
- * VCA_BLACK_PLATE
|
|
|
- * 3- 黑色车牌
|
|
|
- * VCA_GREEN_PLATE
|
|
|
- * 4- 绿色车牌
|
|
|
- * VCA_BKAIR_PLATE
|
|
|
- * 5- 民航黑色车牌
|
|
|
- * VCA_OTHER = 0xff
|
|
|
- * 0xff- 其他
|
|
|
- */
|
|
|
- struVehicleControl.byPlateColor = 0; //车牌颜色
|
|
|
- //有效开始时间
|
|
|
- struVehicleControl.struStartTime.wYear = (short) 2024;
|
|
|
- struVehicleControl.struStartTime.byMonth = (byte) 01;
|
|
|
- struVehicleControl.struStartTime.byDay = (byte) 01;
|
|
|
- struVehicleControl.struStartTime.byHour = (byte) 00;
|
|
|
- struVehicleControl.struStartTime.byMinute = (byte) 00;
|
|
|
- struVehicleControl.struStartTime.bySecond = (byte) 00;
|
|
|
- //有效结束时间
|
|
|
- struVehicleControl.struStopTime.wYear = (short) 2028;
|
|
|
- struVehicleControl.struStopTime.byMonth = (byte) 12;
|
|
|
- struVehicleControl.struStopTime.byDay = (byte) 30;
|
|
|
- struVehicleControl.struStopTime.byHour = (byte) 23;
|
|
|
- struVehicleControl.struStopTime.byMinute = (byte) 59;
|
|
|
- struVehicleControl.struStopTime.bySecond = (byte) 59;
|
|
|
- struVehicleControl.write();
|
|
|
- boolean bSend = hCNetSDK.NET_DVR_SendRemoteConfig(lHandle, HCNetSDK.ENUM_SENDDATA,
|
|
|
- struVehicleControl.getPointer(), struVehicleControl.size());
|
|
|
+
|
|
|
+ HCNetSDK.NET_DVR_VEHICLE_CONTROL_LIST_INFO car = new HCNetSDK.NET_DVR_VEHICLE_CONTROL_LIST_INFO();
|
|
|
+ car.read(); // 读取结构体初始值
|
|
|
+
|
|
|
+ car.dwSize = car.size(); // 结构体大小
|
|
|
+ car.dwChannel = (nameList.getChannel() != null ? nameList.getChannel() : 1); // 通道号,出入口抓拍机,一体机默认1,0xffffffff表示全部通道
|
|
|
+ car.dwDataIndex = (nameList.getDataIndex() != null ? nameList.getDataIndex().intValue() : 0); // 数据流水号,SDK会自动维护
|
|
|
+
|
|
|
+ // 车牌号,固定16字节,GBK编码,不够补0,多余截断 // 车牌号码,最大16字节,GBK编码
|
|
|
+ byte[] licenseBytes = new byte[16];
|
|
|
+ if (nameList.getPlateNumber() != null) {
|
|
|
+ byte[] tmp = nameList.getPlateNumber().getBytes("GBK");
|
|
|
+ System.arraycopy(tmp, 0, licenseBytes, 0, Math.min(tmp.length, 16));
|
|
|
+ }
|
|
|
+ car.sLicense = licenseBytes;
|
|
|
+
|
|
|
+ car.byListType = (byte) ("whitelist".equalsIgnoreCase(nameList.getType()) ? 0 : 1); // 名单类型:0-授权,1-非授权
|
|
|
+ car.byPlateType = (byte) (nameList.getPlateType() != null ? nameList.getPlateType() : 0); // 车牌类型,0-标准民用车(参考 SDK 枚举 VCA_PLATE_TYPE)
|
|
|
+ car.byPlateColor = (byte) (nameList.getPlateColor() != null ? nameList.getPlateColor() : 0); // 车牌颜色,0-蓝色,1-黄色,2-白色,3-黑色,4-绿色,5-民航黑,0xff-其他
|
|
|
+
|
|
|
+ car.byRes = (nameList.getReserved1() != null ? nameList.getReserved1() : new byte[21]); // 保留字段,置0
|
|
|
+
|
|
|
+ // 卡号信息,固定48字节,GBK编码 // 卡号信息,可选,置0
|
|
|
+ byte[] cardNoBytes = new byte[48];
|
|
|
+ if (nameList.getCardNo() != null) {
|
|
|
+ byte[] tmp = nameList.getCardNo().getBytes("GBK");
|
|
|
+ System.arraycopy(tmp, 0, cardNoBytes, 0, Math.min(tmp.length, 48));
|
|
|
+ }
|
|
|
+ car.sCardNo = cardNoBytes;
|
|
|
+
|
|
|
+ // 有效开始时间
|
|
|
+ Calendar cal = Calendar.getInstance();
|
|
|
+ if (nameList.getAccessStartTime() != null) {
|
|
|
+ cal.setTime(nameList.getAccessStartTime());
|
|
|
+ } else {
|
|
|
+ cal.set(2024, Calendar.JANUARY, 1, 0, 0, 0); // 默认开始时间
|
|
|
+ }
|
|
|
+ car.struStartTime.wYear = (short) cal.get(Calendar.YEAR);
|
|
|
+ car.struStartTime.byMonth = (byte) (cal.get(Calendar.MONTH) + 1);
|
|
|
+ car.struStartTime.byDay = (byte) cal.get(Calendar.DAY_OF_MONTH);
|
|
|
+ car.struStartTime.byHour = (byte) cal.get(Calendar.HOUR_OF_DAY);
|
|
|
+ car.struStartTime.byMinute = (byte) cal.get(Calendar.MINUTE);
|
|
|
+ car.struStartTime.bySecond = (byte) cal.get(Calendar.SECOND);
|
|
|
+
|
|
|
+ // 有效结束时间
|
|
|
+ if (nameList.getAccessEndTime() != null) {
|
|
|
+ cal.setTime(nameList.getAccessEndTime());
|
|
|
+ } else {
|
|
|
+ cal.setTime(new Date()); // 默认结束时间为当前时间
|
|
|
+ }
|
|
|
+ car.struStopTime.wYear = (short) cal.get(Calendar.YEAR);
|
|
|
+ car.struStopTime.byMonth = (byte) (cal.get(Calendar.MONTH) + 1);
|
|
|
+ car.struStopTime.byDay = (byte) cal.get(Calendar.DAY_OF_MONTH);
|
|
|
+ car.struStopTime.byHour = (byte) cal.get(Calendar.HOUR_OF_DAY);
|
|
|
+ car.struStopTime.byMinute = (byte) cal.get(Calendar.MINUTE);
|
|
|
+ car.struStopTime.bySecond = (byte) cal.get(Calendar.SECOND);
|
|
|
+
|
|
|
+ // 同步操作数,固定32字节,GBK编码 // 同步操作数(增量同步用,平台维护)
|
|
|
+ byte[] operateBytes = new byte[32];
|
|
|
+ if (nameList.getOperateIndex() != null) {
|
|
|
+ byte[] tmp = nameList.getOperateIndex().getBytes("GBK");
|
|
|
+ System.arraycopy(tmp, 0, operateBytes, 0, Math.min(tmp.length, 32));
|
|
|
+ }
|
|
|
+ car.sOperateIndex = operateBytes;
|
|
|
+
|
|
|
+ car.byRes1 = (nameList.getReserved2() != null ? nameList.getReserved2() : new byte[224]); // 保留字段,置0
|
|
|
+
|
|
|
+ car.write(); // 写入内存,准备下发
|
|
|
+
|
|
|
+ // 下发到设备
|
|
|
+ boolean bSend = hCNetSDK.NET_DVR_SendRemoteConfig(
|
|
|
+ lHandle,
|
|
|
+ HCNetSDK.ENUM_SENDDATA,
|
|
|
+ car.getPointer(),
|
|
|
+ car.size()
|
|
|
+ );
|
|
|
if (!bSend) {
|
|
|
System.err.println("NET_DVR_SendRemoteConfig失败,错误码:" + hCNetSDK.NET_DVR_GetLastError());
|
|
|
- //关闭下发长连接
|
|
|
- hCNetSDK.NET_DVR_StopRemoteConfig(lHandle);
|
|
|
+ hCNetSDK.NET_DVR_StopRemoteConfig(lHandle); // 关闭下发长连接
|
|
|
}
|
|
|
+
|
|
|
/**
|
|
|
* 循环下发车牌名单,继续调用NET_DVR_SendRemoteConfig下发下一张车牌名单
|
|
|
*/
|
|
|
// 循环判断下发状态
|
|
|
+ long startTime = System.currentTimeMillis();
|
|
|
while (true) {
|
|
|
if (iStatus == 1000 || iStatus == 1002) {
|
|
|
// 调用方法关闭长连接
|
|
|
@@ -113,6 +156,12 @@ public class VechileListManage {
|
|
|
}
|
|
|
break; // 退出循环
|
|
|
}
|
|
|
+ if (System.currentTimeMillis() - startTime > 30_000) { // 超时30秒
|
|
|
+ logger.warn("下发超时,强制关闭长连接");
|
|
|
+ hCNetSDK.NET_DVR_StopRemoteConfig(lHandle);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ Thread.sleep(100); // 避免CPU空转
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -121,12 +170,16 @@ public class VechileListManage {
|
|
|
public void invoke(int dwType, Pointer lpBuffer, int dwBufLen, Pointer pUserData) {
|
|
|
switch (dwType) {
|
|
|
case HCNetSDK.NET_SDK_CALLBACK_TYPE_STATUS:
|
|
|
+
|
|
|
+ // 读取 SDK 返回的状态字节
|
|
|
HCNetSDK.BYTE_ARRAY struCallbackStatus = new HCNetSDK.BYTE_ARRAY(40);
|
|
|
struCallbackStatus.write();
|
|
|
Pointer pStatus = struCallbackStatus.getPointer();
|
|
|
pStatus.write(0, lpBuffer.getByteArray(0, struCallbackStatus.size()), 0, dwBufLen);
|
|
|
struCallbackStatus.read();
|
|
|
|
|
|
+ // 将前4个字节解析为状态值(小端序)
|
|
|
+ int status = 0;
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
int ioffset = i * 8;
|
|
|
int iByte = struCallbackStatus.byValue[i] & 0xff;
|
|
|
@@ -136,18 +189,16 @@ public class VechileListManage {
|
|
|
case HCNetSDK.NET_SDK_CALLBACK_STATUS_SUCCESS:// NET_SDK_CALLBACK_STATUS_SUCCESS
|
|
|
{
|
|
|
logger.info("下发成功");
|
|
|
- //增加消息事件,查询成功之后调用NET_DVR_StopRemoteConfig释放资源
|
|
|
+ // 增加消息事件,查询成功之后调用NET_DVR_StopRemoteConfig释放资源
|
|
|
break;
|
|
|
}
|
|
|
-
|
|
|
case HCNetSDK.NET_SDK_CALLBACK_STATUS_PROCESSING: {
|
|
|
logger.info("下发中...");
|
|
|
break;
|
|
|
}
|
|
|
-
|
|
|
case HCNetSDK.NET_SDK_CALLBACK_STATUS_FAILED: {
|
|
|
logger.info("下发失败,错误码: dwStatus:" + iStatus);
|
|
|
- //增加消息事件,查询失败之后调用NET_DVR_StopRemoteConfig释放资源
|
|
|
+ // 增加消息事件,查询失败之后调用NET_DVR_StopRemoteConfig释放资源
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
@@ -163,9 +214,9 @@ public class VechileListManage {
|
|
|
*
|
|
|
* @param lUserID
|
|
|
*/
|
|
|
- public void searchVechileList(int lUserID) {
|
|
|
+ public String searchVechileList(int lUserID) {
|
|
|
String searchVechileListUrl = "POST /ISAPI/Traffic/channels/1/searchLPListAudit";
|
|
|
- //输入参数,XML或者JSON数据,查询多条人员信息json报文
|
|
|
+ // 输入参数,XML或者JSON数据,查询多条人员信息json报文
|
|
|
Map<String, Object> parameter = new HashMap<>();
|
|
|
parameter.put("searchID", UUID.randomUUID()); // 查询id
|
|
|
parameter.put("maxResults", 30); // 最大查询数量
|
|
|
@@ -173,7 +224,7 @@ public class VechileListManage {
|
|
|
logger.info("查询的json报文:" + strInbuff);
|
|
|
String responseString = isapi.stdXMLConfig(lUserID, searchVechileListUrl, strInbuff);
|
|
|
logger.info("查询返回报文:" + responseString);
|
|
|
- return;
|
|
|
+ return responseString;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -181,9 +232,9 @@ public class VechileListManage {
|
|
|
*
|
|
|
* @param lUserID
|
|
|
*/
|
|
|
- public void deleteVechileList(int lUserID) {
|
|
|
+ public void deleteVechileList(int lUserID, NameList nameList) {
|
|
|
String deleteVechileListUrl = "PUT /ISAPI/Traffic/channels/1/DelLicensePlateAuditData?format=json";
|
|
|
- //输入参数,XML或者JSON数据
|
|
|
+ // 输入参数,XML或者JSON数据
|
|
|
Map<String, Object> parameter = new HashMap<>();
|
|
|
parameter.put("plateColor", "yellow"); // 查询id
|
|
|
parameter.put("licensePlate", "京AA12345"); // 最大查询数量
|
|
|
@@ -215,7 +266,7 @@ public class VechileListManage {
|
|
|
isapi.stdXMLConfig(lUserID, "POST /ISAPI/ITC/Entrance/VCL", xmlInput);
|
|
|
}
|
|
|
|
|
|
- // 删除车牌授权名单输入报文
|
|
|
+ // 删除车牌授权名单输入报文
|
|
|
public String deleteXml() {
|
|
|
Document document1;
|
|
|
Element root = DocumentHelper.createElement("VCLDelCond");
|
|
|
@@ -234,7 +285,7 @@ public class VechileListManage {
|
|
|
return requestXml;
|
|
|
}
|
|
|
|
|
|
- //查询车牌授权名单输入报文
|
|
|
+ // 查询车牌授权名单输入报文
|
|
|
public String getXml() {
|
|
|
Document document1;
|
|
|
Element root = DocumentHelper.createElement("VCLDelCond");
|