From a42863a7021abc2f8a74d1dcf22d730e2af8cc0f Mon Sep 17 00:00:00 2001 From: haidong Date: Tue, 10 Oct 2023 10:49:32 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=A4=A7=E5=8D=8E=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E5=AF=B9=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: haidong --- .../netsdk/demo/module/DeviceLogModule.java | 58 ++ .../com/netsdk/demo/module/GateModule.java | 641 +++++++++++++++++- .../com/netsdk/demo/module/LoginModule.java | 51 +- src/main/java/com/yzx/impl/DaHua.java | 101 +-- .../com/yzx/impl/HardwareEquipmentInfo.java | 24 +- 5 files changed, 804 insertions(+), 71 deletions(-) diff --git a/src/main/java/com/netsdk/demo/module/DeviceLogModule.java b/src/main/java/com/netsdk/demo/module/DeviceLogModule.java index a4a3a62..fbf0f38 100644 --- a/src/main/java/com/netsdk/demo/module/DeviceLogModule.java +++ b/src/main/java/com/netsdk/demo/module/DeviceLogModule.java @@ -1,5 +1,6 @@ package com.netsdk.demo.module; +import com.netsdk.lib.NetSDKLib; import com.netsdk.lib.ToolKits; import com.netsdk.lib.enumeration.DH_LOG_QUERY_TYPE; import com.netsdk.lib.structure.DH_DEVICE_LOG_ITEM_EX; @@ -69,4 +70,61 @@ public class DeviceLogModule { return null; } + + public static DH_DEVICE_LOG_ITEM_EX[] getSystemLogV2(NetSDKLib.LLong m_hLoginHandle, NET_TIME startTime, NET_TIME endTime){ + //查询条件,作为入参 + QUERY_DEVICE_LOG_PARAM param=new QUERY_DEVICE_LOG_PARAM(); + //要查询的日志类型 + param.emLogType= DH_LOG_QUERY_TYPE.DHLOG_ALL.ordinal(); + + //通道号 + param.nChannelID=0; + //开始查询的条数 + param.nStartNum=0; + //结束查询的条数,30-1+1=30,查询的条数是30条 + param.nEndNum=1024; + int logNum=param.nEndNum-param.nStartNum+1; + //日志数据结构体类型,写0 c层可能校验不通过,建议写1,使用DH_DEVICE_LOG_ITEM_EX作为日志数据的结构体, + // 因为c层对出参buffer长度的校验是以DH_DEVICE_LOG_ITEM_EX结构体长度来校验的 + // 而DH_DEVICE_LOG_ITEM_EX结构体的长度比DH_DEVICE_LOG_ITEM结构体要长得多 + param.nLogStuType=1; + //要查询的起始时间段 + param.stuStartTime= startTime; + //要查询的结束时间段 + param.stuEndTime= endTime; + + //入参 + Pointer queryParam=new Memory(param.size()); + ToolKits.SetStructDataToPointer(param,queryParam,0); + //日志数据结构体 + DH_DEVICE_LOG_ITEM_EX logBuffer=new DH_DEVICE_LOG_ITEM_EX(); + int totalSize = logBuffer.size() * logNum; + //出参,分配内存 + Pointer pointer=new Memory(totalSize); + pointer.clear(totalSize); + //出参,查询到的日志条数 + IntByReference relogNum = new IntByReference(1); + boolean bSet=LoginModule.netsdk.CLIENT_QueryDeviceLog(m_hLoginHandle,queryParam,pointer,totalSize,relogNum,3000); + System.out.println("get system log is:"+bSet); + if(bSet){ + System.out.println("返回的log 条数:"+relogNum.getValue()); + if(relogNum.getValue()>0){ + DH_DEVICE_LOG_ITEM_EX[] arrays=(DH_DEVICE_LOG_ITEM_EX[])new DH_DEVICE_LOG_ITEM_EX().toArray(relogNum.getValue()); + ToolKits.GetPointerDataToStructArr(pointer,arrays); + for(DH_DEVICE_LOG_ITEM_EX item:arrays){ + String time=item.getDate(); + String operator=item.getOperator(Charset.forName("GBK")).trim(); + String operation=item.getOperation(Charset.forName("GBK")).trim(); + String log=item.getLog(Charset.forName("GBK")).trim(); + String detailLog=item.getDetailLog(Charset.forName("GBK")).trim(); + System.out.println(time+","+operator+","+operation+","+log+","+detailLog+",日志类型:"+item.nLogType); + } + return arrays; + } + }else{ + System.out.println("get log error: the error code is "+ToolKits.getErrorCodePrint()); + } + + return null; + } } diff --git a/src/main/java/com/netsdk/demo/module/GateModule.java b/src/main/java/com/netsdk/demo/module/GateModule.java index 083d10e..774d5db 100644 --- a/src/main/java/com/netsdk/demo/module/GateModule.java +++ b/src/main/java/com/netsdk/demo/module/GateModule.java @@ -153,7 +153,111 @@ public class GateModule { return true; } - + + /** + * 添加卡 + * @param cardNo 卡号 + * @param userId 用户ID + * @param cardName 卡名 + * @param cardPwd 卡密码 + * @param cardStatus 卡状态 + * @param cardType 卡类型 + * @param useTimes 使用次数 + * @param isFirstEnter 是否首卡, 1-true, 0-false + * @param isValid 是否有效, 1-true, 0-false + * @param startValidTime 有效开始时间 + * @param endValidTime 有效结束时间 + * @return true:成功 false:失败 + */ + public static boolean insertCardV2(LLong m_hLoginHandle,String cardNo, String userId, String cardName, String cardPwd, + int cardStatus, int cardType, int useTimes, int isFirstEnter, + int isValid, String startValidTime, String endValidTime) { + /** + * 门禁卡记录集信息 + */ + NET_RECORDSET_ACCESS_CTL_CARD accessCardInfo = new NET_RECORDSET_ACCESS_CTL_CARD(); + + // 卡号 + System.arraycopy(cardNo.getBytes(), 0, accessCardInfo.szCardNo, 0, cardNo.getBytes().length); + + // 用户ID + System.arraycopy(userId.getBytes(), 0, accessCardInfo.szUserID, 0, userId.getBytes().length); + + // 卡名(设备上显示的姓名) + try { + System.arraycopy(cardName.getBytes("GBK"), 0, accessCardInfo.szCardName, 0, cardName.getBytes("GBK").length); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + // 卡密码 + System.arraycopy(cardPwd.getBytes(), 0, accessCardInfo.szPsw, 0, cardPwd.getBytes().length); + + //-- 设置开门权限 + accessCardInfo.nDoorNum = 2; + accessCardInfo.sznDoors[0] = 0; + accessCardInfo.sznDoors[1] = 1; + accessCardInfo.nTimeSectionNum = 2; // 与门数对应 + accessCardInfo.sznTimeSectionNo[0] = 255; // 表示第一个门全天有效 + accessCardInfo.sznTimeSectionNo[1] = 255; // 表示第二个门全天有效 + + // 卡状态 + accessCardInfo.emStatus = cardStatus; + + // 卡类型 + accessCardInfo.emType = cardType; + + // 使用次数 + accessCardInfo.nUserTime = useTimes; + + // 是否首卡 + accessCardInfo.bFirstEnter = isFirstEnter; + + // 是否有效 + accessCardInfo.bIsValid = isValid; + + // 有效开始时间 + String[] startTimes = startValidTime.split(" "); + accessCardInfo.stuValidStartTime.dwYear = Integer.parseInt(startTimes[0].split("-")[0]); + accessCardInfo.stuValidStartTime.dwMonth = Integer.parseInt(startTimes[0].split("-")[1]); + accessCardInfo.stuValidStartTime.dwDay = Integer.parseInt(startTimes[0].split("-")[2]); + accessCardInfo.stuValidStartTime.dwHour = Integer.parseInt(startTimes[1].split(":")[0]); + accessCardInfo.stuValidStartTime.dwMinute = Integer.parseInt(startTimes[1].split(":")[1]); + accessCardInfo.stuValidStartTime.dwSecond = Integer.parseInt(startTimes[01].split(":")[2]); + + // 有效结束时间 + String[] endTimes = endValidTime.split(" "); + accessCardInfo.stuValidEndTime.dwYear = Integer.parseInt(endTimes[0].split("-")[0]); + accessCardInfo.stuValidEndTime.dwMonth = Integer.parseInt(endTimes[0].split("-")[1]); + accessCardInfo.stuValidEndTime.dwDay = Integer.parseInt(endTimes[0].split("-")[2]); + accessCardInfo.stuValidEndTime.dwHour = Integer.parseInt(endTimes[1].split(":")[0]); + accessCardInfo.stuValidEndTime.dwMinute = Integer.parseInt(endTimes[1].split(":")[1]); + accessCardInfo.stuValidEndTime.dwSecond = Integer.parseInt(endTimes[1].split(":")[2]); + + /** + * 记录集操作 + */ + NET_CTRL_RECORDSET_INSERT_PARAM insert = new NET_CTRL_RECORDSET_INSERT_PARAM(); + insert.stuCtrlRecordSetInfo.emType = EM_NET_RECORD_TYPE.NET_RECORD_ACCESSCTLCARD; // 记录集类型 + insert.stuCtrlRecordSetInfo.pBuf = accessCardInfo.getPointer(); + + accessCardInfo.write(); + insert.write(); + boolean bRet = LoginModule.netsdk.CLIENT_ControlDevice(m_hLoginHandle, + CtrlType.CTRLTYPE_CTRL_RECORDSET_INSERT, insert.getPointer(), 5000); + insert.read(); + accessCardInfo.read(); + + if(!bRet) { + System.err.println("添加卡信息失败." + ToolKits.getErrorCodePrint()); + return false; + } else { + System.out.println("添加卡信息成功,卡信息记录集编号 : " + insert.stuCtrlRecordSetResult.nRecNo); + } + + return true; + } + /** * 修改卡信息 * @param recordNo 记录集编号 @@ -260,6 +364,113 @@ public class GateModule { return true; } + + /** + * 修改卡信息 + * @param recordNo 记录集编号 + * @param cardNo 卡号 + * @param userId 用户ID + * @param cardName 卡名 + * @param cardPwd 卡密码 + * @param cardStatus 卡状态 + * @param cardType 卡类型 + * @param useTimes 使用次数 + * @param isFirstEnter 是否首卡, 1-true, 0-false + * @param isValid 是否有效, 1-true, 0-false + * @param startValidTime 有效开始时间 + * @param endValidTime 有效结束时间 + * @return true:成功 false:失败 + */ + public static boolean modifyCardV2(LLong m_hLoginHandle,int recordNo, String cardNo, String userId, String cardName, String cardPwd, + int cardStatus, int cardType, int useTimes, int isFirstEnter, + int isValid, String startValidTime, String endValidTime) { + /** + * 门禁卡记录集信息 + */ + NET_RECORDSET_ACCESS_CTL_CARD accessCardInfo = new NET_RECORDSET_ACCESS_CTL_CARD(); + // 记录集编号, 修改、删除卡信息必须填写 + accessCardInfo.nRecNo = recordNo; + + // 卡号 + System.arraycopy(cardNo.getBytes(), 0, accessCardInfo.szCardNo, 0, cardNo.getBytes().length); + + // 用户ID + System.arraycopy(userId.getBytes(), 0, accessCardInfo.szUserID, 0, userId.getBytes().length); + + // 卡名(设备上显示的姓名) + try { + System.arraycopy(cardName.getBytes("GBK"), 0, accessCardInfo.szCardName, 0, cardName.getBytes("GBK").length); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + // 卡密码 + System.arraycopy(cardPwd.getBytes(), 0, accessCardInfo.szPsw, 0, cardPwd.getBytes().length); + + //-- 设置开门权限 + accessCardInfo.nDoorNum = 2; + accessCardInfo.sznDoors[0] = 0; + accessCardInfo.sznDoors[1] = 1; + accessCardInfo.nTimeSectionNum = 2; // 与门数对应 + accessCardInfo.sznTimeSectionNo[0] = 255; // 表示第一个门全天有效 + accessCardInfo.sznTimeSectionNo[1] = 255; // 表示第二个门全天有效 + + // 卡状态 + accessCardInfo.emStatus = cardStatus; + + // 卡类型 + accessCardInfo.emType = cardType; + + // 使用次数 + accessCardInfo.nUserTime = useTimes; + + // 是否首卡 + accessCardInfo.bFirstEnter = isFirstEnter; + + // 是否有效 + accessCardInfo.bIsValid = isValid; + + // 有效开始时间 + String[] startTimes = startValidTime.split(" "); + accessCardInfo.stuValidStartTime.dwYear = Integer.parseInt(startTimes[0].split("-")[0]); + accessCardInfo.stuValidStartTime.dwMonth = Integer.parseInt(startTimes[0].split("-")[1]); + accessCardInfo.stuValidStartTime.dwDay = Integer.parseInt(startTimes[0].split("-")[2]); + accessCardInfo.stuValidStartTime.dwHour = Integer.parseInt(startTimes[1].split(":")[0]); + accessCardInfo.stuValidStartTime.dwMinute = Integer.parseInt(startTimes[1].split(":")[1]); + accessCardInfo.stuValidStartTime.dwSecond = Integer.parseInt(startTimes[01].split(":")[2]); + + // 有效结束时间 + String[] endTimes = endValidTime.split(" "); + accessCardInfo.stuValidEndTime.dwYear = Integer.parseInt(endTimes[0].split("-")[0]); + accessCardInfo.stuValidEndTime.dwMonth = Integer.parseInt(endTimes[0].split("-")[1]); + accessCardInfo.stuValidEndTime.dwDay = Integer.parseInt(endTimes[0].split("-")[2]); + accessCardInfo.stuValidEndTime.dwHour = Integer.parseInt(endTimes[1].split(":")[0]); + accessCardInfo.stuValidEndTime.dwMinute = Integer.parseInt(endTimes[1].split(":")[1]); + accessCardInfo.stuValidEndTime.dwSecond = Integer.parseInt(endTimes[1].split(":")[2]); + + /** + * 记录集操作 + */ + NET_CTRL_RECORDSET_PARAM update = new NET_CTRL_RECORDSET_PARAM(); + update.emType = EM_NET_RECORD_TYPE.NET_RECORD_ACCESSCTLCARD; // 记录集信息类型 + update.pBuf = accessCardInfo.getPointer(); + + accessCardInfo.write(); + update.write(); + boolean bRet = LoginModule.netsdk.CLIENT_ControlDevice(m_hLoginHandle, + CtrlType.CTRLTYPE_CTRL_RECORDSET_UPDATE, update.getPointer(), 5000); + update.read(); + accessCardInfo.read(); + + if(!bRet) { + System.err.println("修改卡信息失败." + ToolKits.getErrorCodePrint()); + return false; + } else { + System.out.println("修改卡信息成功 "); + } + + return true; + } /** * 删除卡信息(单个删除) @@ -286,7 +497,33 @@ public class GateModule { return bRet; } - + + /** + * 删除卡信息(单个删除) + * @param recordNo 记录集编号 + */ + public static boolean deleteCardV2(LLong m_hLoginHandle,int recordNo) { + /** + * 记录集操作 + */ + NET_CTRL_RECORDSET_PARAM msg = new NET_CTRL_RECORDSET_PARAM(); + msg.emType = EM_NET_RECORD_TYPE.NET_RECORD_ACCESSCTLCARD; + msg.pBuf = new IntByReference(recordNo).getPointer(); + + msg.write(); + boolean bRet = LoginModule.netsdk.CLIENT_ControlDevice(m_hLoginHandle, + CtrlType.CTRLTYPE_CTRL_RECORDSET_REMOVE, msg.getPointer(), 5000); + msg.read(); + + if(!bRet){ + System.err.println("删除卡信息失败." + ToolKits.getErrorCodePrint()); + } else { + System.out.println("删除卡信息成功."); + } + + return bRet; + } + /** * 清除所有卡信息 */ @@ -309,6 +546,29 @@ public class GateModule { return bRet; } + + /** + * 清除所有卡信息 + */ + public static boolean clearCardV2(LLong m_hLoginHandle) { + /** + * 记录集操作 + */ + NetSDKLib.NET_CTRL_RECORDSET_PARAM msg = new NetSDKLib.NET_CTRL_RECORDSET_PARAM(); + msg.emType = EM_NET_RECORD_TYPE.NET_RECORD_ACCESSCTLCARD; // 门禁卡记录集信息类型 + + msg.write(); + boolean bRet = LoginModule.netsdk.CLIENT_ControlDevice(m_hLoginHandle, + CtrlType.CTRLTYPE_CTRL_RECORDSET_CLEAR, msg.getPointer(), 5000); + msg.read(); + if(!bRet){ + System.err.println("清空卡信息失败." + ToolKits.getErrorCodePrint()); + } else { + System.out.println("清空卡信息成功."); + } + + return bRet; + } ///////////////////////////////// 人脸的增、删、改、清空 /////////////////////////////////////// @@ -342,7 +602,99 @@ public class GateModule { /** * 出参 */ - NET_OUT_ADD_FACE_INFO stOut = new NET_OUT_ADD_FACE_INFO(); + NET_OUT_ADD_FACE_INFO stOut = new NET_OUT_ADD_FACE_INFO(); + + stIn.write(); + stOut.write(); + boolean bRet = LoginModule.netsdk.CLIENT_FaceInfoOpreate(LoginModule.m_hLoginHandle, emType, stIn.getPointer(), stOut.getPointer(), 5000); + stIn.read(); + stOut.read(); + if(bRet) { + System.out.println("添加人脸成功!"); + } else { + System.err.println("添加人脸失败!" + ToolKits.getErrorCodePrint()); + return false; + } + + return true; + } + + /** + * 添加人脸 + * @param userId 用户ID + * @param memory 图片缓存 + * @return + */ + public static boolean addFaceInfoV2(LLong m_hLoginHandle,String userId, Memory memory) { + int emType = EM_FACEINFO_OPREATE_TYPE.EM_FACEINFO_OPREATE_ADD; // 添加 + + /** + * 入参 + */ + NET_IN_ADD_FACE_INFO stIn = new NET_IN_ADD_FACE_INFO(); + + // 用户ID + System.arraycopy(userId.getBytes(), 0, stIn.szUserID, 0, userId.getBytes().length); + + // 人脸照片个数 + stIn.stuFaceInfo.nFacePhoto = 1; + + // 每张图片的大小 + stIn.stuFaceInfo.nFacePhotoLen[0] = (int) memory.size(); + + // 人脸照片数据,大小不超过100K, 图片格式为jpg + stIn.stuFaceInfo.pszFacePhotoArr[0].pszFacePhoto = memory; + + /** + * 出参 + */ + NET_OUT_ADD_FACE_INFO stOut = new NET_OUT_ADD_FACE_INFO(); + + stIn.write(); + stOut.write(); + boolean bRet = LoginModule.netsdk.CLIENT_FaceInfoOpreate(m_hLoginHandle, emType, stIn.getPointer(), stOut.getPointer(), 5000); + stIn.read(); + stOut.read(); + if(bRet) { + System.out.println("添加人脸成功!"); + } else { + System.err.println("添加人脸失败!" + ToolKits.getErrorCodePrint()); + return false; + } + + return true; + } + + /** + * 修改人脸 + * @param userId 用户ID + * @param memory 图片缓存 + * @return + */ + public static boolean modifyFaceInfo(String userId, Memory memory) { + int emType = EM_FACEINFO_OPREATE_TYPE.EM_FACEINFO_OPREATE_UPDATE; // 修改 + + /** + * 入参 + */ + NET_IN_UPDATE_FACE_INFO stIn = new NET_IN_UPDATE_FACE_INFO(); + + // 用户ID + System.arraycopy(userId.getBytes(), 0, stIn.szUserID, 0, userId.getBytes().length); + + // 人脸照片个数 + stIn.stuFaceInfo.nFacePhoto = 1; + + // 每张图片的大小 + stIn.stuFaceInfo.nFacePhotoLen[0] = (int) memory.size(); + + // 人脸照片数据,大小不超过100K, 图片格式为jpg + stIn.stuFaceInfo.pszFacePhotoArr[0].pszFacePhoto = memory; + + /** + * 出参 + */ + NET_OUT_UPDATE_FACE_INFO stOut = new NET_OUT_UPDATE_FACE_INFO(); stIn.write(); stOut.write(); @@ -350,49 +702,49 @@ public class GateModule { stIn.read(); stOut.read(); if(bRet) { - System.out.println("添加人脸成功!"); + System.out.println("修改人脸成功!"); } else { - System.err.println("添加人脸失败!" + ToolKits.getErrorCodePrint()); + System.err.println("修改人脸失败!" + ToolKits.getErrorCodePrint()); return false; } return true; } - + /** * 修改人脸 * @param userId 用户ID * @param memory 图片缓存 * @return */ - public static boolean modifyFaceInfo(String userId, Memory memory) { + public static boolean modifyFaceInfoV2(LLong m_hLoginHandle,String userId, Memory memory) { int emType = EM_FACEINFO_OPREATE_TYPE.EM_FACEINFO_OPREATE_UPDATE; // 修改 - + /** * 入参 */ NET_IN_UPDATE_FACE_INFO stIn = new NET_IN_UPDATE_FACE_INFO(); - + // 用户ID - System.arraycopy(userId.getBytes(), 0, stIn.szUserID, 0, userId.getBytes().length); - + System.arraycopy(userId.getBytes(), 0, stIn.szUserID, 0, userId.getBytes().length); + // 人脸照片个数 - stIn.stuFaceInfo.nFacePhoto = 1; - + stIn.stuFaceInfo.nFacePhoto = 1; + // 每张图片的大小 stIn.stuFaceInfo.nFacePhotoLen[0] = (int) memory.size(); // 人脸照片数据,大小不超过100K, 图片格式为jpg - stIn.stuFaceInfo.pszFacePhotoArr[0].pszFacePhoto = memory; - + stIn.stuFaceInfo.pszFacePhotoArr[0].pszFacePhoto = memory; + /** * 出参 */ NET_OUT_UPDATE_FACE_INFO stOut = new NET_OUT_UPDATE_FACE_INFO(); - + stIn.write(); stOut.write(); - boolean bRet = LoginModule.netsdk.CLIENT_FaceInfoOpreate(LoginModule.m_hLoginHandle, emType, stIn.getPointer(), stOut.getPointer(), 5000); + boolean bRet = LoginModule.netsdk.CLIENT_FaceInfoOpreate(m_hLoginHandle, emType, stIn.getPointer(), stOut.getPointer(), 5000); stIn.read(); stOut.read(); if(bRet) { @@ -401,10 +753,10 @@ public class GateModule { System.err.println("修改人脸失败!" + ToolKits.getErrorCodePrint()); return false; } - + return true; } - + /** * 删除人脸(单个删除) * @param userId 用户ID @@ -438,7 +790,41 @@ public class GateModule { return bRet; } - + + /** + * 删除人脸(单个删除) + * @param userId 用户ID + */ + public static boolean deleteFaceInfoV2(LLong m_hLoginHandle,String userId) { + int emType = EM_FACEINFO_OPREATE_TYPE.EM_FACEINFO_OPREATE_REMOVE; + + /** + * 入参 + */ + NET_IN_REMOVE_FACE_INFO inRemove = new NET_IN_REMOVE_FACE_INFO(); + + // 用户ID + System.arraycopy(userId.getBytes(), 0, inRemove.szUserID, 0, userId.getBytes().length); + + /** + * 出参 + */ + NET_OUT_REMOVE_FACE_INFO outRemove = new NET_OUT_REMOVE_FACE_INFO(); + + inRemove.write(); + outRemove.write(); + boolean bRet = LoginModule.netsdk.CLIENT_FaceInfoOpreate(m_hLoginHandle, emType, inRemove.getPointer(), outRemove.getPointer(), 5000); + inRemove.read(); + outRemove.read(); + if(bRet) { + System.out.println("删除人脸成功!"); + } else { + System.err.println("删除人脸失败!" + ToolKits.getErrorCodePrint()); + } + + return bRet; + } + /** * 清除所有人脸 */ @@ -457,7 +843,7 @@ public class GateModule { stIn.write(); stOut.write(); - boolean bRet = LoginModule.netsdk.CLIENT_FaceInfoOpreate(LoginModule.m_hLoginHandle, emType, + boolean bRet = LoginModule.netsdk.CLIENT_FaceInfoOpreate(LoginModule.m_hLoginHandle, emType, stIn.getPointer(), stOut.getPointer(), 5000); stIn.read(); stOut.read(); @@ -470,6 +856,37 @@ public class GateModule { return bRet; } + /** + * 清除所有人脸 + */ + public static boolean clearFaceInfoV2(LLong m_hLoginHandle) { + int emType = EM_FACEINFO_OPREATE_TYPE.EM_FACEINFO_OPREATE_CLEAR; // 清除 + + /** + * 入参 + */ + NET_IN_CLEAR_FACE_INFO stIn = new NET_IN_CLEAR_FACE_INFO(); + + /** + * 出参 + */ + NET_OUT_REMOVE_FACE_INFO stOut = new NET_OUT_REMOVE_FACE_INFO(); + + stIn.write(); + stOut.write(); + boolean bRet = LoginModule.netsdk.CLIENT_FaceInfoOpreate(m_hLoginHandle, emType, + stIn.getPointer(), stOut.getPointer(), 5000); + stIn.read(); + stOut.read(); + if(bRet) { + System.out.println("清空人脸成功!"); + } else { + System.err.println("清空人脸失败!" + ToolKits.getErrorCodePrint()); + } + + return bRet; + } + /** * 查询卡信息,获取查询句柄 * @param cardNo 卡号,为空,查询所有的 @@ -502,7 +919,7 @@ public class GateModule { */ NetSDKLib.NET_IN_FIND_RECORD_PARAM stIn = new NetSDKLib.NET_IN_FIND_RECORD_PARAM(); stIn.emType = NetSDKLib.EM_NET_RECORD_TYPE.NET_RECORD_ACCESSCTLCARD; - if(!cardNo.isEmpty()) { + if(!cardNo.isEmpty() || !userId.isEmpty()) { stIn.pQueryCondition = findCondition.getPointer(); } @@ -521,7 +938,58 @@ public class GateModule { m_lFindHandle = stOut.lFindeHandle; return true; } - + + /** + * 查询卡信息,获取查询句柄 + * @param cardNo 卡号,为空,查询所有的 + * @return + */ + public static LLong findCardV2(LLong m_hLoginHandle,String cardNo,String userId) { + /** + * 查询条件 + */ + NetSDKLib.FIND_RECORD_ACCESSCTLCARD_CONDITION findCondition = new NetSDKLib.FIND_RECORD_ACCESSCTLCARD_CONDITION(); + + if(!cardNo.isEmpty()) { + // 卡号查询条件是否有效 + findCondition.abCardNo = 1; + + // 卡号 + System.arraycopy(cardNo.getBytes(), 0, findCondition.szCardNo, 0, cardNo.getBytes().length); + } + + if(!userId.isEmpty()) { + // 用户Id查询条件是否有效 + findCondition.abUserID = 1; + + // 用户Id + System.arraycopy(userId.getBytes(), 0, findCondition.szUserID, 0, userId.getBytes().length); + } + + /** + * CLIENT_FindRecord 接口入参 + */ + NetSDKLib.NET_IN_FIND_RECORD_PARAM stIn = new NetSDKLib.NET_IN_FIND_RECORD_PARAM(); + stIn.emType = NetSDKLib.EM_NET_RECORD_TYPE.NET_RECORD_ACCESSCTLCARD; + if(!cardNo.isEmpty() || !userId.isEmpty()) { + stIn.pQueryCondition = findCondition.getPointer(); + } + + /** + * CLIENT_FindRecord 接口出参 + */ + NetSDKLib.NET_OUT_FIND_RECORD_PARAM stOut = new NetSDKLib.NET_OUT_FIND_RECORD_PARAM(); + + findCondition.write(); + if(!LoginModule.netsdk.CLIENT_FindRecord(m_hLoginHandle, stIn, stOut, 5000)) { + System.err.println("没查到卡信息!" + ToolKits.getErrorCodePrint()); + return m_lFindHandle; + } + findCondition.read(); + + return stOut.lFindeHandle; + } + /** * 查询具体的卡信息 * @param nFindCount 每次查询的个数 @@ -581,6 +1049,16 @@ public class GateModule { } } + /** + * 关闭查询 + */ + public static void findCardCloseV2(LLong m_lFindHandle) { + if(m_lFindHandle.longValue() != 0) { + LoginModule.netsdk.CLIENT_FindRecordClose(m_lFindHandle); + m_lFindHandle.setValue(0); + } + } + /** * 查询进出记录信息,获取查询句柄 @@ -638,6 +1116,61 @@ public class GateModule { return true; } + /** + * 查询进出记录信息,获取查询句柄 + * @param time 日期,为空,查询所有的 + * @return + */ + public static LLong findRecordV2(LLong m_hLoginHandle,NET_TIME time) { + /** + * 查询条件 + */ + NetSDKLib.FIND_RECORD_ACCESSCTLCARDREC_CONDITION_EX findCondition = new NetSDKLib.FIND_RECORD_ACCESSCTLCARDREC_CONDITION_EX(); + if(time != null){ + // 启用时间段查询是否有效 + findCondition.bTimeEnable = 1; + //开始时间 + findCondition.stStartTime.dwYear = time.dwYear; + findCondition.stStartTime.dwMonth = time.dwMonth; + findCondition.stStartTime.dwDay = time.dwDay; + //结束时间 + findCondition.stEndTime.dwYear = time.dwYear; + findCondition.stEndTime.dwMonth = time.dwMonth; + findCondition.stEndTime.dwDay = time.dwDay + 1; + } + + //启用排序 + findCondition.nOrderNum = 1;//规则数 + FIND_RECORD_ACCESSCTLCARDREC_ORDER order = new FIND_RECORD_ACCESSCTLCARDREC_ORDER(); + order.emField = EM_RECORD_ACCESSCTLCARDREC_ORDER_FIELD.EM_RECORD_ACCESSCTLCARDREC_ORDER_FIELD_CREATETIME;//创建时间排序 + order.emOrderType = EM_RECORD_ORDER_TYPE.EM_RECORD_ORDER_TYPE_ASCENT;//升序 + findCondition.stuOrders = new FIND_RECORD_ACCESSCTLCARDREC_ORDER[1]; + findCondition.stuOrders[0] = order; + + /** + * CLIENT_FindRecord 接口入参 + */ + NetSDKLib.NET_IN_FIND_RECORD_PARAM stIn = new NetSDKLib.NET_IN_FIND_RECORD_PARAM(); + stIn.emType = NetSDKLib.EM_NET_RECORD_TYPE.NET_RECORD_ACCESSCTLCARDREC_EX; + if(time != null) { + stIn.pQueryCondition = findCondition.getPointer(); + } + + /** + * CLIENT_FindRecord 接口出参 + */ + NetSDKLib.NET_OUT_FIND_RECORD_PARAM stOut = new NetSDKLib.NET_OUT_FIND_RECORD_PARAM(); + + findCondition.write(); + if(!LoginModule.netsdk.CLIENT_FindRecord(m_hLoginHandle, stIn, stOut, 5000)) { + System.err.println("没查到开门信息!" + ToolKits.getErrorCodePrint()); + return m_lFindHandle; + } + findCondition.read(); + + return stOut.lFindeHandle; + } + /** * 进出记录查询 */ @@ -690,6 +1223,58 @@ public class GateModule { return null; } + /** + * 进出记录查询 + */ + /** + * 查询具体的卡信息 + * @param nFindCount 每次查询的个数 + * @return 返回具体的查询信息 + */ + public static NET_RECORDSET_ACCESS_CTL_CARDREC[] findNextRecordV2(LLong m_lFindHandle,int nFindCount) { + // 用于申请内存 + NET_RECORDSET_ACCESS_CTL_CARDREC[] pstRecord = new NET_RECORDSET_ACCESS_CTL_CARDREC[nFindCount]; + for(int i = 0; i < nFindCount; i++) { + pstRecord[i] = new NET_RECORDSET_ACCESS_CTL_CARDREC(); + } + + /** + * CLIENT_FindNextRecord 接口入参 + */ + NET_IN_FIND_NEXT_RECORD_PARAM stNextIn = new NET_IN_FIND_NEXT_RECORD_PARAM(); + stNextIn.lFindeHandle = m_lFindHandle; + stNextIn.nFileCount = nFindCount; //想查询的记录条数 + + /** + * CLIENT_FindNextRecord 接口出参 + */ + NET_OUT_FIND_NEXT_RECORD_PARAM stNextOut = new NET_OUT_FIND_NEXT_RECORD_PARAM(); + stNextOut.nMaxRecordNum = nFindCount; + stNextOut.pRecordList = new Memory(pstRecord[0].dwSize * nFindCount); // 申请内存 + stNextOut.pRecordList.clear(pstRecord[0].dwSize * nFindCount); + + ToolKits.SetStructArrToPointerData(pstRecord, stNextOut.pRecordList); // 将数组内存拷贝给指针 + + if(LoginModule.netsdk.CLIENT_FindNextRecord(stNextIn, stNextOut, 5000)) { + if(stNextOut.nRetRecordNum == 0) { + return null; + } + + ToolKits.GetPointerDataToStructArr(stNextOut.pRecordList, pstRecord); // 获取卡信息 + + // 获取有用的信息 + NET_RECORDSET_ACCESS_CTL_CARDREC[] pstRecordEx = new NET_RECORDSET_ACCESS_CTL_CARDREC[stNextOut.nRetRecordNum]; + for(int i = 0; i < stNextOut.nRetRecordNum; i++) { + pstRecordEx[i] = new NET_RECORDSET_ACCESS_CTL_CARDREC(); + pstRecordEx[i] = pstRecord[i]; + } + + return pstRecordEx; + } + + return null; + } + /** * 关闭查询 */ @@ -699,4 +1284,14 @@ public class GateModule { m_lFindHandle.setValue(0); } } + + /** + * 关闭查询 + */ + public static void findRecordCloseV2(LLong m_lFindHandle) { + if(m_lFindHandle.longValue() != 0) { + LoginModule.netsdk.CLIENT_FindRecordClose(m_lFindHandle); + m_lFindHandle.setValue(0); + } + } } diff --git a/src/main/java/com/netsdk/demo/module/LoginModule.java b/src/main/java/com/netsdk/demo/module/LoginModule.java index 2c73527..8015d09 100644 --- a/src/main/java/com/netsdk/demo/module/LoginModule.java +++ b/src/main/java/com/netsdk/demo/module/LoginModule.java @@ -125,7 +125,36 @@ public class LoginModule { return m_hLoginHandle.longValue() == 0? false:true; } - + + /** + * \if ENGLISH_LANG + * Login Device + * \else + * 登录设备 + * \endif + */ + public static LLong login2(String m_strIp, int m_nPort, String m_strUser, String m_strPassword) { + //IntByReference nError = new IntByReference(0); + //入参 + NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY pstInParam=new NET_IN_LOGIN_WITH_HIGHLEVEL_SECURITY(); + pstInParam.nPort=m_nPort; + pstInParam.szIP=m_strIp.getBytes(); + pstInParam.szPassword=m_strPassword.getBytes(); + pstInParam.szUserName=m_strUser.getBytes(); + //出参 + NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY pstOutParam=new NET_OUT_LOGIN_WITH_HIGHLEVEL_SECURITY(); + pstOutParam.stuDeviceInfo=m_stDeviceInfo; + //m_hLoginHandle = netsdk.CLIENT_LoginEx2(m_strIp, m_nPort, m_strUser, m_strPassword, 0, null, m_stDeviceInfo, nError); + m_hLoginHandle=netsdk.CLIENT_LoginWithHighLevelSecurity(pstInParam, pstOutParam); + if(m_hLoginHandle.longValue() == 0) { + System.err.printf("Login Device[%s] Port[%d]Failed. %s\n", m_strIp, m_nPort, ToolKits.getErrorCodePrint()); + } else { + System.out.println("Login Success [ " + m_strIp + " ]"); + } + + return m_hLoginHandle; + } + /** * \if ENGLISH_LANG * Logout Device @@ -145,4 +174,24 @@ public class LoginModule { return bRet; } + + /** + * \if ENGLISH_LANG + * Logout Device + * \else + * 登出设备 + * \endif + */ + public static boolean logout2(LLong m_hLoginHandle) { + if(m_hLoginHandle.longValue() == 0) { + return false; + } + + boolean bRet = netsdk.CLIENT_Logout(m_hLoginHandle); + if(bRet) { + m_hLoginHandle.setValue(0); + } + + return bRet; + } } diff --git a/src/main/java/com/yzx/impl/DaHua.java b/src/main/java/com/yzx/impl/DaHua.java index de842e0..e8dbda4 100644 --- a/src/main/java/com/yzx/impl/DaHua.java +++ b/src/main/java/com/yzx/impl/DaHua.java @@ -6,6 +6,7 @@ import com.netsdk.demo.module.DeviceLogModule; import com.netsdk.demo.module.GateModule; import com.netsdk.demo.module.LoginModule; import com.netsdk.demo.module.TalkModule; +import com.netsdk.lib.NativeString; import com.netsdk.lib.NetSDKLib; import com.netsdk.lib.ToolKits; import com.netsdk.lib.structure.DH_DEVICE_LOG_ITEM_EX; @@ -47,23 +48,47 @@ public class DaHua implements IHardwareEquipment { public DaHua(HardwareEquipmentInfo info){ this.info = info; + this.login(); } + public boolean downloadPersonPic(String szFileName, String pszFileDst) { + /* + * 入参 + */ + NetSDKLib.NET_IN_DOWNLOAD_REMOTE_FILE stuIn = new NetSDKLib.NET_IN_DOWNLOAD_REMOTE_FILE(); + // 需要下载的文件名 + stuIn.pszFileName = new NativeString(szFileName).getPointer(); + + // 存放文件路径 + stuIn.pszFileDst = new NativeString(pszFileDst).getPointer(); + + /* + * 出参 + */ + NetSDKLib.NET_OUT_DOWNLOAD_REMOTE_FILE stuOut = new NetSDKLib.NET_OUT_DOWNLOAD_REMOTE_FILE(); + + if(!LoginModule.netsdk.CLIENT_DownloadRemoteFile(this.info.getLoginHandle(), stuIn, stuOut, 5000)) { + System.err.println("下载图片失败!" + ToolKits.getErrorCodePrint()); + return false; + } + + return true; + } + public boolean openDoor(){ - this.login(info.getIp(),info.getPort(),info.getUsername(),info.getPassword()); NetSDKLib.NET_CTRL_ACCESS_OPEN openInfo = new NetSDKLib.NET_CTRL_ACCESS_OPEN(); openInfo.nChannelID = 0; openInfo.emOpenDoorType = NetSDKLib.EM_OPEN_DOOR_TYPE.EM_OPEN_DOOR_TYPE_REMOTE; Pointer pointer = new Memory(openInfo.size()); ToolKits.SetStructDataToPointer(openInfo, pointer, 0); - boolean ret = LoginModule.netsdk.CLIENT_ControlDeviceEx(LoginModule.m_hLoginHandle, + boolean ret = LoginModule.netsdk.CLIENT_ControlDeviceEx(info.getLoginHandle(), NetSDKLib.CtrlType.CTRLTYPE_CTRL_ACCESS_OPEN, pointer, null, 10000); if (!ret) { return false; } - this.logout(); + return true; } @@ -74,13 +99,9 @@ public class DaHua implements IHardwareEquipment { * @return */ public boolean getSystemLog(String startTime,String endTime){ - this.login(info.getIp(),info.getPort(),info.getUsername(),info.getPassword()); - NET_TIME netTimeStart = new NET_TIME(startTime); NET_TIME netTimeEnd = new NET_TIME(endTime); - DH_DEVICE_LOG_ITEM_EX[] systemLog = DeviceLogModule.getSystemLog(netTimeStart, netTimeEnd); - //退出登录 - this.logout(); + DH_DEVICE_LOG_ITEM_EX[] systemLog = DeviceLogModule.getSystemLogV2(info.getLoginHandle(),netTimeStart, netTimeEnd); return true; } @@ -91,21 +112,21 @@ public class DaHua implements IHardwareEquipment { */ public List getAllRecord(NetSDKLib.NET_TIME time){ List faceRecrodInfoList = new ArrayList<>(); - this.login(info.getIp(),info.getPort(),info.getUsername(),info.getPassword()); - int count = 0; int index = 0; int nFindCount = 100; // 日期: 为空,查询所有开门信息 // 获取查询句柄 - if(!GateModule.findRecord(time)) { + NetSDKLib.LLong findHandle = GateModule.findRecordV2(info.getLoginHandle(), time); + this.info.setFindHandle(findHandle); + if(findHandle.longValue() == 0) { return faceRecrodInfoList; } // 查询具体信息 while(true) { - NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC[] pstRecord = GateModule.findNextRecord(nFindCount); + NetSDKLib.NET_RECORDSET_ACCESS_CTL_CARDREC[] pstRecord = GateModule.findNextRecordV2(info.getFindHandle(),nFindCount); if(pstRecord == null) { break; } @@ -160,10 +181,10 @@ public class DaHua implements IHardwareEquipment { } // 关闭查询接口 - GateModule.findRecordClose(); + GateModule.findRecordCloseV2(info.getFindHandle()); //退出登录 - this.logout(); + return faceRecrodInfoList; } @@ -173,9 +194,9 @@ public class DaHua implements IHardwareEquipment { */ public boolean addOrEditPersion(UserFaceInfo userFaceInfo){ - this.login(info.getIp(),info.getPort(),info.getUsername(),info.getPassword()); //查询用户 String employeeNo = userFaceInfo.getEmployeeNo(); + userFaceInfo.setCardNo(employeeNo); int recordNo = this.findRecordNo(employeeNo); if(recordNo != 0){//编辑 if(this.updateUserCard(userFaceInfo) && this.updateUserFace(employeeNo,userFaceInfo.getImageBytes())){ @@ -186,21 +207,20 @@ public class DaHua implements IHardwareEquipment { return true; } } - this.logout(); + return false; } public boolean deletePerson(UserFaceInfo userFaceInfo){ - this.login(info.getIp(),info.getPort(),info.getUsername(),info.getPassword()); //查询用户 String employeeNo = userFaceInfo.getEmployeeNo(); int recordNo = this.findRecordNo(employeeNo); if(recordNo != 0){ - if(GateModule.deleteCard(recordNo) && GateModule.deleteFaceInfo(employeeNo)){ + if(GateModule.deleteCardV2(info.getLoginHandle(),recordNo) && GateModule.deleteFaceInfoV2(info.getLoginHandle(),employeeNo)){ return true; } } - this.logout(); + return false; } @@ -212,7 +232,7 @@ public class DaHua implements IHardwareEquipment { */ private boolean addUserFace(String userId,byte[] imageBytes){ Memory memory = ToolKits.readPictureBytes(imageBytes); - boolean b = GateModule.addFaceInfo(userId, memory); + boolean b = GateModule.addFaceInfoV2(info.getLoginHandle(),userId, memory); return b; } @@ -224,7 +244,7 @@ public class DaHua implements IHardwareEquipment { */ private boolean updateUserFace(String userId,byte[] imageBytes){ Memory memory = ToolKits.readPictureBytes(imageBytes); - boolean b = GateModule.modifyFaceInfo(userId, memory); + boolean b = GateModule.modifyFaceInfoV2(info.getLoginHandle(),userId, memory); return b; } @@ -239,8 +259,7 @@ public class DaHua implements IHardwareEquipment { String startTime = userFaceInfo.getStartTime(); String endTime = userFaceInfo.getEndTime(); String cardNo = userFaceInfo.getCardNo(); - this.login(info.getIp(),info.getPort(),info.getUsername(),info.getPassword()); - boolean b = GateModule.insertCard(cardNo, employeeNo, employeeName, "", 0, 0, 0, 0, 1, startTime, endTime); + boolean b = GateModule.insertCardV2(info.getLoginHandle(),cardNo, employeeNo, employeeName, "", 0, 0, 0, 0, 1, startTime, endTime); return b; } @@ -250,17 +269,15 @@ public class DaHua implements IHardwareEquipment { * @return */ private boolean updateUserCard(UserFaceInfo userFaceInfo){ - String employeeNo = userFaceInfo.getEmployeeNo(); String employeeName = userFaceInfo.getEmployeeName(); String startTime = userFaceInfo.getStartTime(); String endTime = userFaceInfo.getEndTime(); String cardNo = userFaceInfo.getCardNo(); - this.login(info.getIp(),info.getPort(),info.getUsername(),info.getPassword()); //根据userId 查询记录集编号 int recordNo = this.findRecordNo(employeeNo); - boolean b = GateModule.modifyCard(recordNo,cardNo, employeeNo, employeeName, "", 0, 0, 0, 0, 1, startTime, endTime); + boolean b = GateModule.modifyCardV2(info.getLoginHandle(),recordNo,cardNo, employeeNo, employeeName, "", 0, 0, 0, 0, 1, startTime, endTime); return b; } @@ -268,7 +285,9 @@ public class DaHua implements IHardwareEquipment { int nFindCount = 1; // 卡号: 为空,查询所有的卡信息 // 获取查询句柄 - if(!GateModule.findCard("",employeeNo)) { + NetSDKLib.LLong findHandle = GateModule.findCardV2(this.info.getLoginHandle(), "", employeeNo); + this.info.setFindHandle(findHandle); + if(findHandle.longValue() == 0) { return 0; } @@ -290,19 +309,18 @@ public class DaHua implements IHardwareEquipment { } // 关闭查询接口 - GateModule.findCardClose(); + GateModule.findCardCloseV2(this.info.getFindHandle()); return 0; } public List findAllCard() { - this.login(info.getIp(),info.getPort(),info.getUsername(),info.getPassword()); List userFaceInfoList = new ArrayList<>(); int nFindCount = 1; // 卡号: 为空,查询所有的卡信息 // 获取查询句柄 - if(!GateModule.findCard("","")) { + if(GateModule.findCardV2(info.getLoginHandle(),"","").longValue() == 0) { return userFaceInfoList; } @@ -334,40 +352,31 @@ public class DaHua implements IHardwareEquipment { // 关闭查询接口 GateModule.findCardClose(); - this.logout(); + return userFaceInfoList; } public boolean clearAllPerson(){ - this.login(info.getIp(),info.getPort(),info.getUsername(),info.getPassword()); - if(GateModule.clearCard() && GateModule.clearFaceInfo()){ + if(GateModule.clearCardV2(this.info.getLoginHandle()) && GateModule.clearFaceInfoV2(this.info.getLoginHandle())){ return true; } - this.logout(); + return false; } // 登录 - public boolean login(String ip,short port,String username,String password) { - if(LoginModule.login(ip, - port, - username, - password)) { - // 登陆成功,将通道添加到控件 - } else { - return false; - } + public boolean login() { + NetSDKLib.LLong lLong = LoginModule.login2(info.getIp(),info.getPort(),info.getUsername(),info.getPassword()); + this.info.setLoginHandle(lLong); return true; } // 登出 public void logout() { - LoginModule.logout(); + LoginModule.logout2(info.getLoginHandle()); } - - private static class DisConnect implements NetSDKLib.fDisConnect { public void invoke(NetSDKLib.LLong m_hLoginHandle, String pchDVRIP, int nDVRPort, Pointer dwUser) { System.out.printf("Device[%s] Port[%d] DisConnect!\n", pchDVRIP, nDVRPort); diff --git a/src/main/java/com/yzx/impl/HardwareEquipmentInfo.java b/src/main/java/com/yzx/impl/HardwareEquipmentInfo.java index 41b6440..7e60ca0 100644 --- a/src/main/java/com/yzx/impl/HardwareEquipmentInfo.java +++ b/src/main/java/com/yzx/impl/HardwareEquipmentInfo.java @@ -1,5 +1,6 @@ package com.yzx.impl; +import com.netsdk.lib.NetSDKLib; import com.yzx.callback.AlarmCallback; import lombok.AllArgsConstructor; import lombok.Data; @@ -8,7 +9,6 @@ import lombok.Data; * 设备信息,包含ip,端口,用户名,密码等信息 */ @Data -@AllArgsConstructor public class HardwareEquipmentInfo { private String ip; private short port; @@ -16,4 +16,26 @@ public class HardwareEquipmentInfo { private String password; private AlarmCallback alarmCallback; + + private NetSDKLib.LLong loginHandle;//登录句柄 + private NetSDKLib.LLong findHandle;//查询句柄 + + + public HardwareEquipmentInfo(String ip, short port, String username, String password, AlarmCallback alarmCallback) { + this.ip = ip; + this.port = port; + this.username = username; + this.password = password; + this.alarmCallback = alarmCallback; + } + + public HardwareEquipmentInfo(String ip, short port, String username, String password, AlarmCallback alarmCallback, NetSDKLib.LLong loginHandle, NetSDKLib.LLong findHandle) { + this.ip = ip; + this.port = port; + this.username = username; + this.password = password; + this.alarmCallback = alarmCallback; + this.loginHandle = loginHandle; + this.findHandle = findHandle; + } }