Commit 6c4da7bebe8040f1d8dea551863eae7bbd4c65a6

Authored by panlinlin
1 parent ccc188c1

完成向上级联->通道推送

修复选择通道是查询的bug
README.md
@@ -41,7 +41,7 @@ https://gitee.com/18010473990/wvp-GB28181.git @@ -41,7 +41,7 @@ https://gitee.com/18010473990/wvp-GB28181.git
41 - [X] 注册 41 - [X] 注册
42 - [X] 心跳保活 42 - [X] 心跳保活
43 - [X] 通道选择 43 - [X] 通道选择
44 - - [ ] 通道推送 44 + - [X] 通道推送
45 - [ ] 点播 45 - [ ] 点播
46 - [ ] 云台控制 46 - [ ] 云台控制
47 - [ ] 添加RTSP视频 47 - [ ] 添加RTSP视频
src/main/java/com/genersoft/iot/vmp/gb28181/bean/ParentPlatform.java
@@ -94,6 +94,11 @@ public class ParentPlatform { @@ -94,6 +94,11 @@ public class ParentPlatform {
94 */ 94 */
95 private boolean status; 95 private boolean status;
96 96
  97 + /**
  98 + * 在线状态
  99 + */
  100 + private int channelCount;
  101 +
97 102
98 public boolean isEnable() { 103 public boolean isEnable() {
99 return enable; 104 return enable;
@@ -238,4 +243,12 @@ public class ParentPlatform { @@ -238,4 +243,12 @@ public class ParentPlatform {
238 public void setStatus(boolean status) { 243 public void setStatus(boolean status) {
239 this.status = status; 244 this.status = status;
240 } 245 }
  246 +
  247 + public int getChannelCount() {
  248 + return channelCount;
  249 + }
  250 +
  251 + public void setChannelCount(int channelCount) {
  252 + this.channelCount = channelCount;
  253 + }
241 } 254 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
@@ -9,6 +9,7 @@ import javax.sip.header.Header; @@ -9,6 +9,7 @@ import javax.sip.header.Header;
9 import javax.sip.message.Request; 9 import javax.sip.message.Request;
10 import javax.sip.message.Response; 10 import javax.sip.message.Response;
11 11
  12 +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
12 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 13 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
13 import com.alibaba.fastjson.JSON; 14 import com.alibaba.fastjson.JSON;
14 import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*; 15 import com.genersoft.iot.vmp.gb28181.transmit.response.impl.*;
@@ -72,6 +73,9 @@ public class SIPProcessorFactory { @@ -72,6 +73,9 @@ public class SIPProcessorFactory {
72 73
73 @Autowired 74 @Autowired
74 private SIPCommander cmder; 75 private SIPCommander cmder;
  76 +
  77 + @Autowired
  78 + private SIPCommanderFroPlatform cmderFroPlatform;
75 79
76 @Autowired 80 @Autowired
77 private RedisUtil redis; 81 private RedisUtil redis;
@@ -153,6 +157,7 @@ public class SIPProcessorFactory { @@ -153,6 +157,7 @@ public class SIPProcessorFactory {
153 processor.setDeferredResultHolder(deferredResultHolder); 157 processor.setDeferredResultHolder(deferredResultHolder);
154 processor.setOffLineDetector(offLineDetector); 158 processor.setOffLineDetector(offLineDetector);
155 processor.setCmder(cmder); 159 processor.setCmder(cmder);
  160 + processor.setCmderFroPlatform(cmderFroPlatform);
156 processor.setStorager(storager); 161 processor.setStorager(storager);
157 processor.setRedisCatchStorage(redisCatchStorage); 162 processor.setRedisCatchStorage(redisCatchStorage);
158 return processor; 163 return processor;
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommanderForPlatform.java
1 package com.genersoft.iot.vmp.gb28181.transmit.cmd; 1 package com.genersoft.iot.vmp.gb28181.transmit.cmd;
2 2
  3 +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
3 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 4 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
4 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; 5 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
5 6
6 import javax.sip.header.WWWAuthenticateHeader; 7 import javax.sip.header.WWWAuthenticateHeader;
  8 +import java.nio.channels.Channel;
  9 +import java.util.List;
7 10
8 public interface ISIPCommanderForPlatform { 11 public interface ISIPCommanderForPlatform {
9 12
@@ -29,4 +32,16 @@ public interface ISIPCommanderForPlatform { @@ -29,4 +32,16 @@ public interface ISIPCommanderForPlatform {
29 * @return callId(作为接受回复的判定) 32 * @return callId(作为接受回复的判定)
30 */ 33 */
31 String keepalive(ParentPlatform parentPlatform); 34 String keepalive(ParentPlatform parentPlatform);
  35 +
  36 +
  37 + /**
  38 + * 向上级回复通道信息
  39 + * @param channel 通道信息
  40 + * @param parentPlatform 平台信息
  41 + * @param sn
  42 + * @param fromTag
  43 + * @param size
  44 + * @return
  45 + */
  46 + boolean catalogQuery(DeviceChannel channel, ParentPlatform parentPlatform, String sn, String fromTag, int size);
32 } 47 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderPlarformProvider.java
@@ -4,22 +4,22 @@ import com.genersoft.iot.vmp.conf.SipConfig; @@ -4,22 +4,22 @@ import com.genersoft.iot.vmp.conf.SipConfig;
4 import com.genersoft.iot.vmp.gb28181.bean.Device; 4 import com.genersoft.iot.vmp.gb28181.bean.Device;
5 import com.genersoft.iot.vmp.gb28181.bean.Host; 5 import com.genersoft.iot.vmp.gb28181.bean.Host;
6 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 6 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
  7 +import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
7 import org.springframework.beans.factory.annotation.Autowired; 8 import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.beans.factory.annotation.Qualifier; 9 import org.springframework.beans.factory.annotation.Qualifier;
9 import org.springframework.stereotype.Component; 10 import org.springframework.stereotype.Component;
10 import org.springframework.util.DigestUtils; 11 import org.springframework.util.DigestUtils;
11 12
12 -import javax.sip.InvalidArgumentException;  
13 -import javax.sip.PeerUnavailableException;  
14 -import javax.sip.SipFactory;  
15 -import javax.sip.SipProvider; 13 +import javax.sip.*;
16 import javax.sip.address.Address; 14 import javax.sip.address.Address;
17 import javax.sip.address.SipURI; 15 import javax.sip.address.SipURI;
18 import javax.sip.header.*; 16 import javax.sip.header.*;
19 import javax.sip.message.Request; 17 import javax.sip.message.Request;
20 import javax.validation.constraints.NotNull; 18 import javax.validation.constraints.NotNull;
  19 +import java.nio.channels.Channel;
21 import java.text.ParseException; 20 import java.text.ParseException;
22 import java.util.ArrayList; 21 import java.util.ArrayList;
  22 +import java.util.List;
23 import java.util.UUID; 23 import java.util.UUID;
24 24
25 /** 25 /**
@@ -193,4 +193,38 @@ public class SIPRequestHeaderPlarformProvider { @@ -193,4 +193,38 @@ public class SIPRequestHeaderPlarformProvider {
193 return registerRequest; 193 return registerRequest;
194 } 194 }
195 195
  196 +
  197 + public Request createMessageRequest(ParentPlatform parentPlatform, String content, String fromTag) throws PeerUnavailableException, ParseException, InvalidArgumentException {
  198 + Request request = null;
  199 + // sipuri
  200 + SipURI requestURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(), parentPlatform.getServerIP()+ ":" + parentPlatform.getServerPort());
  201 + // via
  202 + ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
  203 + ViaHeader viaHeader = sipFactory.createHeaderFactory().createViaHeader(parentPlatform.getDeviceIp(), Integer.parseInt(parentPlatform.getDevicePort()),
  204 + parentPlatform.getTransport(), null);
  205 + viaHeader.setRPort();
  206 + viaHeaders.add(viaHeader);
  207 + // from
  208 + SipURI fromSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getServerGBId(),
  209 + parentPlatform.getDeviceIp() + ":" + parentPlatform.getDevicePort());
  210 + Address fromAddress = sipFactory.createAddressFactory().createAddress(fromSipURI);
  211 + FromHeader fromHeader = sipFactory.createHeaderFactory().createFromHeader(fromAddress, fromTag);
  212 + // to
  213 + SipURI toSipURI = sipFactory.createAddressFactory().createSipURI(parentPlatform.getDeviceGBId(), parentPlatform.getServerGBDomain());
  214 + Address toAddress = sipFactory.createAddressFactory().createAddress(toSipURI);
  215 + ToHeader toHeader = sipFactory.createHeaderFactory().createToHeader(toAddress, null);
  216 + // callid
  217 + CallIdHeader callIdHeader = parentPlatform.getTransport().equals("TCP") ? tcpSipProvider.getNewCallId()
  218 + : udpSipProvider.getNewCallId();
  219 + // Forwards
  220 + MaxForwardsHeader maxForwards = sipFactory.createHeaderFactory().createMaxForwardsHeader(70);
  221 + // ceq
  222 + CSeqHeader cSeqHeader = sipFactory.createHeaderFactory().createCSeqHeader(1L, Request.MESSAGE);
  223 +
  224 + request = sipFactory.createMessageFactory().createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader,
  225 + toHeader, viaHeaders, maxForwards);
  226 + ContentTypeHeader contentTypeHeader = sipFactory.createHeaderFactory().createContentTypeHeader("APPLICATION", "MANSCDP+xml");
  227 + request.setContent(content, contentTypeHeader);
  228 + return request;
  229 + }
196 } 230 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommanderFroPlatform.java
@@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl; @@ -2,6 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl;
2 2
3 import com.genersoft.iot.vmp.conf.SipConfig; 3 import com.genersoft.iot.vmp.conf.SipConfig;
4 import com.genersoft.iot.vmp.gb28181.bean.Device; 4 import com.genersoft.iot.vmp.gb28181.bean.Device;
  5 +import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
5 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform; 6 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatform;
6 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch; 7 import com.genersoft.iot.vmp.gb28181.bean.ParentPlatformCatch;
7 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe; 8 import com.genersoft.iot.vmp.gb28181.event.SipSubscribe;
@@ -21,7 +22,9 @@ import javax.sip.*; @@ -21,7 +22,9 @@ import javax.sip.*;
21 import javax.sip.header.CallIdHeader; 22 import javax.sip.header.CallIdHeader;
22 import javax.sip.header.WWWAuthenticateHeader; 23 import javax.sip.header.WWWAuthenticateHeader;
23 import javax.sip.message.Request; 24 import javax.sip.message.Request;
  25 +import java.nio.channels.Channel;
24 import java.text.ParseException; 26 import java.text.ParseException;
  27 +import java.util.List;
25 import java.util.UUID; 28 import java.util.UUID;
26 29
27 @Component 30 @Component
@@ -156,4 +159,54 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform { @@ -156,4 +159,54 @@ public class SIPCommanderFroPlatform implements ISIPCommanderForPlatform {
156 } 159 }
157 160
158 } 161 }
  162 +
  163 + /**
  164 + * 向上级回复通道信息
  165 + * @param channel 通道信息
  166 + * @param parentPlatform 平台信息
  167 + * @return
  168 + */
  169 + @Override
  170 + public boolean catalogQuery(DeviceChannel channel, ParentPlatform parentPlatform, String sn, String fromTag, int size) {
  171 +
  172 + if (channel == null || parentPlatform ==null) {
  173 + return false;
  174 + }
  175 + try {
  176 + StringBuffer catalogXml = new StringBuffer(600);
  177 + catalogXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n");
  178 + catalogXml.append("<Response>\r\n");
  179 + catalogXml.append("<CmdType>Catalog</CmdType>\r\n");
  180 + catalogXml.append("<SN>" +sn + "</SN>\r\n");
  181 + catalogXml.append("<DeviceID>" + parentPlatform.getDeviceGBId() + "</DeviceID>\r\n");
  182 + catalogXml.append("<SumNum>" + size + "</SumNum>\r\n");
  183 + catalogXml.append("<DeviceList Num=\"1\">\r\n");
  184 + catalogXml.append("<Item>\r\n");
  185 +
  186 + catalogXml.append("<DeviceID>" + channel.getChannelId() + "</DeviceID>\r\n");
  187 + catalogXml.append("<Name>" + channel.getName() + "</Name>\r\n");
  188 + catalogXml.append("<Manufacturer>" + channel.getManufacture() + "</Manufacturer>\r\n");
  189 + catalogXml.append("<Model>" + channel.getModel() + "</Model>\r\n");
  190 + catalogXml.append("<Owner>" + channel.getOwner() + "</Owner>\r\n");
  191 + catalogXml.append("<CivilCode>" + channel.getCivilCode() + "</CivilCode>\r\n");
  192 + catalogXml.append("<Address>" + channel.getAddress() + "</Address>\r\n");
  193 + catalogXml.append("<Parental>" + channel.getParental() + "</Parental>\r\n");// TODO 当前不能添加分组, 所以暂时没有父节点
  194 + catalogXml.append("<ParentID>" + channel.getParentId() + "</ParentID>\r\n"); // TODO 当前不能添加分组, 所以暂时没有父节点
  195 + catalogXml.append("<Secrecy>" + channel.getSecrecy() + "</Secrecy>\r\n");
  196 + catalogXml.append("<RegisterWay>" + channel.getRegisterWay() + "</RegisterWay>\r\n");
  197 + catalogXml.append("<Status>" + (channel.getStatus() == 0?"OFF":"ON") + "</Status>\r\n");
  198 + catalogXml.append("<Info></Info>\r\n");
  199 +
  200 + catalogXml.append("</Item>\r\n");
  201 + catalogXml.append("</DeviceList>\r\n");
  202 + catalogXml.append("</Response>\r\n");
  203 + Request request = headerProviderPlarformProvider.createMessageRequest(parentPlatform, catalogXml.toString(), fromTag);
  204 + transmitRequest(parentPlatform, request);
  205 +
  206 + } catch (SipException | ParseException | InvalidArgumentException e) {
  207 + e.printStackTrace();
  208 + return false;
  209 + }
  210 + return true;
  211 + }
159 } 212 }
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
@@ -7,10 +7,14 @@ import java.util.*; @@ -7,10 +7,14 @@ import java.util.*;
7 import javax.sip.InvalidArgumentException; 7 import javax.sip.InvalidArgumentException;
8 import javax.sip.RequestEvent; 8 import javax.sip.RequestEvent;
9 import javax.sip.SipException; 9 import javax.sip.SipException;
  10 +import javax.sip.header.FromHeader;
10 import javax.sip.message.Request; 11 import javax.sip.message.Request;
11 import javax.sip.message.Response; 12 import javax.sip.message.Response;
12 13
  14 +import com.genersoft.iot.vmp.gb28181.bean.*;
  15 +import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommanderFroPlatform;
13 import com.genersoft.iot.vmp.storager.IRedisCatchStorage; 16 import com.genersoft.iot.vmp.storager.IRedisCatchStorage;
  17 +import com.genersoft.iot.vmp.vmanager.platform.bean.ChannelReduce;
14 import org.dom4j.Document; 18 import org.dom4j.Document;
15 import org.dom4j.DocumentException; 19 import org.dom4j.DocumentException;
16 import org.dom4j.Element; 20 import org.dom4j.Element;
@@ -20,10 +24,6 @@ import org.slf4j.LoggerFactory; @@ -20,10 +24,6 @@ import org.slf4j.LoggerFactory;
20 import org.springframework.beans.factory.annotation.Autowired; 24 import org.springframework.beans.factory.annotation.Autowired;
21 25
22 import com.genersoft.iot.vmp.common.VideoManagerConstants; 26 import com.genersoft.iot.vmp.common.VideoManagerConstants;
23 -import com.genersoft.iot.vmp.gb28181.bean.Device;  
24 -import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;  
25 -import com.genersoft.iot.vmp.gb28181.bean.RecordInfo;  
26 -import com.genersoft.iot.vmp.gb28181.bean.RecordItem;  
27 import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector; 27 import com.genersoft.iot.vmp.gb28181.event.DeviceOffLineDetector;
28 import com.genersoft.iot.vmp.gb28181.event.EventPublisher; 28 import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
29 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder; 29 import com.genersoft.iot.vmp.gb28181.transmit.callback.DeferredResultHolder;
@@ -47,6 +47,8 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { @@ -47,6 +47,8 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
47 47
48 private SIPCommander cmder; 48 private SIPCommander cmder;
49 49
  50 + private SIPCommanderFroPlatform cmderFroPlatform;
  51 +
50 private IVideoManagerStorager storager; 52 private IVideoManagerStorager storager;
51 53
52 private IRedisCatchStorage redisCatchStorage; 54 private IRedisCatchStorage redisCatchStorage;
@@ -163,110 +165,135 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { @@ -163,110 +165,135 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
163 Element deviceIdElement = rootElement.element("DeviceID"); 165 Element deviceIdElement = rootElement.element("DeviceID");
164 String deviceId = deviceIdElement.getText(); 166 String deviceId = deviceIdElement.getText();
165 Element deviceListElement = rootElement.element("DeviceList"); 167 Element deviceListElement = rootElement.element("DeviceList");
166 - if (deviceListElement == null) {  
167 - return;  
168 - }  
169 - Iterator<Element> deviceListIterator = deviceListElement.elementIterator();  
170 - if (deviceListIterator != null) {  
171 - Device device = storager.queryVideoDevice(deviceId);  
172 - if (device == null) { 168 + if (deviceListElement == null) { // 存在DeviceList则为响应 catalog, 不存在DeviceList则为查询请求
  169 + // TODO 后续将代码拆分
  170 + ParentPlatform parentPlatform = storager.queryParentPlatById(deviceId);
  171 + if (parentPlatform == null) {
  172 + response404Ack(evt);
173 return; 173 return;
174 - }  
175 - // 遍历DeviceList  
176 - while (deviceListIterator.hasNext()) {  
177 - Element itemDevice = deviceListIterator.next();  
178 - Element channelDeviceElement = itemDevice.element("DeviceID");  
179 - if (channelDeviceElement == null) {  
180 - continue;  
181 - }  
182 - String channelDeviceId = channelDeviceElement.getText();  
183 - Element channdelNameElement = itemDevice.element("Name");  
184 - String channelName = channdelNameElement != null ? channdelNameElement.getTextTrim().toString() : "";  
185 - Element statusElement = itemDevice.element("Status");  
186 - String status = statusElement != null ? statusElement.getText().toString() : "ON";  
187 - DeviceChannel deviceChannel = new DeviceChannel();  
188 - deviceChannel.setName(channelName);  
189 - deviceChannel.setChannelId(channelDeviceId);  
190 - // ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理  
191 - if (status.equals("ON") || status.equals("On") || status.equals("ONLINE")) {  
192 - deviceChannel.setStatus(1);  
193 - }  
194 - if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) {  
195 - deviceChannel.setStatus(0); 174 + }else {
  175 + // 回复200 OK
  176 + responseAck(evt);
  177 +
  178 + Element snElement = rootElement.element("SN");
  179 + String sn = snElement.getText();
  180 + FromHeader fromHeader = (FromHeader)evt.getRequest().getHeader(FromHeader.NAME);
  181 + // 准备回复通道信息
  182 + List<ChannelReduce> channelReduces = storager.queryChannelListInParentPlatform(parentPlatform.getDeviceGBId());
  183 + if (channelReduces.size() >0 ) {
  184 + for (ChannelReduce channelReduce : channelReduces) {
  185 + DeviceChannel deviceChannel = storager.queryChannel(channelReduce.getDeviceId(), channelReduce.getChannelId());
  186 + cmderFroPlatform.catalogQuery(deviceChannel, parentPlatform, sn, fromHeader.getTag(), channelReduces.size());
  187 + }
196 } 188 }
197 189
198 - deviceChannel.setManufacture(XmlUtil.getText(itemDevice, "Manufacturer"));  
199 - deviceChannel.setModel(XmlUtil.getText(itemDevice, "Model"));  
200 - deviceChannel.setOwner(XmlUtil.getText(itemDevice, "Owner"));  
201 - deviceChannel.setCivilCode(XmlUtil.getText(itemDevice, "CivilCode"));  
202 - deviceChannel.setBlock(XmlUtil.getText(itemDevice, "Block"));  
203 - deviceChannel.setAddress(XmlUtil.getText(itemDevice, "Address"));  
204 - if (XmlUtil.getText(itemDevice, "Parental") == null || XmlUtil.getText(itemDevice, "Parental") == "") {  
205 - deviceChannel.setParental(0);  
206 - } else {  
207 - deviceChannel.setParental(Integer.parseInt(XmlUtil.getText(itemDevice, "Parental")));  
208 - }  
209 - deviceChannel.setParentId(XmlUtil.getText(itemDevice, "ParentID"));  
210 - if (XmlUtil.getText(itemDevice, "SafetyWay") == null || XmlUtil.getText(itemDevice, "SafetyWay")== "") {  
211 - deviceChannel.setSafetyWay(0);  
212 - } else {  
213 - deviceChannel.setSafetyWay(Integer.parseInt(XmlUtil.getText(itemDevice, "SafetyWay")));  
214 - }  
215 - if (XmlUtil.getText(itemDevice, "RegisterWay") == null || XmlUtil.getText(itemDevice, "RegisterWay") =="") {  
216 - deviceChannel.setRegisterWay(1);  
217 - } else {  
218 - deviceChannel.setRegisterWay(Integer.parseInt(XmlUtil.getText(itemDevice, "RegisterWay")));  
219 - }  
220 - deviceChannel.setCertNum(XmlUtil.getText(itemDevice, "CertNum"));  
221 - if (XmlUtil.getText(itemDevice, "Certifiable") == null || XmlUtil.getText(itemDevice, "Certifiable") == "") {  
222 - deviceChannel.setCertifiable(0);  
223 - } else {  
224 - deviceChannel.setCertifiable(Integer.parseInt(XmlUtil.getText(itemDevice, "Certifiable")));  
225 - }  
226 - if (XmlUtil.getText(itemDevice, "ErrCode") == null || XmlUtil.getText(itemDevice, "ErrCode") == "") {  
227 - deviceChannel.setErrCode(0);  
228 - } else {  
229 - deviceChannel.setErrCode(Integer.parseInt(XmlUtil.getText(itemDevice, "ErrCode")));  
230 - }  
231 - deviceChannel.setEndTime(XmlUtil.getText(itemDevice, "EndTime"));  
232 - deviceChannel.setSecrecy(XmlUtil.getText(itemDevice, "Secrecy"));  
233 - deviceChannel.setIpAddress(XmlUtil.getText(itemDevice, "IPAddress"));  
234 - if (XmlUtil.getText(itemDevice, "Port") == null || XmlUtil.getText(itemDevice, "Port") =="") {  
235 - deviceChannel.setPort(0);  
236 - } else {  
237 - deviceChannel.setPort(Integer.parseInt(XmlUtil.getText(itemDevice, "Port")));  
238 - }  
239 - deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password"));  
240 - if (XmlUtil.getText(itemDevice, "Longitude") == null || XmlUtil.getText(itemDevice, "Longitude") == "") {  
241 - deviceChannel.setLongitude(0.00);  
242 - } else {  
243 - deviceChannel.setLongitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Longitude")));  
244 - }  
245 - if (XmlUtil.getText(itemDevice, "Latitude") == null || XmlUtil.getText(itemDevice, "Latitude") =="") {  
246 - deviceChannel.setLatitude(0.00);  
247 - } else {  
248 - deviceChannel.setLatitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Latitude"))); 190 + }
  191 +
  192 +
  193 + }else {
  194 + Iterator<Element> deviceListIterator = deviceListElement.elementIterator();
  195 + if (deviceListIterator != null) {
  196 + Device device = storager.queryVideoDevice(deviceId);
  197 + if (device == null) {
  198 + return;
249 } 199 }
250 - if (XmlUtil.getText(itemDevice, "PTZType") == null || XmlUtil.getText(itemDevice, "PTZType") == "") {  
251 - deviceChannel.setPTZType(0);  
252 - } else {  
253 - deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType"))); 200 + // 遍历DeviceList
  201 + while (deviceListIterator.hasNext()) {
  202 + Element itemDevice = deviceListIterator.next();
  203 + Element channelDeviceElement = itemDevice.element("DeviceID");
  204 + if (channelDeviceElement == null) {
  205 + continue;
  206 + }
  207 + String channelDeviceId = channelDeviceElement.getText();
  208 + Element channdelNameElement = itemDevice.element("Name");
  209 + String channelName = channdelNameElement != null ? channdelNameElement.getTextTrim().toString() : "";
  210 + Element statusElement = itemDevice.element("Status");
  211 + String status = statusElement != null ? statusElement.getText().toString() : "ON";
  212 + DeviceChannel deviceChannel = new DeviceChannel();
  213 + deviceChannel.setName(channelName);
  214 + deviceChannel.setChannelId(channelDeviceId);
  215 + // ONLINE OFFLINE HIKVISION DS-7716N-E4 NVR的兼容性处理
  216 + if (status.equals("ON") || status.equals("On") || status.equals("ONLINE")) {
  217 + deviceChannel.setStatus(1);
  218 + }
  219 + if (status.equals("OFF") || status.equals("Off") || status.equals("OFFLINE")) {
  220 + deviceChannel.setStatus(0);
  221 + }
  222 +
  223 + deviceChannel.setManufacture(XmlUtil.getText(itemDevice, "Manufacturer"));
  224 + deviceChannel.setModel(XmlUtil.getText(itemDevice, "Model"));
  225 + deviceChannel.setOwner(XmlUtil.getText(itemDevice, "Owner"));
  226 + deviceChannel.setCivilCode(XmlUtil.getText(itemDevice, "CivilCode"));
  227 + deviceChannel.setBlock(XmlUtil.getText(itemDevice, "Block"));
  228 + deviceChannel.setAddress(XmlUtil.getText(itemDevice, "Address"));
  229 + if (XmlUtil.getText(itemDevice, "Parental") == null || XmlUtil.getText(itemDevice, "Parental") == "") {
  230 + deviceChannel.setParental(0);
  231 + } else {
  232 + deviceChannel.setParental(Integer.parseInt(XmlUtil.getText(itemDevice, "Parental")));
  233 + }
  234 + deviceChannel.setParentId(XmlUtil.getText(itemDevice, "ParentID"));
  235 + if (XmlUtil.getText(itemDevice, "SafetyWay") == null || XmlUtil.getText(itemDevice, "SafetyWay")== "") {
  236 + deviceChannel.setSafetyWay(0);
  237 + } else {
  238 + deviceChannel.setSafetyWay(Integer.parseInt(XmlUtil.getText(itemDevice, "SafetyWay")));
  239 + }
  240 + if (XmlUtil.getText(itemDevice, "RegisterWay") == null || XmlUtil.getText(itemDevice, "RegisterWay") =="") {
  241 + deviceChannel.setRegisterWay(1);
  242 + } else {
  243 + deviceChannel.setRegisterWay(Integer.parseInt(XmlUtil.getText(itemDevice, "RegisterWay")));
  244 + }
  245 + deviceChannel.setCertNum(XmlUtil.getText(itemDevice, "CertNum"));
  246 + if (XmlUtil.getText(itemDevice, "Certifiable") == null || XmlUtil.getText(itemDevice, "Certifiable") == "") {
  247 + deviceChannel.setCertifiable(0);
  248 + } else {
  249 + deviceChannel.setCertifiable(Integer.parseInt(XmlUtil.getText(itemDevice, "Certifiable")));
  250 + }
  251 + if (XmlUtil.getText(itemDevice, "ErrCode") == null || XmlUtil.getText(itemDevice, "ErrCode") == "") {
  252 + deviceChannel.setErrCode(0);
  253 + } else {
  254 + deviceChannel.setErrCode(Integer.parseInt(XmlUtil.getText(itemDevice, "ErrCode")));
  255 + }
  256 + deviceChannel.setEndTime(XmlUtil.getText(itemDevice, "EndTime"));
  257 + deviceChannel.setSecrecy(XmlUtil.getText(itemDevice, "Secrecy"));
  258 + deviceChannel.setIpAddress(XmlUtil.getText(itemDevice, "IPAddress"));
  259 + if (XmlUtil.getText(itemDevice, "Port") == null || XmlUtil.getText(itemDevice, "Port") =="") {
  260 + deviceChannel.setPort(0);
  261 + } else {
  262 + deviceChannel.setPort(Integer.parseInt(XmlUtil.getText(itemDevice, "Port")));
  263 + }
  264 + deviceChannel.setPassword(XmlUtil.getText(itemDevice, "Password"));
  265 + if (XmlUtil.getText(itemDevice, "Longitude") == null || XmlUtil.getText(itemDevice, "Longitude") == "") {
  266 + deviceChannel.setLongitude(0.00);
  267 + } else {
  268 + deviceChannel.setLongitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Longitude")));
  269 + }
  270 + if (XmlUtil.getText(itemDevice, "Latitude") == null || XmlUtil.getText(itemDevice, "Latitude") =="") {
  271 + deviceChannel.setLatitude(0.00);
  272 + } else {
  273 + deviceChannel.setLatitude(Double.parseDouble(XmlUtil.getText(itemDevice, "Latitude")));
  274 + }
  275 + if (XmlUtil.getText(itemDevice, "PTZType") == null || XmlUtil.getText(itemDevice, "PTZType") == "") {
  276 + deviceChannel.setPTZType(0);
  277 + } else {
  278 + deviceChannel.setPTZType(Integer.parseInt(XmlUtil.getText(itemDevice, "PTZType")));
  279 + }
  280 + deviceChannel.setHasAudio(true); // 默认含有音频,播放时再检查是否有音频及是否AAC
  281 + storager.updateChannel(device.getDeviceId(), deviceChannel);
254 } 282 }
255 - deviceChannel.setHasAudio(true); // 默认含有音频,播放时再检查是否有音频及是否AAC  
256 - storager.updateChannel(device.getDeviceId(), deviceChannel);  
257 - }  
258 283
259 - RequestMessage msg = new RequestMessage();  
260 - msg.setDeviceId(deviceId);  
261 - msg.setType(DeferredResultHolder.CALLBACK_CMD_CATALOG);  
262 - msg.setData(device);  
263 - deferredResultHolder.invokeResult(msg);  
264 - // 回复200 OK  
265 - responseAck(evt);  
266 - if (offLineDetector.isOnline(deviceId)) {  
267 - publisher.onlineEventPublish(deviceId, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE); 284 + RequestMessage msg = new RequestMessage();
  285 + msg.setDeviceId(deviceId);
  286 + msg.setType(DeferredResultHolder.CALLBACK_CMD_CATALOG);
  287 + msg.setData(device);
  288 + deferredResultHolder.invokeResult(msg);
  289 + // 回复200 OK
  290 + responseAck(evt);
  291 + if (offLineDetector.isOnline(deviceId)) {
  292 + publisher.onlineEventPublish(deviceId, VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);
  293 + }
268 } 294 }
269 } 295 }
  296 +
270 } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) { 297 } catch (DocumentException | SipException | InvalidArgumentException | ParseException e) {
271 e.printStackTrace(); 298 e.printStackTrace();
272 } 299 }
@@ -469,6 +496,18 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { @@ -469,6 +496,18 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
469 getServerTransaction(evt).sendResponse(response); 496 getServerTransaction(evt).sendResponse(response);
470 } 497 }
471 498
  499 + /***
  500 + * 回复200 OK
  501 + * @param evt
  502 + * @throws SipException
  503 + * @throws InvalidArgumentException
  504 + * @throws ParseException
  505 + */
  506 + private void response404Ack(RequestEvent evt) throws SipException, InvalidArgumentException, ParseException {
  507 + Response response = getMessageFactory().createResponse(Response.NOT_FOUND, evt.getRequest());
  508 + getServerTransaction(evt).sendResponse(response);
  509 + }
  510 +
472 private Element getRootElement(RequestEvent evt) throws DocumentException { 511 private Element getRootElement(RequestEvent evt) throws DocumentException {
473 Request request = evt.getRequest(); 512 Request request = evt.getRequest();
474 SAXReader reader = new SAXReader(); 513 SAXReader reader = new SAXReader();
@@ -508,4 +547,12 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor { @@ -508,4 +547,12 @@ public class MessageRequestProcessor extends SIPRequestAbstractProcessor {
508 public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) { 547 public void setRedisCatchStorage(IRedisCatchStorage redisCatchStorage) {
509 this.redisCatchStorage = redisCatchStorage; 548 this.redisCatchStorage = redisCatchStorage;
510 } 549 }
  550 +
  551 + public SIPCommanderFroPlatform getCmderFroPlatform() {
  552 + return cmderFroPlatform;
  553 + }
  554 +
  555 + public void setCmderFroPlatform(SIPCommanderFroPlatform cmderFroPlatform) {
  556 + this.cmderFroPlatform = cmderFroPlatform;
  557 + }
511 } 558 }
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
@@ -210,6 +210,11 @@ public interface IVideoManagerStorager { @@ -210,6 +210,11 @@ public interface IVideoManagerStorager {
210 */ 210 */
211 PageInfo<ChannelReduce> queryAllChannelList(int page, int count, String query, Boolean online, Boolean channelType, String platformId, Boolean inPlatform); 211 PageInfo<ChannelReduce> queryAllChannelList(int page, int count, String query, Boolean online, Boolean channelType, String platformId, Boolean inPlatform);
212 212
  213 + /**
  214 + * 查询设备的通道信息
  215 + */
  216 + List<ChannelReduce> queryChannelListInParentPlatform(String platformId);
  217 +
213 218
214 /** 219 /**
215 * 更新上级平台的通道信息 220 * 更新上级平台的通道信息
src/main/java/com/genersoft/iot/vmp/storager/dao/DeviceChannelMapper.java
@@ -83,19 +83,19 @@ public interface DeviceChannelMapper { @@ -83,19 +83,19 @@ public interface DeviceChannelMapper {
83 "SELECT * FROM ( "+ 83 "SELECT * FROM ( "+
84 " SELECT dc.channelId, dc.deviceId, dc.name, de.manufacturer, de.hostAddress, " + 84 " SELECT dc.channelId, dc.deviceId, dc.name, de.manufacturer, de.hostAddress, " +
85 "(SELECT count(0) FROM device_channel WHERE parentId=dc.channelId) as subCount, " + 85 "(SELECT count(0) FROM device_channel WHERE parentId=dc.channelId) as subCount, " +
86 - "pc.platformId " + 86 + "(SELECT pc.platformId FROM platform_gb_channel pc WHERE pc.deviceId=dc.deviceId AND pc.channelId = dc.channelId ) as platformId " +
87 "FROM device_channel dc " + 87 "FROM device_channel dc " +
88 "LEFT JOIN device de ON dc.deviceId = de.deviceId " + 88 "LEFT JOIN device de ON dc.deviceId = de.deviceId " +
89 - "LEFT JOIN platform_gb_channel pc on pc.deviceId = dc.deviceId AND pc.channelId = dc.channelId " +  
90 " WHERE 1=1 " + 89 " WHERE 1=1 " +
91 " <if test=\"query != null\"> AND (dc.channelId LIKE '%${query}%' OR dc.name LIKE '%${query}%' OR dc.name LIKE '%${query}%')</if> " + 90 " <if test=\"query != null\"> AND (dc.channelId LIKE '%${query}%' OR dc.name LIKE '%${query}%' OR dc.name LIKE '%${query}%')</if> " +
92 " <if test=\"online == true\" > AND dc.status=1</if> " + 91 " <if test=\"online == true\" > AND dc.status=1</if> " +
93 " <if test=\"online == false\" > AND dc.status=0</if> " + 92 " <if test=\"online == false\" > AND dc.status=0</if> " +
94 - " <if test=\"platformId != null and inPlatform == true\"> AND pc.platformId=#{platformId} </if> " +  
95 ") dcr" + 93 ") dcr" +
96 " WHERE 1=1 " + 94 " WHERE 1=1 " +
97 " <if test=\"hasSubChannel!= null and hasSubChannel == true\" > AND subCount >0</if> " + 95 " <if test=\"hasSubChannel!= null and hasSubChannel == true\" > AND subCount >0</if> " +
98 " <if test=\"hasSubChannel!= null and hasSubChannel == false\" > AND subCount=0</if> " + 96 " <if test=\"hasSubChannel!= null and hasSubChannel == false\" > AND subCount=0</if> " +
  97 + " <if test=\"platformId != null and inPlatform == true \" > AND platformId='${platformId}'</if> " +
  98 + " <if test=\"platformId != null and inPlatform == false \" > AND (platformId != '${platformId}' OR platformId is NULL ) </if> " +
99 " </script>"}) 99 " </script>"})
100 100
101 List<ChannelReduce> queryChannelListInAll(String query, Boolean online, Boolean hasSubChannel, String platformId, Boolean inPlatform); 101 List<ChannelReduce> queryChannelListInAll(String query, Boolean online, Boolean hasSubChannel, String platformId, Boolean inPlatform);
src/main/java/com/genersoft/iot/vmp/storager/dao/ParentPlatformMapper.java
@@ -45,7 +45,7 @@ public interface ParentPlatformMapper { @@ -45,7 +45,7 @@ public interface ParentPlatformMapper {
45 @Delete("DELETE FROM parent_platform WHERE deviceGBId=#{deviceGBId}") 45 @Delete("DELETE FROM parent_platform WHERE deviceGBId=#{deviceGBId}")
46 int delParentPlatform(ParentPlatform parentPlatform); 46 int delParentPlatform(ParentPlatform parentPlatform);
47 47
48 - @Select("SELECT * FROM parent_platform") 48 + @Select("SELECT *,( SELECT count(0) FROM platform_gb_channel pc WHERE pc.platformId = pp.deviceGBId) as channelCount FROM parent_platform pp ")
49 List<ParentPlatform> getParentPlatformList(); 49 List<ParentPlatform> getParentPlatformList();
50 50
51 @Select("SELECT * FROM parent_platform WHERE enable=#{enable}") 51 @Select("SELECT * FROM parent_platform WHERE enable=#{enable}")
src/main/java/com/genersoft/iot/vmp/storager/dao/PatformChannelMapper.java
@@ -30,8 +30,13 @@ public interface PatformChannelMapper { @@ -30,8 +30,13 @@ public interface PatformChannelMapper {
30 30
31 31
32 @Delete("<script> "+ 32 @Delete("<script> "+
33 - "DELETE FROM platform_gb_channel WHERE deviceAndChannelId in" + 33 + "DELETE FROM platform_gb_channel WHERE platformId='${platformId}' AND deviceAndChannelId in" +
34 "<foreach collection='channelReducesToDel' item='item' open='(' separator=',' close=')' > '${item.deviceId}_${item.channelId}'</foreach>" + 34 "<foreach collection='channelReducesToDel' item='item' open='(' separator=',' close=')' > '${item.deviceId}_${item.channelId}'</foreach>" +
35 "</script>") 35 "</script>")
36 int delChannelForGB(String platformId, List<ChannelReduce> channelReducesToDel); 36 int delChannelForGB(String platformId, List<ChannelReduce> channelReducesToDel);
  37 +
  38 + @Delete("<script> "+
  39 + "DELETE FROM platform_gb_channel WHERE platformId='${platformId}'" +
  40 + "</script>")
  41 + int cleanChannelForGB(String platformId);
37 } 42 }
src/main/java/com/genersoft/iot/vmp/storager/impl/VideoManagerStoragerImpl.java
@@ -249,9 +249,12 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -249,9 +249,12 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
249 return result > 0; 249 return result > 0;
250 } 250 }
251 251
  252 + @Transactional
252 @Override 253 @Override
253 public boolean deleteParentPlatform(ParentPlatform parentPlatform) { 254 public boolean deleteParentPlatform(ParentPlatform parentPlatform) {
254 int result = platformMapper.delParentPlatform(parentPlatform); 255 int result = platformMapper.delParentPlatform(parentPlatform);
  256 + // 删除关联的通道
  257 + patformChannelMapper.cleanChannelForGB(parentPlatform.getDeviceGBId());
255 return result > 0; 258 return result > 0;
256 } 259 }
257 260
@@ -286,6 +289,11 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager { @@ -286,6 +289,11 @@ public class VideoManagerStoragerImpl implements IVideoManagerStorager {
286 return new PageInfo<>(all); 289 return new PageInfo<>(all);
287 } 290 }
288 291
  292 + @Override
  293 + public List<ChannelReduce> queryChannelListInParentPlatform(String platformId) {
  294 +
  295 + return deviceChannelMapper.queryChannelListInAll(null, null, null, platformId, true);
  296 + }
289 297
290 @Override 298 @Override
291 public int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces) { 299 public int updateChannelForGB(String platformId, List<ChannelReduce> channelReduces) {
web_src/src/components/gb28181/chooseChannel.vue
1 <template> 1 <template>
2 <div id="chooseChannel" v-loading="isLoging"> 2 <div id="chooseChannel" v-loading="isLoging">
3 3
4 - <el-dialog title="选择通道" top="2rem" width="70%" :close-on-click-modal="false" :visible.sync="showDialog" :destroy-on-close="true" @close="close()"> 4 + <el-dialog title="选择通道" v-if="showDialog" top="2rem" width="70%" :close-on-click-modal="false" :visible.sync="showDialog" :destroy-on-close="true" @close="close()">
5 <el-tabs v-model="tabActiveName" > 5 <el-tabs v-model="tabActiveName" >
6 <el-tab-pane label="国标通道" name="gbChannel"> 6 <el-tab-pane label="国标通道" name="gbChannel">
7 <el-container> 7 <el-container>
web_src/src/components/gb28181/chooseChannelForGb.vue
@@ -41,7 +41,7 @@ @@ -41,7 +41,7 @@
41 <el-table-column prop="manufacturer" label="厂家" align="center"> 41 <el-table-column prop="manufacturer" label="厂家" align="center">
42 </el-table-column> 42 </el-table-column>
43 </el-table> 43 </el-table>
44 - <el-pagination style="float: right;margin-top: 1rem;" @size-change="handleSizeChange" @current-change="currentChange" :current-page="currentPage" :page-size="count" :page-sizes="[15, 20, 30, 50]" layout="total, sizes, prev, pager, next" :total="total"> 44 + <el-pagination style="float: right;margin-top: 1rem;" @size-change="handleSizeChange" @current-change="currentChange" :current-page="currentPage" :page-size="count" :page-sizes="[10, 20, 30, 50]" layout="total, sizes, prev, pager, next" :total="total">
45 </el-pagination> 45 </el-pagination>
46 </div> 46 </div>
47 </template> 47 </template>