Commit 29710b7cc154191ae56acf6af32ec70241886e78

Authored by swwheihei
2 parents 4202cfb8 92cbbefc

Merge branch 'master' of https://github.com/swwheihei/wvp.git

Conflicts:
	src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java
Showing 49 changed files with 461 additions and 343 deletions
LICENSE 0 → 100644
  1 +MIT License
  2 +
  3 +Copyright (c) 2020 swwhaha
  4 +
  5 +Permission is hereby granted, free of charge, to any person obtaining a copy
  6 +of this software and associated documentation files (the "Software"), to deal
  7 +in the Software without restriction, including without limitation the rights
  8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9 +copies of the Software, and to permit persons to whom the Software is
  10 +furnished to do so, subject to the following conditions:
  11 +
  12 +The above copyright notice and this permission notice shall be included in all
  13 +copies or substantial portions of the Software.
  14 +
  15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21 +SOFTWARE.
... ...
... ... @@ -39,7 +39,7 @@
39 39 </dependency>
40 40 <dependency>
41 41 <groupId>org.springframework.boot</groupId>
42   - <artifactId>spring-boot-starter-undertow</artifactId>
  42 + <artifactId>spring-boot-starter-tomcat</artifactId>
43 43 </dependency>
44 44 <dependency>
45 45 <groupId>org.springframework.boot</groupId>
... ... @@ -127,7 +127,7 @@
127 127 <dependency>
128 128 <groupId>org.dom4j</groupId>
129 129 <artifactId>dom4j</artifactId>
130   - <version>2.1.1</version>
  130 + <version>2.1.3</version>
131 131 </dependency>
132 132 <dependency>
133 133 <groupId>com.google.code.gson</groupId>
... ...
src/main/java/com/genersoft/iot/vmp/common/VideoManagerConstants.java
... ... @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.common;
2 2  
3 3 /**
4 4 * @Description:TODO(这里用一句话描述这个类的作用)
5   - * @author: swwheihei
  5 + * @author: songww
6 6 * @date: 2019年5月30日 下午3:04:04
7 7 *
8 8 */
... ...
src/main/java/com/genersoft/iot/vmp/conf/RedisConfig.java
... ... @@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.utils.redis.FastJsonRedisSerializer;
13 13  
14 14 /**
15 15 * @Description:Redis中间件配置类,使用spring-data-redis集成,自动从application.yml中加载redis配置
16   - * @author: swwheihei
  16 + * @author: songww
17 17 * @date: 2019年5月30日 上午10:58:25
18 18 *
19 19 */
... ...
src/main/java/com/genersoft/iot/vmp/conf/VManagerConfig.java
... ... @@ -5,7 +5,7 @@ import org.springframework.context.annotation.Configuration;
5 5  
6 6 /**
7 7 * @Description:TODO(这里用一句话描述这个类的作用)
8   - * @author: swwheihei
  8 + * @author: songww
9 9 * @date: 2020年5月6日 下午2:46:00
10 10 */
11 11 @Configuration("vmConfig")
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
1   -package com.genersoft.iot.vmp.gb28181;
2   -
3   -import java.util.Properties;
4   -
5   -import javax.annotation.PostConstruct;
6   -import javax.sip.DialogTerminatedEvent;
7   -import javax.sip.IOExceptionEvent;
8   -import javax.sip.ListeningPoint;
9   -import javax.sip.RequestEvent;
10   -import javax.sip.ResponseEvent;
11   -import javax.sip.ServerTransaction;
12   -import javax.sip.SipFactory;
13   -import javax.sip.SipListener;
14   -import javax.sip.SipProvider;
15   -import javax.sip.SipStack;
16   -import javax.sip.TimeoutEvent;
17   -import javax.sip.TransactionAlreadyExistsException;
18   -import javax.sip.TransactionTerminatedEvent;
19   -import javax.sip.TransactionUnavailableException;
20   -import javax.sip.address.AddressFactory;
21   -import javax.sip.header.HeaderFactory;
22   -import javax.sip.header.ViaHeader;
23   -import javax.sip.message.MessageFactory;
24   -import javax.sip.message.Request;
25   -import javax.sip.message.Response;
26   -
27   -import org.slf4j.Logger;
28   -import org.slf4j.LoggerFactory;
29   -import org.springframework.beans.factory.annotation.Autowired;
30   -import org.springframework.stereotype.Component;
31   -
32   -import com.genersoft.iot.vmp.conf.SipConfig;
33   -import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorFactory;
34   -import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
35   -import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
36   -
37   -import gov.nist.javax.sip.SipStackImpl;
38   -
39   -@Component
40   -public class SipLayer implements SipListener, Runnable {
41   -
42   - private final static Logger logger = LoggerFactory.getLogger(SipLayer.class);
43   -
44   - @Autowired
45   - private SipConfig sipConfig;
46   -
47   - private SipProvider tcpSipProvider;
48   -
49   - private SipProvider udpSipProvider;
50   -
51   - @Autowired
52   - private SIPProcessorFactory processorFactory;
53   -
54   - private SipStack sipStack;
55   -
56   - private AddressFactory addressFactory;
57   - private HeaderFactory headerFactory;
58   - private MessageFactory messageFactory;
59   -
60   - @PostConstruct
61   - private void initSipServer() {
62   - Thread thread=new Thread(this);
63   - thread.setDaemon(true);
64   - thread.setName("sip server thread start");
65   - thread.start();
66   - }
67   -
68   - @Override
69   - public void run() {
70   - SipFactory sipFactory = SipFactory.getInstance();
71   - sipFactory.setPathName("gov.nist");
72   - try {
73   - headerFactory = sipFactory.createHeaderFactory();
74   -
75   - addressFactory = sipFactory.createAddressFactory();
76   - messageFactory = sipFactory.createMessageFactory();
77   -
78   - Properties properties = new Properties();
79   - properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
80   - properties.setProperty("javax.sip.IP_ADDRESS", sipConfig.getSipIp());
81   - properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "false");
82   - /**
83   - * sip_server_log.log 和 sip_debug_log.log public static final int TRACE_NONE =
84   - * 0; public static final int TRACE_MESSAGES = 16; public static final int
85   - * TRACE_EXCEPTION = 17; public static final int TRACE_DEBUG = 32;
86   - */
87   - properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "0");
88   - properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "sip_server_log");
89   - properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "sip_debug_log");
90   - sipStack = (SipStackImpl) sipFactory.createSipStack(properties);
91   -
92   - startTcpListener();
93   - startUdpListener();
94   - } catch (Exception e) {
95   - logger.error("Sip Server 启动失败! port {" + sipConfig.getSipPort() + "}");
96   - e.printStackTrace();
97   - }
98   - logger.info("Sip Server 启动成功 port {" + sipConfig.getSipPort() + "}");
99   - }
100   -
101   - private void startTcpListener() throws Exception {
102   - ListeningPoint tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), "TCP");
103   - tcpSipProvider = sipStack.createSipProvider(tcpListeningPoint);
104   - tcpSipProvider.addSipListener(this);
105   - }
106   -
107   - private void startUdpListener() throws Exception {
108   - ListeningPoint udpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(), "UDP");
109   - udpSipProvider = sipStack.createSipProvider(udpListeningPoint);
110   - udpSipProvider.addSipListener(this);
111   - }
112   -
113   - /**
114   - * SIP服务端接收消息的方法 Content 里面是GBK编码 This method is called by the SIP stack when a
115   - * new request arrives.
116   - */
117   - @Override
118   - public void processRequest(RequestEvent evt) {
119   - ISIPRequestProcessor processor = processorFactory.createRequestProcessor(evt);
120   - processor.process(evt, this);
121   - }
122   -
123   - @Override
124   - public void processResponse(ResponseEvent evt) {
125   - Response response = evt.getResponse();
126   - int status = response.getStatusCode();
127   - if ((status >= 200) && (status < 300)) { // Success!
128   - ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt);
129   - processor.process(evt, this, sipConfig);
130   - } else {
131   - logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getContent().toString());
132   - }
133   - // trying不会回复
134   - if (status == Response.TRYING) {
135   -
136   - }
137   - }
138   -
139   - /**
140   - * <p>
141   - * Title: processTimeout
142   - * </p>
143   - * <p>
144   - * Description:
145   - * </p>
146   - *
147   - * @param timeoutEvent
148   - */
149   - @Override
150   - public void processTimeout(TimeoutEvent timeoutEvent) {
151   - // TODO Auto-generated method stub
152   -
153   - }
154   -
155   - /**
156   - * <p>
157   - * Title: processIOException
158   - * </p>
159   - * <p>
160   - * Description:
161   - * </p>
162   - *
163   - * @param exceptionEvent
164   - */
165   - @Override
166   - public void processIOException(IOExceptionEvent exceptionEvent) {
167   - // TODO Auto-generated method stub
168   -
169   - }
170   -
171   - /**
172   - * <p>
173   - * Title: processTransactionTerminated
174   - * </p>
175   - * <p>
176   - * Description:
177   - * </p>
178   - *
179   - * @param transactionTerminatedEvent
180   - */
181   - @Override
182   - public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) {
183   - // TODO Auto-generated method stub
184   -
185   - }
186   -
187   - /**
188   - * <p>
189   - * Title: processDialogTerminated
190   - * </p>
191   - * <p>
192   - * Description:
193   - * </p>
194   - *
195   - * @param dialogTerminatedEvent
196   - */
197   - @Override
198   - public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) {
199   - // TODO Auto-generated method stub
200   -
201   - }
202   -
203   - public ServerTransaction getServerTransaction(RequestEvent evt) {
204   - Request request = evt.getRequest();
205   - ServerTransaction serverTransaction = evt.getServerTransaction();
206   - // 判断TCP还是UDP
207   - boolean isTcp = false;
208   - ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
209   - String transport = reqViaHeader.getTransport();
210   - if (transport.equals("TCP")) {
211   - isTcp = true;
212   - }
213   -
214   - if (serverTransaction == null) {
215   - try {
216   - if (isTcp) {
217   - serverTransaction = tcpSipProvider.getNewServerTransaction(request);
218   - } else {
219   - serverTransaction = udpSipProvider.getNewServerTransaction(request);
220   - }
221   - } catch (TransactionAlreadyExistsException e) {
222   - e.printStackTrace();
223   - } catch (TransactionUnavailableException e) {
224   - e.printStackTrace();
225   - }
226   - }
227   - return serverTransaction;
228   - }
229   -
230   - public AddressFactory getAddressFactory() {
231   - return addressFactory;
232   - }
233   -
234   - public HeaderFactory getHeaderFactory() {
235   - return headerFactory;
236   - }
237   -
238   - public MessageFactory getMessageFactory() {
239   - return messageFactory;
240   - }
241   -
242   - public SipProvider getTcpSipProvider() {
243   - return tcpSipProvider;
244   - }
245   -
246   - public SipProvider getUdpSipProvider() {
247   - return udpSipProvider;
248   - }
249   -
250   -}
  1 +package com.genersoft.iot.vmp.gb28181;
  2 +
  3 +import java.text.ParseException;
  4 +import java.util.Properties;
  5 +
  6 +import javax.annotation.PostConstruct;
  7 +import javax.sip.DialogTerminatedEvent;
  8 +import javax.sip.IOExceptionEvent;
  9 +import javax.sip.ListeningPoint;
  10 +import javax.sip.RequestEvent;
  11 +import javax.sip.ResponseEvent;
  12 +import javax.sip.ServerTransaction;
  13 +import javax.sip.SipFactory;
  14 +import javax.sip.SipListener;
  15 +import javax.sip.SipProvider;
  16 +import javax.sip.SipStack;
  17 +import javax.sip.TimeoutEvent;
  18 +import javax.sip.TransactionAlreadyExistsException;
  19 +import javax.sip.TransactionTerminatedEvent;
  20 +import javax.sip.TransactionUnavailableException;
  21 +import javax.sip.address.AddressFactory;
  22 +import javax.sip.header.HeaderFactory;
  23 +import javax.sip.header.ViaHeader;
  24 +import javax.sip.message.MessageFactory;
  25 +import javax.sip.message.Request;
  26 +import javax.sip.message.Response;
  27 +
  28 +import org.slf4j.Logger;
  29 +import org.slf4j.LoggerFactory;
  30 +import org.springframework.beans.factory.annotation.Autowired;
  31 +import org.springframework.stereotype.Component;
  32 +
  33 +import com.genersoft.iot.vmp.conf.SipConfig;
  34 +import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorFactory;
  35 +import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
  36 +import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
  37 +
  38 +import gov.nist.javax.sip.SipStackImpl;
  39 +
  40 +@Component
  41 +public class SipLayer implements SipListener, Runnable {
  42 +
  43 + private final static Logger logger = LoggerFactory.getLogger(SipLayer.class);
  44 +
  45 + @Autowired
  46 + private SipConfig sipConfig;
  47 +
  48 + private SipProvider tcpSipProvider;
  49 +
  50 + private SipProvider udpSipProvider;
  51 +
  52 + @Autowired
  53 + private SIPProcessorFactory processorFactory;
  54 +
  55 + private SipStack sipStack;
  56 +
  57 + private AddressFactory addressFactory;
  58 + private HeaderFactory headerFactory;
  59 + private MessageFactory messageFactory;
  60 +
  61 + @PostConstruct
  62 + private void initSipServer() {
  63 + Thread thread = new Thread(this);
  64 + thread.setDaemon(true);
  65 + thread.setName("sip server thread start");
  66 + thread.start();
  67 + }
  68 +
  69 + @Override
  70 + public void run() {
  71 + SipFactory sipFactory = SipFactory.getInstance();
  72 + sipFactory.setPathName("gov.nist");
  73 + try {
  74 + headerFactory = sipFactory.createHeaderFactory();
  75 +
  76 + addressFactory = sipFactory.createAddressFactory();
  77 + messageFactory = sipFactory.createMessageFactory();
  78 +
  79 + Properties properties = new Properties();
  80 + properties.setProperty("javax.sip.STACK_NAME", "GB28181_SIP");
  81 + properties.setProperty("javax.sip.IP_ADDRESS", sipConfig.getSipIp());
  82 + properties.setProperty("gov.nist.javax.sip.LOG_MESSAGE_CONTENT", "false");
  83 + /**
  84 + * sip_server_log.log 和 sip_debug_log.log public static final int TRACE_NONE =
  85 + * 0; public static final int TRACE_MESSAGES = 16; public static final int
  86 + * TRACE_EXCEPTION = 17; public static final int TRACE_DEBUG = 32;
  87 + */
  88 + properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", "32");
  89 + properties.setProperty("gov.nist.javax.sip.SERVER_LOG", "sip_server_log");
  90 + properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", "sip_debug_log");
  91 + sipStack = (SipStackImpl) sipFactory.createSipStack(properties);
  92 +
  93 + startTcpListener();
  94 + startUdpListener();
  95 + } catch (Exception e) {
  96 + logger.error("Sip Server 启动失败! port {" + sipConfig.getSipPort() + "}");
  97 + e.printStackTrace();
  98 + }
  99 + logger.info("Sip Server 启动成功 port {" + sipConfig.getSipPort() + "}");
  100 + }
  101 +
  102 + private void startTcpListener() throws Exception {
  103 + ListeningPoint tcpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(),
  104 + "TCP");
  105 + tcpSipProvider = sipStack.createSipProvider(tcpListeningPoint);
  106 + tcpSipProvider.addSipListener(this);
  107 + }
  108 +
  109 + private void startUdpListener() throws Exception {
  110 + ListeningPoint udpListeningPoint = sipStack.createListeningPoint(sipConfig.getSipIp(), sipConfig.getSipPort(),
  111 + "UDP");
  112 + udpSipProvider = sipStack.createSipProvider(udpListeningPoint);
  113 + udpSipProvider.addSipListener(this);
  114 + }
  115 +
  116 + /**
  117 + * SIP服务端接收消息的方法 Content 里面是GBK编码 This method is called by the SIP stack when a
  118 + * new request arrives.
  119 + */
  120 + @Override
  121 + public void processRequest(RequestEvent evt) {
  122 + ISIPRequestProcessor processor = processorFactory.createRequestProcessor(evt);
  123 + processor.process(evt, this);
  124 + }
  125 +
  126 + @Override
  127 + public void processResponse(ResponseEvent evt) {
  128 + Response response = evt.getResponse();
  129 + int status = response.getStatusCode();
  130 + if ((status >= 200) && (status < 300)) { // Success!
  131 + ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt);
  132 + try {
  133 + processor.process(evt, this, sipConfig);
  134 + } catch (ParseException e) {
  135 + // TODO Auto-generated catch block
  136 + e.printStackTrace();
  137 + }
  138 + // } else if (status == Response.TRYING) {
  139 + // trying不会回复
  140 + } else if ((status >= 100) && (status < 200)) {
  141 + // 增加其它无需回复的响应,如101、180等
  142 + } else {
  143 + logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getReasonPhrase()/* .getContent().toString()*/);
  144 + }
  145 + // trying不会回复
  146 + // if (status == Response.TRYING) {
  147 +
  148 + // }
  149 + }
  150 +
  151 + /**
  152 + * <p>
  153 + * Title: processTimeout
  154 + * </p>
  155 + * <p>
  156 + * Description:
  157 + * </p>
  158 + *
  159 + * @param timeoutEvent
  160 + */
  161 + @Override
  162 + public void processTimeout(TimeoutEvent timeoutEvent) {
  163 + // TODO Auto-generated method stub
  164 +
  165 + }
  166 +
  167 + /**
  168 + * <p>
  169 + * Title: processIOException
  170 + * </p>
  171 + * <p>
  172 + * Description:
  173 + * </p>
  174 + *
  175 + * @param exceptionEvent
  176 + */
  177 + @Override
  178 + public void processIOException(IOExceptionEvent exceptionEvent) {
  179 + // TODO Auto-generated method stub
  180 +
  181 + }
  182 +
  183 + /**
  184 + * <p>
  185 + * Title: processTransactionTerminated
  186 + * </p>
  187 + * <p>
  188 + * Description:
  189 + * </p>
  190 + *
  191 + * @param transactionTerminatedEvent
  192 + */
  193 + @Override
  194 + public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) {
  195 + // TODO Auto-generated method stub
  196 +
  197 + }
  198 +
  199 + /**
  200 + * <p>
  201 + * Title: processDialogTerminated
  202 + * </p>
  203 + * <p>
  204 + * Description:
  205 + * </p>
  206 + *
  207 + * @param dialogTerminatedEvent
  208 + */
  209 + @Override
  210 + public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) {
  211 + // TODO Auto-generated method stub
  212 +
  213 + }
  214 +
  215 + public ServerTransaction getServerTransaction(RequestEvent evt) {
  216 + Request request = evt.getRequest();
  217 + ServerTransaction serverTransaction = evt.getServerTransaction();
  218 + // 判断TCP还是UDP
  219 + boolean isTcp = false;
  220 + ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
  221 + String transport = reqViaHeader.getTransport();
  222 + if (transport.equals("TCP")) {
  223 + isTcp = true;
  224 + }
  225 +
  226 + if (serverTransaction == null) {
  227 + try {
  228 + if (isTcp) {
  229 + serverTransaction = tcpSipProvider.getNewServerTransaction(request);
  230 + } else {
  231 + serverTransaction = udpSipProvider.getNewServerTransaction(request);
  232 + }
  233 + } catch (TransactionAlreadyExistsException e) {
  234 + e.printStackTrace();
  235 + } catch (TransactionUnavailableException e) {
  236 + e.printStackTrace();
  237 + }
  238 + }
  239 + return serverTransaction;
  240 + }
  241 +
  242 + public AddressFactory getAddressFactory() {
  243 + return addressFactory;
  244 + }
  245 +
  246 + public HeaderFactory getHeaderFactory() {
  247 + return headerFactory;
  248 + }
  249 +
  250 + public MessageFactory getMessageFactory() {
  251 + return messageFactory;
  252 + }
  253 +
  254 + public SipProvider getTcpSipProvider() {
  255 + return tcpSipProvider;
  256 + }
  257 +
  258 + public SipProvider getUdpSipProvider() {
  259 + return udpSipProvider;
  260 + }
  261 +
  262 +}
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/auth/RegisterLogicHandler.java
... ... @@ -8,7 +8,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
8 8  
9 9 /**
10 10 * @Description:注册逻辑处理,当设备注册后触发逻辑。
11   - * @author: swwheihei
  11 + * @author: songww
12 12 * @date: 2020年5月8日 下午9:41:46
13 13 */
14 14 @Component
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordInfo.java
... ... @@ -4,7 +4,7 @@ import java.util.List;
4 4  
5 5 /**
6 6 * @Description:设备录像信息bean
7   - * @author: swwheihei
  7 + * @author: songww
8 8 * @date: 2020年5月8日 下午2:05:56
9 9 */
10 10 public class RecordInfo {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/bean/RecordItem.java
... ... @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.gb28181.bean;
2 2  
3 3 /**
4 4 * @Description:设备录像bean
5   - * @author: swwheihei
  5 + * @author: songww
6 6 * @date: 2020年5月8日 下午2:06:54
7 7 */
8 8 public class RecordItem {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/DeviceOffLineDetector.java
... ... @@ -8,7 +8,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil;
8 8  
9 9 /**
10 10 * @Description:设备离在线状态检测器,用于检测设备状态
11   - * @author: swwheihei
  11 + * @author: songww
12 12 * @date: 2020年5月13日 下午2:40:29
13 13 */
14 14 @Component
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/EventPublisher.java
... ... @@ -9,7 +9,7 @@ import com.genersoft.iot.vmp.gb28181.event.online.OnlineEvent;
9 9  
10 10 /**
11 11 * @Description:Event事件通知推送器,支持推送在线事件、离线事件
12   - * @author: swwheihei
  12 + * @author: songww
13 13 * @date: 2020年5月6日 上午11:30:50
14 14 */
15 15 @Component
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/KeepliveTimeoutListener.java
... ... @@ -11,7 +11,7 @@ import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
11 11  
12 12 /**
13 13 * @Description:设备心跳超时监听,借助redis过期特性,进行监听,监听到说明设备心跳超时,发送离线事件
14   - * @author: swwheihei
  14 + * @author: songww
15 15 * @date: 2020年5月6日 上午11:35:46
16 16 */
17 17 @Component
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEvent.java
... ... @@ -4,7 +4,7 @@ import org.springframework.context.ApplicationEvent;
4 4  
5 5 /**
6 6 * @Description:TODO(这里用一句话描述这个类的作用)
7   - * @author: swwheihei
  7 + * @author: songww
8 8 * @date: 2020年5月6日 上午11:33:13
9 9 */
10 10 public class OfflineEvent extends ApplicationEvent {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/offline/OfflineEventListener.java
... ... @@ -14,7 +14,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil;
14 14 * @Description: 离线事件监听器,监听到离线后,修改设备离在线状态。 设备离线有两个来源:
15 15 * 1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor}
16 16 * 2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.event.offline.OfflineEventListener}
17   - * @author: swwheihei
  17 + * @author: songww
18 18 * @date: 2020年5月6日 下午1:51:23
19 19 */
20 20 @Component
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEvent.java
... ... @@ -4,7 +4,7 @@ import org.springframework.context.ApplicationEvent;
4 4  
5 5 /**
6 6 * @Description:TODO(这里用一句话描述这个类的作用)
7   - * @author: swwheihei
  7 + * @author: songww
8 8 * @date: 2020年5月6日 上午11:32:56
9 9 */
10 10 public class OnlineEvent extends ApplicationEvent {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/event/online/OnlineEventListener.java
... ... @@ -14,7 +14,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil;
14 14 * @Description: 在线事件监听器,监听到离线后,修改设备离在线状态。 设备在线有两个来源:
15 15 * 1、设备主动注销,发送注销指令,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor}
16 16 * 2、设备未知原因离线,心跳超时,{@link com.genersoft.iot.vmp.gb28181.transmit.request.impl.MessageRequestProcessor}
17   - * @author: swwheihei
  17 + * @author: songww
18 18 * @date: 2020年5月6日 下午1:51:23
19 19 */
20 20 @Component
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/session/SsrcUtil.java
... ... @@ -9,7 +9,7 @@ import com.genersoft.iot.vmp.utils.SpringBeanFactory;
9 9  
10 10 /**
11 11 * @Description:SIP信令中的SSRC工具类。SSRC值由10位十进制整数组成的字符串,第一位为0代表实况,为1则代表回放;第二位至第六位由监控域ID的第4位到第8位组成;最后4位为不重复的4个整数
12   - * @author: swwheihei
  12 + * @author: songww
13 13 * @date: 2020年5月10日 上午11:57:57
14 14 */
15 15 public class SsrcUtil {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/session/VideoStreamSessionManager.java
... ... @@ -8,7 +8,7 @@ import org.springframework.stereotype.Component;
8 8  
9 9 /**
10 10 * @Description:视频流session管理器,管理视频预览、预览回放的通信句柄
11   - * @author: swwheihei
  11 + * @author: songww
12 12 * @date: 2020年5月13日 下午4:03:02
13 13 */
14 14 @Component
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/SIPProcessorFactory.java
... ... @@ -26,7 +26,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.response.impl.OtherResponseProcess
26 26  
27 27 /**
28 28 * @Description:TODO(这里用一句话描述这个类的作用)
29   - * @author: swwheihei
  29 + * @author: songww
30 30 * @date: 2020年5月3日 下午4:24:37
31 31 */
32 32 @Component
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/DeferredResultHolder.java
... ... @@ -10,7 +10,7 @@ import org.springframework.web.context.request.async.DeferredResult;
10 10  
11 11 /**
12 12 * @Description:TODO(这里用一句话描述这个类的作用)
13   - * @author: swwheihei
  13 + * @author: songww
14 14 * @date: 2020年5月8日 下午7:59:05
15 15 */
16 16 @Component
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/callback/RequestMessage.java
... ... @@ -2,7 +2,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.callback;
2 2  
3 3 /**
4 4 * @Description:TODO(这里用一句话描述这个类的作用)
5   - * @author: swwheihei
  5 + * @author: songww
6 6 * @date: 2020年5月8日 下午1:09:18
7 7 */
8 8 public class RequestMessage {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/ISIPCommander.java
... ... @@ -4,7 +4,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device;
4 4  
5 5 /**
6 6 * @Description:设备能力接口,用于定义设备的控制、查询能力
7   - * @author: swwheihei
  7 + * @author: songww
8 8 * @date: 2020年5月3日 下午9:16:34
9 9 */
10 10 public interface ISIPCommander {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
... ... @@ -25,7 +25,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Host;
25 25  
26 26 /**
27 27 * @Description:摄像头命令request创造器 TODO 冗余代码太多待优化
28   - * @author: swwheihei
  28 + * @author: songww
29 29 * @date: 2020年5月6日 上午9:29:02
30 30 */
31 31 @Component
... ... @@ -79,7 +79,8 @@ public class SIPRequestHeaderProvider {
79 79 SipURI requestLine = layer.getAddressFactory().createSipURI(channelId, host.getAddress());
80 80 //via
81 81 ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
82   - ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag);
  82 + // ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag);
  83 + ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(device.getHost().getIp(), device.getHost().getPort(), device.getTransport(), viaTag);
83 84 viaHeader.setRPort();
84 85 viaHeaders.add(viaHeader);
85 86 //from
... ... @@ -108,6 +109,7 @@ public class SIPRequestHeaderProvider {
108 109 request = layer.getMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards);
109 110  
110 111 Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), sipConfig.getSipIp()+":"+sipConfig.getSipPort()));
  112 + // Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), device.getHost().getIp()+":"+device.getHost().getPort()));
111 113 request.addHeader(layer.getHeaderFactory().createContactHeader(concatAddress));
112 114  
113 115 ContentTypeHeader contentTypeHeader = layer.getHeaderFactory().createContentTypeHeader("Application", "SDP");
... ... @@ -122,7 +124,8 @@ public class SIPRequestHeaderProvider {
122 124 SipURI requestLine = layer.getAddressFactory().createSipURI(device.getDeviceId(), host.getAddress());
123 125 //via
124 126 ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
125   - ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag);
  127 + // ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag);
  128 + ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(device.getHost().getIp(), device.getHost().getPort(), device.getTransport(), viaTag);
126 129 viaHeader.setRPort();
127 130 viaHeaders.add(viaHeader);
128 131 //from
... ... @@ -151,6 +154,7 @@ public class SIPRequestHeaderProvider {
151 154 request = layer.getMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards);
152 155  
153 156 Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), sipConfig.getSipIp()+":"+sipConfig.getSipPort()));
  157 + // Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), device.getHost().getIp()+":"+device.getHost().getPort()));
154 158 request.addHeader(layer.getHeaderFactory().createContactHeader(concatAddress));
155 159  
156 160 ContentTypeHeader contentTypeHeader = layer.getHeaderFactory().createContentTypeHeader("Application", "SDP");
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/impl/SIPCommander.java
... ... @@ -7,10 +7,13 @@ import javax.sip.Dialog;
7 7 import javax.sip.InvalidArgumentException;
8 8 import javax.sip.SipException;
9 9 import javax.sip.TransactionDoesNotExistException;
  10 +import javax.sip.address.Address;
  11 +import javax.sip.address.SipURI;
10 12 import javax.sip.header.ViaHeader;
11 13 import javax.sip.message.Request;
12 14  
13 15 import org.springframework.beans.factory.annotation.Autowired;
  16 +import org.springframework.boot.autoconfigure.security.SecurityProperties.Headers;
14 17 import org.springframework.stereotype.Component;
15 18  
16 19 import com.genersoft.iot.vmp.conf.SipConfig;
... ... @@ -21,9 +24,12 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
21 24 import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
22 25 import com.genersoft.iot.vmp.gb28181.utils.DateUtil;
23 26  
  27 +import java.util.regex.Pattern;
  28 +import java.util.regex.Matcher;
  29 +
24 30 /**
25 31 * @Description:设备能力接口,用于定义设备的控制、查询能力
26   - * @author: swwheihei
  32 + * @author: songww
27 33 * @date: 2020年5月3日 下午9:22:48
28 34 */
29 35 @Component
... ... @@ -94,6 +100,49 @@ public class SIPCommander implements ISIPCommander {
94 100 return ptzCmd(device, channelId, 0, 0, inOut, 0, zoomSpeed);
95 101 }
96 102  
  103 + /**
  104 + * 云台指令码计算
  105 + *
  106 + * @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
  107 + * @param upDown 镜头上移下移 0:停止 1:上移 2:下移
  108 + * @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
  109 + * @param moveSpeed 镜头移动速度 默认 0XFF (0-255)
  110 + * @param zoomSpeed 镜头缩放速度 默认 0X1 (0-255)
  111 + */
  112 + public static String cmdString(int leftRight, int upDown, int inOut, int moveSpeed, int zoomSpeed) {
  113 + int cmdCode = 0;
  114 + if (leftRight == 2) {
  115 + cmdCode|=0x01; // 右移
  116 + } else if(leftRight == 1) {
  117 + cmdCode|=0x02; // 左移
  118 + }
  119 + if (upDown == 2) {
  120 + cmdCode|=0x04; // 下移
  121 + } else if(upDown == 1) {
  122 + cmdCode|=0x08; // 上移
  123 + }
  124 + if (inOut == 2) {
  125 + cmdCode |= 0x10; // 放大
  126 + } else if(inOut == 1) {
  127 + cmdCode |= 0x20; // 缩小
  128 + }
  129 + StringBuilder builder = new StringBuilder("A50F01");
  130 + String strTmp;
  131 + strTmp = String.format("%02X", cmdCode);
  132 + builder.append(strTmp, 0, 2);
  133 + strTmp = String.format("%02X", moveSpeed);
  134 + builder.append(strTmp, 0, 2);
  135 + builder.append(strTmp, 0, 2);
  136 + strTmp = String.format("%X", zoomSpeed);
  137 + builder.append(strTmp, 0, 1).append("0");
  138 + //计算校验码
  139 + int checkCode = (0XA5 + 0X0F + 0X01 + cmdCode + moveSpeed + moveSpeed + (zoomSpeed /*<< 4*/ & 0XF0)) % 0X100;
  140 + strTmp = String.format("%02X", checkCode);
  141 + builder.append(strTmp, 0, 2);
  142 + return builder.toString();
  143 +}
  144 +
  145 +
97 146 /**
98 147 * 云台控制,支持方向与缩放控制
99 148 *
... ... @@ -109,13 +158,14 @@ public class SIPCommander implements ISIPCommander {
109 158 public boolean ptzCmd(Device device, String channelId, int leftRight, int upDown, int inOut, int moveSpeed,
110 159 int zoomSpeed) {
111 160 try {
  161 + String cmdStr= cmdString(leftRight, upDown, inOut, moveSpeed, zoomSpeed);
112 162 StringBuffer ptzXml = new StringBuffer(200);
113 163 ptzXml.append("<?xml version=\"1.0\" ?>");
114 164 ptzXml.append("<Control>");
115 165 ptzXml.append("<CmdType>DeviceControl</CmdType>");
116 166 ptzXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>");
117 167 ptzXml.append("<DeviceID>" + channelId + "</DeviceID>");
118   - ptzXml.append("<PTZCmd>" + "</PTZCmd>");
  168 + ptzXml.append("<PTZCmd>" + cmdStr + "</PTZCmd>");
119 169 ptzXml.append("<Info>");
120 170 ptzXml.append("</Info>");
121 171 ptzXml.append("</Control>");
... ... @@ -123,7 +173,6 @@ public class SIPCommander implements ISIPCommander {
123 173 Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtzTag", "ToPtzTag");
124 174  
125 175 transmitRequest(device, request);
126   -
127 176 return true;
128 177 } catch (SipException | ParseException | InvalidArgumentException e) {
129 178 e.printStackTrace();
... ... @@ -245,6 +294,13 @@ public class SIPCommander implements ISIPCommander {
245 294 return;
246 295 }
247 296 Request byeRequest = dialog.createRequest(Request.BYE);
  297 + SipURI byeURI = (SipURI) byeRequest.getRequestURI();
  298 + String vh = transaction.getRequest().getHeader(ViaHeader.NAME).toString();
  299 + Pattern p = Pattern.compile("(\\d+\\.\\d+\\.\\d+\\.\\d+)\\:(\\d+)");
  300 + Matcher matcher = p.matcher(vh);
  301 + if (matcher.find()) {
  302 + byeURI.setHost(matcher.group(1));
  303 + }
248 304 ViaHeader viaHeader = (ViaHeader) byeRequest.getHeader(ViaHeader.NAME);
249 305 String protocol = viaHeader.getTransport().toUpperCase();
250 306 ClientTransaction clientTransaction = null;
... ... @@ -258,6 +314,8 @@ public class SIPCommander implements ISIPCommander {
258 314 e.printStackTrace();
259 315 } catch (SipException e) {
260 316 e.printStackTrace();
  317 + } catch (ParseException e) {
  318 + e.printStackTrace();
261 319 }
262 320 }
263 321  
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/ISIPRequestProcessor.java
... ... @@ -6,7 +6,7 @@ import com.genersoft.iot.vmp.gb28181.SipLayer;
6 6  
7 7 /**
8 8 * @Description:处理接收IPCamera发来的SIP协议请求消息
9   - * @author: swwheihei
  9 + * @author: songww
10 10 * @date: 2020年5月3日 下午4:42:22
11 11 */
12 12 public interface ISIPRequestProcessor {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/AckRequestProcessor.java
... ... @@ -16,7 +16,7 @@ import gov.nist.javax.sip.header.CSeq;
16 16  
17 17 /**
18 18 * @Description:ACK请求处理器
19   - * @author: swwheihei
  19 + * @author: songww
20 20 * @date: 2020年5月3日 下午5:31:45
21 21 */
22 22 @Component
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/ByeRequestProcessor.java
... ... @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
10 10  
11 11 /**
12 12 * @Description: BYE请求处理器
13   - * @author: swwheihei
  13 + * @author: songww
14 14 * @date: 2020年5月3日 下午5:32:05
15 15 */
16 16 @Component
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/CancelRequestProcessor.java
... ... @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
10 10  
11 11 /**
12 12 * @Description:CANCEL请求处理器
13   - * @author: swwheihei
  13 + * @author: songww
14 14 * @date: 2020年5月3日 下午5:32:23
15 15 */
16 16 @Component
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/InviteRequestProcessor.java
... ... @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
10 10  
11 11 /**
12 12 * @Description:处理INVITE请求
13   - * @author: swwheihei
  13 + * @author: songww
14 14 * @date: 2020年5月3日 下午4:43:52
15 15 */
16 16 @Component
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
... ... @@ -43,7 +43,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil;
43 43  
44 44 /**
45 45 * @Description:MESSAGE请求处理器
46   - * @author: swwheihei
  46 + * @author: songww
47 47 * @date: 2020年5月3日 下午5:32:41
48 48 */
49 49 @Component
... ... @@ -100,6 +100,7 @@ public class MessageRequestProcessor implements ISIPRequestProcessor {
100 100  
101 101 Request request = evt.getRequest();
102 102 SAXReader reader = new SAXReader();
  103 + reader.setEncoding("gbk");
103 104 Document xml;
104 105 try {
105 106 xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
... ... @@ -375,7 +376,7 @@ public class MessageRequestProcessor implements ISIPRequestProcessor {
375 376 private Element getRootElement(RequestEvent evt) throws DocumentException {
376 377 Request request = evt.getRequest();
377 378 SAXReader reader = new SAXReader();
378   - reader.setEncoding("GB2312");
  379 + reader.setEncoding("gbk");
379 380 Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
380 381 return xml.getRootElement();
381 382 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/OtherRequestProcessor.java
... ... @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
10 10  
11 11 /**
12 12 * @Description:暂不支持的消息请求处理器
13   - * @author: swwheihei
  13 + * @author: songww
14 14 * @date: 2020年5月3日 下午5:32:59
15 15 */
16 16 @Component
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/RegisterRequestProcessor.java
... ... @@ -38,7 +38,7 @@ import gov.nist.javax.sip.header.Expires;
38 38  
39 39 /**
40 40 * @Description:收到注册请求 处理
41   - * @author: swwheihei
  41 + * @author: songww
42 42 * @date: 2020年5月3日 下午4:47:25
43 43 */
44 44 @Component
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/SubscribeRequestProcessor.java
... ... @@ -17,7 +17,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
17 17  
18 18 /**
19 19 * @Description:SUBSCRIBE请求处理器
20   - * @author: swwheihei
  20 + * @author: songww
21 21 * @date: 2020年5月3日 下午5:31:20
22 22 */
23 23 @Component
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/ISIPResponseProcessor.java
1 1 package com.genersoft.iot.vmp.gb28181.transmit.response;
2 2  
  3 +import java.text.ParseException;
  4 +
3 5 import javax.sip.ResponseEvent;
4 6  
5 7 import com.genersoft.iot.vmp.conf.SipConfig;
... ... @@ -7,11 +9,11 @@ import com.genersoft.iot.vmp.gb28181.SipLayer;
7 9  
8 10 /**
9 11 * @Description:处理接收IPCamera发来的SIP协议响应消息
10   - * @author: swwheihei
  12 + * @author: songww
11 13 * @date: 2020年5月3日 下午4:42:22
12 14 */
13 15 public interface ISIPResponseProcessor {
14 16  
15   - public void process(ResponseEvent evt, SipLayer layer, SipConfig config);
  17 + public void process(ResponseEvent evt, SipLayer layer, SipConfig config) throws ParseException;
16 18  
17 19 }
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/ByeResponseProcessor.java
... ... @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
10 10  
11 11 /**
12 12 * @Description: BYE请求响应器
13   - * @author: swwheihei
  13 + * @author: songww
14 14 * @date: 2020年5月3日 下午5:32:05
15 15 */
16 16 @Component
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/CancelResponseProcessor.java
... ... @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
10 10  
11 11 /**
12 12 * @Description:CANCEL响应处理器
13   - * @author: swwheihei
  13 + * @author: songww
14 14 * @date: 2020年5月3日 下午5:32:23
15 15 */
16 16 @Component
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java
... ... @@ -2,7 +2,6 @@ package com.genersoft.iot.vmp.gb28181.transmit.response.impl;
2 2  
3 3 import java.text.ParseException;
4 4  
5   -import javax.sip.ClientTransaction;
6 5 import javax.sip.Dialog;
7 6 import javax.sip.InvalidArgumentException;
8 7 import javax.sip.ResponseEvent;
... ... @@ -22,57 +21,76 @@ import com.genersoft.iot.vmp.gb28181.SipLayer;
22 21 import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorFactory;
23 22 import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
24 23  
25   -/**
26   - * @Description:处理INVITE响应
27   - * @author: swwheihei
28   - * @date: 2020年5月3日 下午4:43:52
  24 +
  25 +/**
  26 + * @Description:处理INVITE响应
  27 + * @author: songww
  28 + * @date: 2020年5月3日 下午4:43:52
29 29 */
30 30 @Component
31 31 public class InviteResponseProcessor implements ISIPResponseProcessor {
32 32  
33 33 private final static Logger logger = LoggerFactory.getLogger(SIPProcessorFactory.class);
34   -
  34 +
35 35 /**
36 36 * 处理invite响应
37 37 *
38   - * @param evt
39   - * 响应消息
40   - */
  38 + * @param evt 响应消息
  39 + * @throws ParseException
  40 + */
41 41 @Override
42   - public void process(ResponseEvent evt, SipLayer layer, SipConfig config) {
  42 + public void process(ResponseEvent evt, SipLayer layer, SipConfig config) throws ParseException {
43 43 try {
44 44 Response response = evt.getResponse();
45 45 int statusCode = response.getStatusCode();
46   - //trying不会回复
47   - if(statusCode == Response.TRYING){
48   -
  46 + // trying不会回复
  47 + if (statusCode == Response.TRYING) {
49 48 }
50   - //成功响应
51   - //下发ack
52   - if(statusCode == Response.OK){
53   -// ClientTransaction clientTransaction = evt.getClientTransaction();
54   -// if(clientTransaction == null){
55   -// logger.error("回复ACK时,clientTransaction为null >>> {}",response);
56   -// return;
57   -// }
58   -// Dialog clientDialog = clientTransaction.getDialog();
59   -//
60   -// CSeqHeader clientCSeqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
61   -// long cseqId = clientCSeqHeader.getSeqNumber();
62   -// /*
63   -// createAck函数,创建的ackRequest,会采用Invite响应的200OK,中的contact字段中的地址,作为目标地址。
64   -// 有的终端传上来的可能还是内网地址,会造成ack发送不出去。接受不到音视频流
65   -// 所以在此处统一替换地址。和响应消息的Via头中的地址保持一致。
66   -// */
67   -// Request ackRequest = clientDialog.createAck(cseqId);
68   -// SipURI requestURI = (SipURI) ackRequest.getRequestURI();
69   -// ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME);
70   -// requestURI.setHost(viaHeader.getHost());
71   -// requestURI.setPort(viaHeader.getPort());
72   -// clientDialog.sendAck(ackRequest);
73   -
  49 + // 成功响应
  50 + // 下发ack
  51 + if (statusCode == Response.OK) {
  52 + // ClientTransaction clientTransaction = evt.getClientTransaction();
  53 + // if(clientTransaction == null){
  54 + // logger.error("回复ACK时,clientTransaction为null >>> {}",response);
  55 + // return;
  56 + // }
  57 + // Dialog clientDialog = clientTransaction.getDialog();
  58 +
  59 + // CSeqHeader clientCSeqHeader = (CSeqHeader)
  60 + // response.getHeader(CSeqHeader.NAME);
  61 + // long cseqId = clientCSeqHeader.getSeqNumber();
  62 + // /*
  63 + // createAck函数,创建的ackRequest,会采用Invite响应的200OK,中的contact字段中的地址,作为目标地址。
  64 + // 有的终端传上来的可能还是内网地址,会造成ack发送不出去。接受不到音视频流
  65 + // 所以在此处统一替换地址。和响应消息的Via头中的地址保持一致。
  66 + // */
  67 + // Request ackRequest = clientDialog.createAck(cseqId);
  68 + // SipURI requestURI = (SipURI) ackRequest.getRequestURI();
  69 + // ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME);
  70 + // try {
  71 + // requestURI.setHost(viaHeader.getHost());
  72 + // } catch (Exception e) {
  73 + // e.printStackTrace();
  74 + // }
  75 + // requestURI.setPort(viaHeader.getPort());
  76 + // clientDialog.sendAck(ackRequest);
  77 +
74 78 Dialog dialog = evt.getDialog();
75   - Request reqAck =dialog.createAck(1L);
  79 + CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
  80 + Request reqAck = dialog.createAck(cseq.getSeqNumber());
  81 +
  82 + SipURI requestURI = (SipURI) reqAck.getRequestURI();
  83 + ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME);
  84 + // String viaHost =viaHeader.getHost();
  85 + //getHost()函数取回的IP地址是“[xxx.xxx.xxx.xxx:yyyy]”的格式,需用正则表达式截取为“xxx.xxx.xxx.xxx"格式
  86 + // Pattern p = Pattern.compile("(?<=//|)((\\w)+\\.)+\\w+");
  87 + // Matcher matcher = p.matcher(viaHeader.getHost());
  88 + // if (matcher.find()) {
  89 + // requestURI.setHost(matcher.group());
  90 + // }
  91 + requestURI.setHost(viaHeader.getHost());
  92 + requestURI.setPort(viaHeader.getPort());
  93 + reqAck.setRequestURI(requestURI);
76 94 dialog.sendAck(reqAck);
77 95 }
78 96 } catch (InvalidArgumentException | SipException e) {
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/OtherResponseProcessor.java
... ... @@ -10,7 +10,7 @@ import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
10 10  
11 11 /**
12 12 * @Description:暂不支持的消息响应处理器
13   - * @author: swwheihei
  13 + * @author: songww
14 14 * @date: 2020年5月3日 下午5:32:59
15 15 */
16 16 @Component
... ...
src/main/java/com/genersoft/iot/vmp/gb28181/utils/DateUtil.java
... ... @@ -7,7 +7,7 @@ import java.util.Locale;
7 7  
8 8 /**
9 9 * @Description:时间工具类,主要处理ISO 8601格式转换
10   - * @author: swwheihei
  10 + * @author: songww
11 11 * @date: 2020年5月8日 下午3:24:42
12 12 */
13 13 public class DateUtil {
... ...
src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
... ... @@ -18,11 +18,11 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
18 18  
19 19 /**
20 20 * @Description:针对 ZLMediaServer的hook事件监听
21   - * @author: swwheihei
  21 + * @author: songww
22 22 * @date: 2020年5月8日 上午10:46:48
23 23 */
24 24 @RestController
25   -@RequestMapping("/hook/zlm")
  25 +@RequestMapping("/index/hook")
26 26 public class ZLMHttpHookListener {
27 27  
28 28 private final static Logger logger = LoggerFactory.getLogger(ZLMHttpHookListener.class);
... ...
src/main/java/com/genersoft/iot/vmp/storager/IVideoManagerStorager.java
... ... @@ -6,7 +6,7 @@ import com.genersoft.iot.vmp.gb28181.bean.Device;
6 6  
7 7 /**
8 8 * @Description:视频设备数据存储接口
9   - * @author: swwheihei
  9 + * @author: songww
10 10 * @date: 2020年5月6日 下午2:14:31
11 11 */
12 12 public interface IVideoManagerStorager {
... ...
src/main/java/com/genersoft/iot/vmp/storager/VideoManagerStoragerFactory.java
... ... @@ -8,7 +8,7 @@ import com.genersoft.iot.vmp.conf.VManagerConfig;
8 8  
9 9 /**
10 10 * @Description:视频设备数据存储工厂,根据存储策略,返回对应的存储器
11   - * @author: swwheihei
  11 + * @author: songww
12 12 * @date: 2020年5月6日 下午2:15:16
13 13 */
14 14 @Component
... ...
src/main/java/com/genersoft/iot/vmp/storager/jdbc/VideoManagerJdbcStoragerImpl.java
... ... @@ -11,7 +11,7 @@ import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
11 11  
12 12 /**
13 13 * @Description:视频设备数据存储-jdbc实现
14   - * @author: swwheihei
  14 + * @author: songww
15 15 * @date: 2020年5月6日 下午2:28:12
16 16 */
17 17 @Component("jdbcStorager")
... ...
src/main/java/com/genersoft/iot/vmp/storager/redis/VideoManagerRedisStoragerImpl.java
... ... @@ -13,7 +13,7 @@ import com.genersoft.iot.vmp.utils.redis.RedisUtil;
13 13  
14 14 /**
15 15 * @Description:视频设备数据存储-redis实现
16   - * @author: swwheihei
  16 + * @author: songww
17 17 * @date: 2020年5月6日 下午2:31:42
18 18 */
19 19 @Component("redisStorager")
... ...
src/main/java/com/genersoft/iot/vmp/utils/SpringBeanFactory.java
... ... @@ -7,7 +7,7 @@ import org.springframework.stereotype.Component;
7 7  
8 8 /**
9 9 * @Description:spring bean获取工厂,获取spring中的已初始化的bean
10   - * @author: swwheihei
  10 + * @author: songww
11 11 * @date: 2019年6月25日 下午4:51:52
12 12 *
13 13 */
... ...
src/main/java/com/genersoft/iot/vmp/utils/redis/FastJsonRedisSerializer.java
... ... @@ -10,7 +10,7 @@ import com.alibaba.fastjson.serializer.SerializerFeature;
10 10  
11 11 /**
12 12 * @Description:使用fastjson实现redis的序列化
13   - * @author: swwheihei
  13 + * @author: songww
14 14 * @date: 2020年5月6日 下午8:40:11
15 15 */
16 16 public class FastJsonRedisSerializer<T> implements RedisSerializer<T> {
... ...
src/main/java/com/genersoft/iot/vmp/utils/redis/RedisUtil.java
... ... @@ -13,7 +13,7 @@ import org.springframework.util.CollectionUtils;
13 13  
14 14 /**
15 15 * @Description:Redis工具类
16   - * @author: swwheihei
  16 + * @author: songww
17 17 * @date: 2020年5月6日 下午8:27:29
18 18 */
19 19 @Component
... ...
src/main/resources/application.yml
... ... @@ -26,7 +26,8 @@ spring:
26 26 server:
27 27 port: 8080
28 28 sip:
29   - ip: 10.200.64.63
  29 +# ip: 10.200.64.63
  30 + ip: 192.168.0.102
30 31 port: 5060
31 32 # 根据国标6.1.2中规定,domain宜采用ID统一编码的前十位编码。国标附录D中定义前8位为中心编码(由省级、市级、区级、基层编号组成,参照GB/T 2260-2007)
32 33 # 后两位为行业编码,定义参照附录D.3
... ... @@ -34,7 +35,8 @@ sip:
34 35 domain: 3701020049
35 36 id: 37010200492000000001
36 37 # 默认设备认证密码,后续扩展使用设备单独密码
37   - password: admin
  38 + password: admin123
38 39 media:
39   - ip: 10.200.64.88
  40 +# ip: 10.200.64.88
  41 + ip: 192.168.0.102
40 42 port: 10000
41 43 \ No newline at end of file
... ...
wikis/images/核心流程.png

33 KB | W: | H:

169 KB | W: | H:

  • 2-up
  • Swipe
  • Onion skin