diff --git a/README.md b/README.md index 89120451..26d07287 100644 --- a/README.md +++ b/README.md @@ -60,21 +60,24 @@ https://gitee.com/18010473990/wvp-GB28181.git 15. 支持订阅与通知方法 - [X] 移动位置订阅 - [X] 移动位置通知处理 - - [ ] 报警事件订阅 + - [X] 报警事件订阅 - [X] 报警事件通知处理 - [ ] 设备目录订阅 - [X] 设备目录通知处理 16. 移动位置查询和显示,可通过配置文件设置移动位置历史是否存储 # 2.0 支持特性 -- [ ] 国标通道向上级联 +- [X] 国标通道向上级联 - [X] WEB添加上级平台 - [X] 注册 - [X] 心跳保活 - [X] 通道选择 - [X] 通道推送 - - [ ] 点播 - - [ ] 云台控制 + - [X] 点播 + - [X] 云台控制 + - [X] 平台状态查询 + - [X] 平台信息查询 + - [X] 平台远程启动 - [ ] 添加RTSP视频 - [ ] 添加ONVIF探测局域网内的设备 - [ ] 添加RTMP视频 diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java index 6fa4eca9..27000bb7 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java @@ -77,6 +77,14 @@ public interface ISIPCommander { */ boolean frontEndCmd(Device device, String channelId, int cmdCode, int parameter1, int parameter2, int combineCode2); + /** + * 前端控制指令(用于转发上级指令) + * @param device 控制设备 + * @param channelId 预览通道 + * @param cmdString 前端控制指令串 + */ + boolean fronEndCmd(Device device, String channelId, String cmdString); + /** * 请求预览视频流 * diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java index a9ace7be..e941a8ba 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java @@ -282,6 +282,36 @@ public class SIPCommander implements ISIPCommander { } /** + * 前端控制指令(用于转发上级指令) + * @param device 控制设备 + * @param channelId 预览通道 + * @param cmdString 前端控制指令串 + */ + @Override + public boolean fronEndCmd(Device device, String channelId, String cmdString) { + try { + StringBuffer ptzXml = new StringBuffer(200); + ptzXml.append("\r\n"); + ptzXml.append("\r\n"); + ptzXml.append("DeviceControl\r\n"); + ptzXml.append("" + (int)((Math.random()*9+1)*100000) + "\r\n"); + ptzXml.append("" + channelId + "\r\n"); + ptzXml.append("" + cmdString + "\r\n"); + ptzXml.append("\r\n"); + ptzXml.append("\r\n"); + ptzXml.append("\r\n"); + + String tm = Long.toString(System.currentTimeMillis()); + Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "z9hG4bK-ViaPtz-" + tm, "FromPtz" + tm, null); + transmitRequest(device, request); + return true; + } catch (SipException | ParseException | InvalidArgumentException e) { + e.printStackTrace(); + } + return false; + } + + /** * 请求预览视频流 * @param device 视频设备 * @param channelId 预览通道 diff --git a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java index 92835e58..e97629b8 100644 --- a/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java +++ b/src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java @@ -4,8 +4,11 @@ import java.io.ByteArrayInputStream; import java.text.ParseException; import java.util.*; +import javax.sip.address.SipURI; + import javax.sip.header.FromHeader; import javax.sip.header.HeaderAddress; +import javax.sip.header.ToHeader; import javax.sip.InvalidArgumentException; import javax.sip.ListeningPoint; import javax.sip.ObjectInUseException; @@ -290,38 +293,50 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { deferredResultHolder.invokeResult(msg); } else { // 此处是上级发出的DeviceControl指令 - if (XmlUtil.getText(rootElement, "TeleBoot").equals("Boot") ) { // 远程启动功能:需要在重新启动程序后先对SipStack解绑 - String platformId = ((SipUri) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); - logger.info("执行远程启动命令"); - ParentPlatform parentPlatform = storager.queryParentPlatById(platformId); - cmderFroPlatform.unregister(parentPlatform, null, null); - - Thread restartThread = new Thread(new Runnable() { - @Override - public void run() { - try { - Thread.sleep(3000); - SipProvider up = (SipProvider) SpringBeanFactory.getBean("udpSipProvider"); - SipStackImpl stack = (SipStackImpl)up.getSipStack(); - stack.stop(); - Iterator listener = stack.getListeningPoints(); - while (listener.hasNext()) { - stack.deleteListeningPoint((ListeningPoint) listener.next()); + String platformId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(FromHeader.NAME)).getAddress().getURI()).getUser(); + String targetGBId = ((SipURI) ((HeaderAddress) evt.getRequest().getHeader(ToHeader.NAME)).getAddress().getURI()).getUser(); + // 远程启动功能 + if (!XmlUtil.isEmpty(XmlUtil.getText(rootElement, "TeleBoot"))) { + if (deviceId.equals(targetGBId)) { + // 远程启动功能:需要在重新启动程序后先对SipStack解绑 + logger.info("执行远程启动本平台命令"); + ParentPlatform parentPlatform = storager.queryParentPlatById(platformId); + cmderFroPlatform.unregister(parentPlatform, null, null); + + Thread restartThread = new Thread(new Runnable() { + @Override + public void run() { + try { + Thread.sleep(3000); + SipProvider up = (SipProvider) SpringBeanFactory.getBean("udpSipProvider"); + SipStackImpl stack = (SipStackImpl)up.getSipStack(); + stack.stop(); + Iterator listener = stack.getListeningPoints(); + while (listener.hasNext()) { + stack.deleteListeningPoint((ListeningPoint) listener.next()); + } + Iterator providers = stack.getSipProviders(); + while (providers.hasNext()) { + stack.deleteSipProvider((SipProvider) providers.next()); + } + VManageBootstrap.restart(); + } catch (InterruptedException ignored) { + } catch (ObjectInUseException e) { + e.printStackTrace(); } - Iterator providers = stack.getSipProviders(); - while (providers.hasNext()) { - stack.deleteSipProvider((SipProvider) providers.next()); - } - VManageBootstrap.restart(); - } catch (InterruptedException ignored) { - } catch (ObjectInUseException e) { - e.printStackTrace(); } - } - }); - - restartThread.setDaemon(false); - restartThread.start(); + }); + + restartThread.setDaemon(false); + restartThread.start(); + } else { + // 远程启动指定设备 + } + } + if (!XmlUtil.isEmpty(XmlUtil.getText(rootElement,"PTZCmd")) && !deviceId.equals(targetGBId)) { + String cmdString = XmlUtil.getText(rootElement,"PTZCmd"); + Device device = storager.queryVideoDeviceByPlatformIdAndChannelId(platformId, deviceId); + cmder.fronEndCmd(device, deviceId, cmdString); } } } catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {