Commit 25fca14e6224909811d96c348fc2427cf7fe13d1
1 parent
40ece192
修复WVP作为下级平台接受deviceControl指令的问题-修复指令响应
Showing
5 changed files
with
81 additions
and
72 deletions
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPSender.java
| ... | ... | @@ -47,61 +47,65 @@ public class SIPSender { |
| 47 | 47 | } |
| 48 | 48 | |
| 49 | 49 | public void transmitRequest(String ip, Message message, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws SipException, ParseException { |
| 50 | - ViaHeader viaHeader = (ViaHeader)message.getHeader(ViaHeader.NAME); | |
| 51 | - String transport = "UDP"; | |
| 52 | - if (viaHeader == null) { | |
| 53 | - logger.warn("[消息头缺失]: ViaHeader, 使用默认的UDP方式处理数据"); | |
| 54 | - }else { | |
| 55 | - transport = viaHeader.getTransport(); | |
| 56 | - } | |
| 57 | - if (message.getHeader(UserAgentHeader.NAME) == null) { | |
| 58 | - try { | |
| 59 | - message.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | |
| 60 | - } catch (ParseException e) { | |
| 61 | - logger.error("添加UserAgentHeader失败", e); | |
| 50 | + try { | |
| 51 | + ViaHeader viaHeader = (ViaHeader)message.getHeader(ViaHeader.NAME); | |
| 52 | + String transport = "UDP"; | |
| 53 | + if (viaHeader == null) { | |
| 54 | + logger.warn("[消息头缺失]: ViaHeader, 使用默认的UDP方式处理数据"); | |
| 55 | + }else { | |
| 56 | + transport = viaHeader.getTransport(); | |
| 57 | + } | |
| 58 | + if (message.getHeader(UserAgentHeader.NAME) == null) { | |
| 59 | + try { | |
| 60 | + message.addHeader(SipUtils.createUserAgentHeader(sipLayer.getSipFactory(), gitUtil)); | |
| 61 | + } catch (ParseException e) { | |
| 62 | + logger.error("添加UserAgentHeader失败", e); | |
| 63 | + } | |
| 62 | 64 | } |
| 63 | - } | |
| 64 | 65 | |
| 65 | - CallIdHeader callIdHeader = (CallIdHeader) message.getHeader(CallIdHeader.NAME); | |
| 66 | - // 添加错误订阅 | |
| 67 | - if (errorEvent != null) { | |
| 68 | - sipSubscribe.addErrorSubscribe(callIdHeader.getCallId(), (eventResult -> { | |
| 69 | - errorEvent.response(eventResult); | |
| 70 | - sipSubscribe.removeErrorSubscribe(eventResult.callId); | |
| 71 | - sipSubscribe.removeOkSubscribe(eventResult.callId); | |
| 72 | - })); | |
| 73 | - } | |
| 74 | - // 添加订阅 | |
| 75 | - if (okEvent != null) { | |
| 76 | - sipSubscribe.addOkSubscribe(callIdHeader.getCallId(), eventResult -> { | |
| 77 | - okEvent.response(eventResult); | |
| 78 | - sipSubscribe.removeOkSubscribe(eventResult.callId); | |
| 79 | - sipSubscribe.removeErrorSubscribe(eventResult.callId); | |
| 80 | - }); | |
| 81 | - } | |
| 82 | - if ("TCP".equals(transport)) { | |
| 83 | - SipProviderImpl tcpSipProvider = sipLayer.getTcpSipProvider(ip); | |
| 84 | - if (tcpSipProvider == null) { | |
| 85 | - logger.error("[发送信息失败] 未找到tcp://{}的监听信息", ip); | |
| 86 | - return; | |
| 66 | + CallIdHeader callIdHeader = (CallIdHeader) message.getHeader(CallIdHeader.NAME); | |
| 67 | + // 添加错误订阅 | |
| 68 | + if (errorEvent != null) { | |
| 69 | + sipSubscribe.addErrorSubscribe(callIdHeader.getCallId(), (eventResult -> { | |
| 70 | + errorEvent.response(eventResult); | |
| 71 | + sipSubscribe.removeErrorSubscribe(eventResult.callId); | |
| 72 | + sipSubscribe.removeOkSubscribe(eventResult.callId); | |
| 73 | + })); | |
| 87 | 74 | } |
| 88 | - if (message instanceof Request) { | |
| 89 | - tcpSipProvider.sendRequest((Request)message); | |
| 90 | - }else if (message instanceof Response) { | |
| 91 | - tcpSipProvider.sendResponse((Response)message); | |
| 75 | + // 添加订阅 | |
| 76 | + if (okEvent != null) { | |
| 77 | + sipSubscribe.addOkSubscribe(callIdHeader.getCallId(), eventResult -> { | |
| 78 | + okEvent.response(eventResult); | |
| 79 | + sipSubscribe.removeOkSubscribe(eventResult.callId); | |
| 80 | + sipSubscribe.removeErrorSubscribe(eventResult.callId); | |
| 81 | + }); | |
| 92 | 82 | } |
| 83 | + if ("TCP".equals(transport)) { | |
| 84 | + SipProviderImpl tcpSipProvider = sipLayer.getTcpSipProvider(ip); | |
| 85 | + if (tcpSipProvider == null) { | |
| 86 | + logger.error("[发送信息失败] 未找到tcp://{}的监听信息", ip); | |
| 87 | + return; | |
| 88 | + } | |
| 89 | + if (message instanceof Request) { | |
| 90 | + tcpSipProvider.sendRequest((Request)message); | |
| 91 | + }else if (message instanceof Response) { | |
| 92 | + tcpSipProvider.sendResponse((Response)message); | |
| 93 | + } | |
| 93 | 94 | |
| 94 | - } else if ("UDP".equals(transport)) { | |
| 95 | - SipProviderImpl sipProvider = sipLayer.getUdpSipProvider(ip); | |
| 96 | - if (sipProvider == null) { | |
| 97 | - logger.error("[发送信息失败] 未找到udp://{}的监听信息", ip); | |
| 98 | - return; | |
| 99 | - } | |
| 100 | - if (message instanceof Request) { | |
| 101 | - sipProvider.sendRequest((Request)message); | |
| 102 | - }else if (message instanceof Response) { | |
| 103 | - sipProvider.sendResponse((Response)message); | |
| 95 | + } else if ("UDP".equals(transport)) { | |
| 96 | + SipProviderImpl sipProvider = sipLayer.getUdpSipProvider(ip); | |
| 97 | + if (sipProvider == null) { | |
| 98 | + logger.error("[发送信息失败] 未找到udp://{}的监听信息", ip); | |
| 99 | + return; | |
| 100 | + } | |
| 101 | + if (message instanceof Request) { | |
| 102 | + sipProvider.sendRequest((Request)message); | |
| 103 | + }else if (message instanceof Response) { | |
| 104 | + sipProvider.sendResponse((Response)message); | |
| 105 | + } | |
| 104 | 106 | } |
| 107 | + } finally { | |
| 108 | + logger.info("[SEND]:SUCCESS:{}", message); | |
| 105 | 109 | } |
| 106 | 110 | } |
| 107 | 111 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
| ... | ... | @@ -183,7 +183,7 @@ public interface ISIPCommander { |
| 183 | 183 | * @param channelId 预览通道 |
| 184 | 184 | * @param recordCmdStr 录像命令:Record / StopRecord |
| 185 | 185 | */ |
| 186 | - void recordCmd(Device device, String channelId, String recordCmdStr, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; | |
| 186 | + void recordCmd(Device device, String channelId, String recordCmdStr, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException; | |
| 187 | 187 | |
| 188 | 188 | /** |
| 189 | 189 | * 远程启动控制命令 |
| ... | ... | @@ -197,7 +197,7 @@ public interface ISIPCommander { |
| 197 | 197 | * |
| 198 | 198 | * @param device 视频设备 |
| 199 | 199 | */ |
| 200 | - void guardCmd(Device device, String guardCmdStr, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; | |
| 200 | + void guardCmd(Device device, String guardCmdStr, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException; | |
| 201 | 201 | |
| 202 | 202 | /** |
| 203 | 203 | * 报警复位命令 |
| ... | ... | @@ -206,7 +206,7 @@ public interface ISIPCommander { |
| 206 | 206 | * @param alarmMethod 报警方式(可选) |
| 207 | 207 | * @param alarmType 报警类型(可选) |
| 208 | 208 | */ |
| 209 | - void alarmCmd(Device device, String alarmMethod, String alarmType, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException; | |
| 209 | + void alarmCmd(Device device, String alarmMethod, String alarmType, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException; | |
| 210 | 210 | |
| 211 | 211 | /** |
| 212 | 212 | * 强制关键帧命令,设备收到此命令应立刻发送一个IDR帧 | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
| ... | ... | @@ -664,7 +664,7 @@ public class SIPCommander implements ISIPCommander { |
| 664 | 664 | * @param recordCmdStr 录像命令:Record / StopRecord |
| 665 | 665 | */ |
| 666 | 666 | @Override |
| 667 | - public void recordCmd(Device device, String channelId, String recordCmdStr, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException { | |
| 667 | + public void recordCmd(Device device, String channelId, String recordCmdStr, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException { | |
| 668 | 668 | StringBuffer cmdXml = new StringBuffer(200); |
| 669 | 669 | String charset = device.getCharset(); |
| 670 | 670 | cmdXml.append("<?xml version=\"1.0\" encoding=\"" + charset + "\"?>\r\n"); |
| ... | ... | @@ -682,7 +682,7 @@ public class SIPCommander implements ISIPCommander { |
| 682 | 682 | |
| 683 | 683 | |
| 684 | 684 | Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); |
| 685 | - sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent); | |
| 685 | + sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent,okEvent); | |
| 686 | 686 | } |
| 687 | 687 | |
| 688 | 688 | /** |
| ... | ... | @@ -716,7 +716,7 @@ public class SIPCommander implements ISIPCommander { |
| 716 | 716 | * @param guardCmdStr "SetGuard"/"ResetGuard" |
| 717 | 717 | */ |
| 718 | 718 | @Override |
| 719 | - public void guardCmd(Device device, String guardCmdStr, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException { | |
| 719 | + public void guardCmd(Device device, String guardCmdStr, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException { | |
| 720 | 720 | |
| 721 | 721 | StringBuffer cmdXml = new StringBuffer(200); |
| 722 | 722 | String charset = device.getCharset(); |
| ... | ... | @@ -729,7 +729,7 @@ public class SIPCommander implements ISIPCommander { |
| 729 | 729 | cmdXml.append("</Control>\r\n"); |
| 730 | 730 | |
| 731 | 731 | Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); |
| 732 | - sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent); | |
| 732 | + sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent,okEvent); | |
| 733 | 733 | } |
| 734 | 734 | |
| 735 | 735 | /** |
| ... | ... | @@ -738,7 +738,7 @@ public class SIPCommander implements ISIPCommander { |
| 738 | 738 | * @param device 视频设备 |
| 739 | 739 | */ |
| 740 | 740 | @Override |
| 741 | - public void alarmCmd(Device device, String alarmMethod, String alarmType, SipSubscribe.Event errorEvent) throws InvalidArgumentException, SipException, ParseException { | |
| 741 | + public void alarmCmd(Device device, String alarmMethod, String alarmType, SipSubscribe.Event errorEvent, SipSubscribe.Event okEvent) throws InvalidArgumentException, SipException, ParseException { | |
| 742 | 742 | |
| 743 | 743 | StringBuffer cmdXml = new StringBuffer(200); |
| 744 | 744 | String charset = device.getCharset(); |
| ... | ... | @@ -765,7 +765,7 @@ public class SIPCommander implements ISIPCommander { |
| 765 | 765 | |
| 766 | 766 | |
| 767 | 767 | Request request = headerProvider.createMessageRequest(device, cmdXml.toString(), null, SipUtils.getNewFromTag(), null,sipSender.getNewCallIdHeader(sipLayer.getLocalIp(device.getLocalIp()),device.getTransport())); |
| 768 | - sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent); | |
| 768 | + sipSender.transmitRequest(sipLayer.getLocalIp(device.getLocalIp()), request, errorEvent,okEvent); | |
| 769 | 769 | } |
| 770 | 770 | |
| 771 | 771 | /** | ... | ... |
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/event/request/impl/message/control/cmd/DeviceControlQueryMessageHandler.java
| ... | ... | @@ -131,16 +131,16 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent |
| 131 | 131 | handleRecordCmd(deviceForPlatform,channelId,rootElement,request,DeviceControlType.RECORD); |
| 132 | 132 | break; |
| 133 | 133 | case I_FRAME: |
| 134 | - handleIFameCmd(deviceForPlatform,channelId); | |
| 134 | + handleIFameCmd(deviceForPlatform,request,channelId); | |
| 135 | 135 | break; |
| 136 | 136 | case TELE_BOOT: |
| 137 | - handleTeleBootCmd(deviceForPlatform); | |
| 137 | + handleTeleBootCmd(deviceForPlatform,request); | |
| 138 | 138 | break; |
| 139 | 139 | case DRAG_ZOOM_IN: |
| 140 | - handleDragZoom(deviceForPlatform,channelId,rootElement,DeviceControlType.DRAG_ZOOM_IN); | |
| 140 | + handleDragZoom(deviceForPlatform,channelId,rootElement,request,DeviceControlType.DRAG_ZOOM_IN); | |
| 141 | 141 | break; |
| 142 | 142 | case DRAG_ZOOM_OUT: |
| 143 | - handleDragZoom(deviceForPlatform,channelId,rootElement,DeviceControlType.DRAG_ZOOM_OUT); | |
| 143 | + handleDragZoom(deviceForPlatform,channelId,rootElement,request,DeviceControlType.DRAG_ZOOM_OUT); | |
| 144 | 144 | break; |
| 145 | 145 | case HOME_POSITION: |
| 146 | 146 | handleHomePositionCmd(deviceForPlatform,channelId,rootElement,request,DeviceControlType.HOME_POSITION); |
| ... | ... | @@ -167,7 +167,6 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent |
| 167 | 167 | } catch (InvalidArgumentException | SipException | ParseException e) { |
| 168 | 168 | logger.error("[命令发送失败] 云台/前端: {}", e.getMessage()); |
| 169 | 169 | } |
| 170 | - | |
| 171 | 170 | } |
| 172 | 171 | |
| 173 | 172 | /** |
| ... | ... | @@ -175,9 +174,10 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent |
| 175 | 174 | * @param device 设备 |
| 176 | 175 | * @param channelId 通道id |
| 177 | 176 | */ |
| 178 | - private void handleIFameCmd(Device device,String channelId){ | |
| 177 | + private void handleIFameCmd(Device device,SIPRequest request,String channelId){ | |
| 179 | 178 | try { |
| 180 | 179 | cmder.iFrameCmd(device,channelId); |
| 180 | + responseAck(request, Response.OK); | |
| 181 | 181 | } catch (InvalidArgumentException | SipException | ParseException e) { |
| 182 | 182 | logger.error("[命令发送失败] 强制关键帧: {}", e.getMessage()); |
| 183 | 183 | } |
| ... | ... | @@ -187,9 +187,10 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent |
| 187 | 187 | * 处理重启命令 |
| 188 | 188 | * @param device 设备信息 |
| 189 | 189 | */ |
| 190 | - private void handleTeleBootCmd(Device device){ | |
| 190 | + private void handleTeleBootCmd(Device device,SIPRequest request){ | |
| 191 | 191 | try { |
| 192 | 192 | cmder.teleBootCmd(device); |
| 193 | + responseAck(request, Response.OK); | |
| 193 | 194 | } catch (InvalidArgumentException | SipException | ParseException e) { |
| 194 | 195 | logger.error("[命令发送失败] 重启: {}", e.getMessage()); |
| 195 | 196 | } |
| ... | ... | @@ -203,7 +204,7 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent |
| 203 | 204 | * @param rootElement 根节点 |
| 204 | 205 | * @param type 消息类型 |
| 205 | 206 | */ |
| 206 | - private void handleDragZoom(Device device,String channelId,Element rootElement,DeviceControlType type){ | |
| 207 | + private void handleDragZoom(Device device,String channelId,Element rootElement,SIPRequest request,DeviceControlType type){ | |
| 207 | 208 | String cmdString = getText(rootElement,type.getVal()); |
| 208 | 209 | StringBuffer cmdXml = new StringBuffer(200); |
| 209 | 210 | cmdXml.append("<" + type.getVal() + ">\r\n"); |
| ... | ... | @@ -211,6 +212,7 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent |
| 211 | 212 | cmdXml.append("</" + type.getVal() + ">\r\n"); |
| 212 | 213 | try { |
| 213 | 214 | cmder.dragZoomCmd(device,channelId,cmdXml.toString()); |
| 215 | + responseAck(request, Response.OK); | |
| 214 | 216 | } catch (InvalidArgumentException | SipException | ParseException e) { |
| 215 | 217 | logger.error("[命令发送失败] 拉框控制: {}", e.getMessage()); |
| 216 | 218 | } |
| ... | ... | @@ -255,7 +257,8 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent |
| 255 | 257 | } |
| 256 | 258 | try { |
| 257 | 259 | cmder.alarmCmd(device, alarmMethod,alarmType, |
| 258 | - errorResult -> onError(request,errorResult)); | |
| 260 | + errorResult -> onError(request,errorResult), | |
| 261 | + okResult -> onOk(request,okResult)); | |
| 259 | 262 | } catch (InvalidArgumentException | SipException | ParseException e) { |
| 260 | 263 | logger.error("[命令发送失败] 告警消息: {}", e.getMessage()); |
| 261 | 264 | } |
| ... | ... | @@ -274,7 +277,8 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent |
| 274 | 277 | String cmdString = getText(rootElement,type.getVal()); |
| 275 | 278 | try { |
| 276 | 279 | cmder.recordCmd(device, channelId,cmdString, |
| 277 | - errorResult -> onError(request,errorResult)); | |
| 280 | + errorResult -> onError(request,errorResult), | |
| 281 | + okResult -> onOk(request,okResult)); | |
| 278 | 282 | } catch (InvalidArgumentException | SipException | ParseException e) { |
| 279 | 283 | logger.error("[命令发送失败] 录像控制: {}", e.getMessage()); |
| 280 | 284 | } |
| ... | ... | @@ -292,7 +296,8 @@ public class DeviceControlQueryMessageHandler extends SIPRequestProcessorParent |
| 292 | 296 | String cmdString = getText(rootElement,type.getVal()); |
| 293 | 297 | try { |
| 294 | 298 | cmder.guardCmd(device, cmdString, |
| 295 | - errorResult -> onError(request,errorResult)); | |
| 299 | + errorResult -> onError(request,errorResult), | |
| 300 | + okResult -> onOk(request,okResult)); | |
| 296 | 301 | } catch (InvalidArgumentException | SipException | ParseException e) { |
| 297 | 302 | logger.error("[命令发送失败] 布防/撤防命令: {}", e.getMessage()); |
| 298 | 303 | } | ... | ... |
src/main/java/com/genersoft/iot/vmp/vmanager/gb28181/device/DeviceControl.java
| ... | ... | @@ -110,7 +110,7 @@ public class DeviceControl { |
| 110 | 110 | msg.setKey(key); |
| 111 | 111 | msg.setData(String.format("开始/停止录像操作失败,错误码: %s, %s", event.statusCode, event.msg)); |
| 112 | 112 | resultHolder.invokeAllResult(msg); |
| 113 | - }); | |
| 113 | + },null); | |
| 114 | 114 | } catch (InvalidArgumentException | SipException | ParseException e) { |
| 115 | 115 | logger.error("[命令发送失败] 开始/停止录像: {}", e.getMessage()); |
| 116 | 116 | throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage()); |
| ... | ... | @@ -143,7 +143,7 @@ public class DeviceControl { |
| 143 | 143 | msg.setKey(key); |
| 144 | 144 | msg.setData(String.format("布防/撤防操作失败,错误码: %s, %s", event.statusCode, event.msg)); |
| 145 | 145 | resultHolder.invokeResult(msg); |
| 146 | - }); | |
| 146 | + },null); | |
| 147 | 147 | } catch (InvalidArgumentException | SipException | ParseException e) { |
| 148 | 148 | logger.error("[命令发送失败] 布防/撤防操作: {}", e.getMessage()); |
| 149 | 149 | throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送: " + e.getMessage()); |
| ... | ... | @@ -192,7 +192,7 @@ public class DeviceControl { |
| 192 | 192 | msg.setKey(key); |
| 193 | 193 | msg.setData(String.format("报警复位操作失败,错误码: %s, %s", event.statusCode, event.msg)); |
| 194 | 194 | resultHolder.invokeResult(msg); |
| 195 | - }); | |
| 195 | + },null); | |
| 196 | 196 | } catch (InvalidArgumentException | SipException | ParseException e) { |
| 197 | 197 | logger.error("[命令发送失败] 报警复位: {}", e.getMessage()); |
| 198 | 198 | throw new ControllerException(ErrorCode.ERROR100.getCode(), "命令发送失败: " + e.getMessage()); | ... | ... |