src/main/java/com/genersoft/iot/vmp/gb28181/SipLayer.java
@@ -1,5 +1,6 @@ package com.genersoft.iot.vmp.gb28181; import java.text.ParseException; import java.util.Properties; import javax.annotation.PostConstruct; @@ -128,11 +129,18 @@ int status = response.getStatusCode(); if ((status >= 200) && (status < 300)) { // Success! ISIPResponseProcessor processor = processorFactory.createResponseProcessor(evt); processor.process(evt, this, sipConfig); } else if (status == Response.TRYING) { try { processor.process(evt, this, sipConfig); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } // } else if (status == Response.TRYING) { // trying不会回复 } else if ((status >= 100) && (status < 200)) { // 增加其它无需回复的响应,如101、180等 } else { logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getContent().toString()); logger.warn("接收到失败的response响应!status:" + status + ",message:" + response.getReasonPhrase()/* .getContent().toString()*/); } // trying不会回复 // if (status == Response.TRYING) { src/main/java/com/genersoft/iot/vmp/gb28181/transmit/cmd/SIPRequestHeaderProvider.java
@@ -79,7 +79,8 @@ SipURI requestLine = layer.getAddressFactory().createSipURI(channelId, host.getAddress()); //via ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag); // ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag); ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(device.getHost().getIp(), device.getHost().getPort(), device.getTransport(), viaTag); viaHeader.setRPort(); viaHeaders.add(viaHeader); //from @@ -108,6 +109,7 @@ request = layer.getMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), sipConfig.getSipIp()+":"+sipConfig.getSipPort())); // Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), device.getHost().getIp()+":"+device.getHost().getPort())); request.addHeader(layer.getHeaderFactory().createContactHeader(concatAddress)); ContentTypeHeader contentTypeHeader = layer.getHeaderFactory().createContentTypeHeader("Application", "SDP"); @@ -122,7 +124,8 @@ SipURI requestLine = layer.getAddressFactory().createSipURI(device.getDeviceId(), host.getAddress()); //via ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>(); ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag); // ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(sipConfig.getSipIp(), sipConfig.getSipPort(), device.getTransport(), viaTag); ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(device.getHost().getIp(), device.getHost().getPort(), device.getTransport(), viaTag); viaHeader.setRPort(); viaHeaders.add(viaHeader); //from @@ -151,6 +154,7 @@ request = layer.getMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards); Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), sipConfig.getSipIp()+":"+sipConfig.getSipPort())); // Address concatAddress = layer.getAddressFactory().createAddress(layer.getAddressFactory().createSipURI(sipConfig.getSipId(), device.getHost().getIp()+":"+device.getHost().getPort())); request.addHeader(layer.getHeaderFactory().createContactHeader(concatAddress)); 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.InvalidArgumentException; import javax.sip.SipException; import javax.sip.TransactionDoesNotExistException; import javax.sip.address.Address; import javax.sip.address.SipURI; import javax.sip.header.ViaHeader; import javax.sip.message.Request; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.security.SecurityProperties.Headers; import org.springframework.stereotype.Component; import com.genersoft.iot.vmp.conf.SipConfig; @@ -20,6 +23,9 @@ import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander; import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider; import com.genersoft.iot.vmp.gb28181.utils.DateUtil; import java.util.regex.Pattern; import java.util.regex.Matcher; /** * @Description:设备能力接口,用于定义设备的控制、查询能力 @@ -288,6 +294,13 @@ return; } Request byeRequest = dialog.createRequest(Request.BYE); SipURI byeURI = (SipURI) byeRequest.getRequestURI(); String vh = transaction.getRequest().getHeader(ViaHeader.NAME).toString(); Pattern p = Pattern.compile("(\\d+\\.\\d+\\.\\d+\\.\\d+)\\:(\\d+)"); Matcher matcher = p.matcher(vh); if (matcher.find()) { byeURI.setHost(matcher.group(1)); } ViaHeader viaHeader = (ViaHeader) byeRequest.getHeader(ViaHeader.NAME); String protocol = viaHeader.getTransport().toUpperCase(); ClientTransaction clientTransaction = null; @@ -301,6 +314,8 @@ e.printStackTrace(); } catch (SipException e) { e.printStackTrace(); } catch (ParseException e) { e.printStackTrace(); } } src/main/java/com/genersoft/iot/vmp/gb28181/transmit/request/impl/MessageRequestProcessor.java
@@ -100,6 +100,7 @@ Request request = evt.getRequest(); SAXReader reader = new SAXReader(); reader.setEncoding("gbk"); Document xml; try { xml = reader.read(new ByteArrayInputStream(request.getRawContent())); @@ -375,7 +376,7 @@ private Element getRootElement(RequestEvent evt) throws DocumentException { Request request = evt.getRequest(); SAXReader reader = new SAXReader(); reader.setEncoding("GB2312"); reader.setEncoding("gbk"); Document xml = reader.read(new ByteArrayInputStream(request.getRawContent())); return xml.getRootElement(); } src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/ISIPResponseProcessor.java
@@ -1,5 +1,7 @@ package com.genersoft.iot.vmp.gb28181.transmit.response; import java.text.ParseException; import javax.sip.ResponseEvent; import com.genersoft.iot.vmp.conf.SipConfig; @@ -12,6 +14,6 @@ */ public interface ISIPResponseProcessor { public void process(ResponseEvent evt, SipLayer layer, SipConfig config); public void process(ResponseEvent evt, SipLayer layer, SipConfig config) throws ParseException; } src/main/java/com/genersoft/iot/vmp/gb28181/transmit/response/impl/InviteResponseProcessor.java
@@ -7,8 +7,11 @@ import javax.sip.InvalidArgumentException; import javax.sip.ResponseEvent; import javax.sip.SipException; import javax.sip.address.Address; import javax.sip.address.SipURI; import javax.sip.header.CSeqHeader; import javax.sip.header.ContactHeader; import javax.sip.header.FromHeader; import javax.sip.header.ViaHeader; import javax.sip.message.Request; import javax.sip.message.Response; @@ -22,57 +25,78 @@ import com.genersoft.iot.vmp.gb28181.transmit.SIPProcessorFactory; import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor; /** // import java.util.regex.Pattern; // import java.util.regex.Matcher; /** * @Description:处理INVITE响应 * @author: songww * @date: 2020年5月3日 下午4:43:52 * @date: 2020年5月3日 下午4:43:52 */ @Component public class InviteResponseProcessor implements ISIPResponseProcessor { private final static Logger logger = LoggerFactory.getLogger(SIPProcessorFactory.class); /** * 处理invite响应 * * @param evt * 响应消息 */ * @param evt 响应消息 * @throws ParseException */ @Override public void process(ResponseEvent evt, SipLayer layer, SipConfig config) { public void process(ResponseEvent evt, SipLayer layer, SipConfig config) throws ParseException { try { Response response = evt.getResponse(); int statusCode = response.getStatusCode(); //trying不会回复 if(statusCode == Response.TRYING){ // trying不会回复 if (statusCode == Response.TRYING) { } //成功响应 //下发ack if(statusCode == Response.OK){ // ClientTransaction clientTransaction = evt.getClientTransaction(); // if(clientTransaction == null){ // logger.error("回复ACK时,clientTransaction为null >>> {}",response); // return; // } // Dialog clientDialog = clientTransaction.getDialog(); // // CSeqHeader clientCSeqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME); // long cseqId = clientCSeqHeader.getSeqNumber(); // /* // createAck函数,创建的ackRequest,会采用Invite响应的200OK,中的contact字段中的地址,作为目标地址。 // 有的终端传上来的可能还是内网地址,会造成ack发送不出去。接受不到音视频流 // 所以在此处统一替换地址。和响应消息的Via头中的地址保持一致。 // */ // Request ackRequest = clientDialog.createAck(cseqId); // SipURI requestURI = (SipURI) ackRequest.getRequestURI(); // ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME); // requestURI.setHost(viaHeader.getHost()); // requestURI.setPort(viaHeader.getPort()); // clientDialog.sendAck(ackRequest); // 成功响应 // 下发ack if (statusCode == Response.OK) { // ClientTransaction clientTransaction = evt.getClientTransaction(); // if(clientTransaction == null){ // logger.error("回复ACK时,clientTransaction为null >>> {}",response); // return; // } // Dialog clientDialog = clientTransaction.getDialog(); // CSeqHeader clientCSeqHeader = (CSeqHeader) // response.getHeader(CSeqHeader.NAME); // long cseqId = clientCSeqHeader.getSeqNumber(); // /* // createAck函数,创建的ackRequest,会采用Invite响应的200OK,中的contact字段中的地址,作为目标地址。 // 有的终端传上来的可能还是内网地址,会造成ack发送不出去。接受不到音视频流 // 所以在此处统一替换地址。和响应消息的Via头中的地址保持一致。 // */ // Request ackRequest = clientDialog.createAck(cseqId); // SipURI requestURI = (SipURI) ackRequest.getRequestURI(); // ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME); // try { // requestURI.setHost(viaHeader.getHost()); // } catch (Exception e) { // e.printStackTrace(); // } // requestURI.setPort(viaHeader.getPort()); // clientDialog.sendAck(ackRequest); Dialog dialog = evt.getDialog(); Request reqAck =dialog.createAck(1L); CSeqHeader cseq = (CSeqHeader) response.getHeader(CSeqHeader.NAME); Request reqAck = dialog.createAck(cseq.getSeqNumber()); SipURI requestURI = (SipURI) reqAck.getRequestURI(); ViaHeader viaHeader = (ViaHeader) response.getHeader(ViaHeader.NAME); // String viaHost =viaHeader.getHost(); //getHost()函数取回的IP地址是“[xxx.xxx.xxx.xxx:yyyy]”的格式,需用正则表达式截取为“xxx.xxx.xxx.xxx"格式 // Pattern p = Pattern.compile("(?<=//|)((\\w)+\\.)+\\w+"); // Matcher matcher = p.matcher(viaHeader.getHost()); // if (matcher.find()) { // requestURI.setHost(matcher.group()); // } requestURI.setHost(viaHeader.getHost()); requestURI.setPort(viaHeader.getPort()); reqAck.setRequestURI(requestURI); dialog.sendAck(reqAck); } } catch (InvalidArgumentException | SipException e) { src/main/java/com/genersoft/iot/vmp/media/zlm/ZLMHttpHookListener.java
@@ -22,7 +22,7 @@ * @date: 2020年5月8日 上午10:46:48 */ @RestController @RequestMapping("/hook/zlm") @RequestMapping("/index/hook") public class ZLMHttpHookListener { private final static Logger logger = LoggerFactory.getLogger(ZLMHttpHookListener.class);