初始提交
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit;
|
||||
|
||||
import javax.sip.RequestEvent;
|
||||
import javax.sip.ResponseEvent;
|
||||
import javax.sip.header.CSeqHeader;
|
||||
import javax.sip.message.Request;
|
||||
import javax.sip.message.Response;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.AckRequestProcessor;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.ByeRequestProcessor;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.CancelRequestProcessor;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.InviteRequestProcessor;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.MessageRequestProcessor;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.OtherRequestProcessor;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.RegisterRequestProcessor;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.request.impl.SubscribeRequestProcessor;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.ByeResponseProcessor;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.CancelResponseProcessor;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.InviteResponseProcessor;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.response.impl.OtherResponseProcessor;
|
||||
|
||||
/**
|
||||
* @Description:TODO(这里用一句话描述这个类的作用)
|
||||
* @author: songww
|
||||
* @date: 2020年5月3日 下午4:24:37
|
||||
*/
|
||||
@Component
|
||||
public class SIPProcessorFactory {
|
||||
|
||||
@Autowired
|
||||
private InviteRequestProcessor inviteRequestProcessor;
|
||||
|
||||
@Autowired
|
||||
private RegisterRequestProcessor registerRequestProcessor;
|
||||
|
||||
@Autowired
|
||||
private SubscribeRequestProcessor subscribeRequestProcessor;
|
||||
|
||||
@Autowired
|
||||
private AckRequestProcessor ackRequestProcessor;
|
||||
|
||||
@Autowired
|
||||
private ByeRequestProcessor byeRequestProcessor;
|
||||
|
||||
@Autowired
|
||||
private CancelRequestProcessor cancelRequestProcessor;
|
||||
|
||||
@Autowired
|
||||
private MessageRequestProcessor messageRequestProcessor;
|
||||
|
||||
@Autowired
|
||||
private OtherRequestProcessor otherRequestProcessor;
|
||||
|
||||
@Autowired
|
||||
private InviteResponseProcessor inviteResponseProcessor;
|
||||
|
||||
@Autowired
|
||||
private ByeResponseProcessor byeResponseProcessor;
|
||||
|
||||
@Autowired
|
||||
private CancelResponseProcessor cancelResponseProcessor;
|
||||
|
||||
@Autowired
|
||||
private OtherResponseProcessor otherResponseProcessor;
|
||||
|
||||
|
||||
public ISIPRequestProcessor createRequestProcessor(RequestEvent evt) {
|
||||
Request request = evt.getRequest();
|
||||
String method = request.getMethod();
|
||||
|
||||
if (Request.INVITE.equals(method)) {
|
||||
return inviteRequestProcessor;
|
||||
} else if (Request.REGISTER.equals(method)) {
|
||||
return registerRequestProcessor;
|
||||
} else if (Request.SUBSCRIBE.equals(method)) {
|
||||
return subscribeRequestProcessor;
|
||||
} else if (Request.ACK.equals(method)) {
|
||||
return ackRequestProcessor;
|
||||
} else if (Request.BYE.equals(method)) {
|
||||
return byeRequestProcessor;
|
||||
} else if (Request.CANCEL.equals(method)) {
|
||||
return cancelRequestProcessor;
|
||||
} else if (Request.MESSAGE.equals(method)) {
|
||||
return messageRequestProcessor;
|
||||
} else {
|
||||
return otherRequestProcessor;
|
||||
}
|
||||
}
|
||||
|
||||
public ISIPResponseProcessor createResponseProcessor(ResponseEvent evt) {
|
||||
Response response = evt.getResponse();
|
||||
CSeqHeader cseqHeader = (CSeqHeader) response.getHeader(CSeqHeader.NAME);
|
||||
String method = cseqHeader.getMethod();
|
||||
if(Request.INVITE.equals(method)){
|
||||
return inviteResponseProcessor;
|
||||
} else if (Request.BYE.equals(method)) {
|
||||
return byeResponseProcessor;
|
||||
} else if (Request.CANCEL.equals(method)) {
|
||||
return cancelResponseProcessor;
|
||||
} else {
|
||||
return otherResponseProcessor;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit.cmd;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
|
||||
/**
|
||||
* @Description:设备能力接口,用于定义设备的控制、查询能力
|
||||
* @author: songww
|
||||
* @date: 2020年5月3日 下午9:16:34
|
||||
*/
|
||||
public interface ISIPCommander {
|
||||
|
||||
/**
|
||||
* 云台方向放控制,使用配置文件中的默认镜头移动速度
|
||||
*
|
||||
* @param deviceId 控制设备
|
||||
* @param channelId 预览通道
|
||||
* @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
|
||||
* @param upDown 镜头上移下移 0:停止 1:上移 2:下移
|
||||
* @param moveSpeed 镜头移动速度
|
||||
*/
|
||||
public boolean ptzdirectCmd(String deviceId,String channelId,int leftRight, int upDown);
|
||||
|
||||
/**
|
||||
* 云台方向放控制
|
||||
*
|
||||
* @param deviceId 控制设备
|
||||
* @param channelId 预览通道
|
||||
* @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
|
||||
* @param upDown 镜头上移下移 0:停止 1:上移 2:下移
|
||||
* @param moveSpeed 镜头移动速度
|
||||
*/
|
||||
public boolean ptzdirectCmd(String deviceId,String channelId,int leftRight, int upDown, int moveSpeed);
|
||||
|
||||
/**
|
||||
* 云台缩放控制,使用配置文件中的默认镜头缩放速度
|
||||
*
|
||||
* @param deviceId 控制设备
|
||||
* @param channelId 预览通道
|
||||
* @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
|
||||
*/
|
||||
public boolean ptzZoomCmd(String deviceId,String channelId,int inOut);
|
||||
|
||||
/**
|
||||
* 云台缩放控制
|
||||
*
|
||||
* @param deviceId 控制设备
|
||||
* @param channelId 预览通道
|
||||
* @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
|
||||
* @param zoomSpeed 镜头缩放速度
|
||||
*/
|
||||
public boolean ptzZoomCmd(String deviceId,String channelId,int inOut, int moveSpeed);
|
||||
|
||||
/**
|
||||
* 云台控制,支持方向与缩放控制
|
||||
*
|
||||
* @param deviceId 控制设备
|
||||
* @param channelId 预览通道
|
||||
* @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
|
||||
* @param upDown 镜头上移下移 0:停止 1:上移 2:下移
|
||||
* @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
|
||||
* @param moveSpeed 镜头移动速度
|
||||
* @param zoomSpeed 镜头缩放速度
|
||||
*/
|
||||
public boolean ptzCmd(String deviceId,String channelId,int leftRight, int upDown, int inOut, int moveSpeed, int zoomSpeed);
|
||||
|
||||
/**
|
||||
* 请求预览视频流
|
||||
*
|
||||
* @param deviceId 视频设备
|
||||
* @param channelId 预览通道
|
||||
*/
|
||||
public String playStreamCmd(String deviceId,String channelId);
|
||||
|
||||
/**
|
||||
* 语音广播
|
||||
*
|
||||
* @param deviceId 视频设备
|
||||
* @param channelId 预览通道
|
||||
*/
|
||||
public String audioBroadcastCmd(String deviceId,String channelId);
|
||||
|
||||
/**
|
||||
* 音视频录像控制
|
||||
*
|
||||
* @param deviceId 视频设备
|
||||
* @param channelId 预览通道
|
||||
*/
|
||||
public String recordCmd(String deviceId,String channelId);
|
||||
|
||||
/**
|
||||
* 报警布防/撤防命令
|
||||
*
|
||||
* @param deviceId 视频设备
|
||||
*/
|
||||
public String guardCmd(String deviceId);
|
||||
|
||||
/**
|
||||
* 报警复位命令
|
||||
*
|
||||
* @param deviceId 视频设备
|
||||
*/
|
||||
public String alarmCmd(String deviceId);
|
||||
|
||||
/**
|
||||
* 强制关键帧命令,设备收到此命令应立刻发送一个IDR帧
|
||||
*
|
||||
* @param deviceId 视频设备
|
||||
* @param channelId 预览通道
|
||||
*/
|
||||
public String iFameCmd(String deviceId,String channelId);
|
||||
|
||||
/**
|
||||
* 看守位控制命令
|
||||
*
|
||||
* @param deviceId 视频设备
|
||||
*/
|
||||
public String homePositionCmd(String deviceId);
|
||||
|
||||
/**
|
||||
* 设备配置命令
|
||||
*
|
||||
* @param deviceId 视频设备
|
||||
*/
|
||||
public String deviceConfigCmd(String deviceId);
|
||||
|
||||
|
||||
/**
|
||||
* 查询设备状态
|
||||
*
|
||||
* @param device 视频设备
|
||||
*/
|
||||
public boolean deviceStatusQuery(Device device);
|
||||
|
||||
/**
|
||||
* 查询设备信息
|
||||
*
|
||||
* @param device 视频设备
|
||||
* @return
|
||||
*/
|
||||
public boolean deviceInfoQuery(Device device);
|
||||
|
||||
/**
|
||||
* 查询目录列表
|
||||
*
|
||||
* @param device 视频设备
|
||||
*/
|
||||
public boolean catalogQuery(Device device);
|
||||
|
||||
/**
|
||||
* 查询录像信息
|
||||
*
|
||||
* @param device 视频设备
|
||||
*/
|
||||
public boolean recordInfoQuery(Device device);
|
||||
|
||||
/**
|
||||
* 查询报警信息
|
||||
*
|
||||
* @param device 视频设备
|
||||
*/
|
||||
public boolean alarmInfoQuery(Device device);
|
||||
|
||||
/**
|
||||
* 查询设备配置
|
||||
*
|
||||
* @param device 视频设备
|
||||
*/
|
||||
public boolean configQuery(Device device);
|
||||
|
||||
/**
|
||||
* 查询设备预置位置
|
||||
*
|
||||
* @param device 视频设备
|
||||
*/
|
||||
public boolean presetQuery(Device device);
|
||||
|
||||
/**
|
||||
* 查询移动设备位置数据
|
||||
*
|
||||
* @param device 视频设备
|
||||
*/
|
||||
public boolean mobilePostitionQuery(Device device);
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit.cmd;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.sip.InvalidArgumentException;
|
||||
import javax.sip.address.Address;
|
||||
import javax.sip.address.SipURI;
|
||||
import javax.sip.header.CSeqHeader;
|
||||
import javax.sip.header.CallIdHeader;
|
||||
import javax.sip.header.ContentTypeHeader;
|
||||
import javax.sip.header.FromHeader;
|
||||
import javax.sip.header.MaxForwardsHeader;
|
||||
import javax.sip.header.ToHeader;
|
||||
import javax.sip.header.ViaHeader;
|
||||
import javax.sip.message.Request;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Host;
|
||||
|
||||
/**
|
||||
* @Description:TODO(这里用一句话描述这个类的作用)
|
||||
* @author: songww
|
||||
* @date: 2020年5月6日 上午9:29:02
|
||||
*/
|
||||
@Component
|
||||
public class SIPRequestHeaderProvider {
|
||||
|
||||
@Autowired
|
||||
private SipLayer layer;
|
||||
|
||||
@Autowired
|
||||
private SipConfig config;
|
||||
|
||||
public Request createMessageRequest(Device device, String content, String viaTag, String fromTag, String toTag) throws ParseException, InvalidArgumentException {
|
||||
Request request = null;
|
||||
Host host = device.getHost();
|
||||
// sipuri
|
||||
SipURI requestURI = layer.getAddressFactory().createSipURI(device.getDeviceId(), host.getAddress());
|
||||
// via
|
||||
ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
|
||||
ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(config.getSipIp(), config.getSipPort(),
|
||||
device.getTransport(), viaTag);
|
||||
viaHeaders.add(viaHeader);
|
||||
// from
|
||||
SipURI fromSipURI = layer.getAddressFactory().createSipURI(device.getDeviceId(),
|
||||
config.getSipIp() + ":" + config.getSipPort());
|
||||
Address fromAddress = layer.getAddressFactory().createAddress(fromSipURI);
|
||||
FromHeader fromHeader = layer.getHeaderFactory().createFromHeader(fromAddress, fromTag);
|
||||
// to
|
||||
SipURI toSipURI = layer.getAddressFactory().createSipURI(device.getDeviceId(), host.getAddress());
|
||||
Address toAddress = layer.getAddressFactory().createAddress(toSipURI);
|
||||
ToHeader toHeader = layer.getHeaderFactory().createToHeader(toAddress, toTag);
|
||||
// callid
|
||||
CallIdHeader callIdHeader = device.getTransport().equals("TCP") ? layer.getTcpSipProvider().getNewCallId()
|
||||
: layer.getUdpSipProvider().getNewCallId();
|
||||
// Forwards
|
||||
MaxForwardsHeader maxForwards = layer.getHeaderFactory().createMaxForwardsHeader(70);
|
||||
// ceq
|
||||
CSeqHeader cSeqHeader = layer.getHeaderFactory().createCSeqHeader(1L, Request.MESSAGE);
|
||||
|
||||
request = layer.getMessageFactory().createRequest(requestURI, Request.MESSAGE, callIdHeader, cSeqHeader, fromHeader,
|
||||
toHeader, viaHeaders, maxForwards);
|
||||
ContentTypeHeader contentTypeHeader = layer.getHeaderFactory().createContentTypeHeader("Application", "MANSCDP+xml");
|
||||
request.setContent(content, contentTypeHeader);
|
||||
return request;
|
||||
}
|
||||
|
||||
public Request createInviteRequest(Device device, String content, String viaTag, String fromTag, String toTag) throws ParseException, InvalidArgumentException {
|
||||
Request request = null;
|
||||
Host host = device.getHost();
|
||||
//请求行
|
||||
SipURI requestLine = layer.getAddressFactory().createSipURI(device.getDeviceId(), host.getAddress());
|
||||
//via
|
||||
ArrayList<ViaHeader> viaHeaders = new ArrayList<ViaHeader>();
|
||||
ViaHeader viaHeader = layer.getHeaderFactory().createViaHeader(config.getSipIp(), config.getSipPort(), device.getTransport(), viaTag);
|
||||
viaHeader.setRPort();
|
||||
viaHeaders.add(viaHeader);
|
||||
//from
|
||||
SipURI fromSipURI = layer.getAddressFactory().createSipURI(device.getDeviceId(),config.getSipIp()+":"+config.getSipPort());
|
||||
Address fromAddress = layer.getAddressFactory().createAddress(fromSipURI);
|
||||
FromHeader fromHeader = layer.getHeaderFactory().createFromHeader(fromAddress, fromTag); //必须要有标记,否则无法创建会话,无法回应ack
|
||||
//to
|
||||
SipURI toSipURI = layer.getAddressFactory().createSipURI(device.getDeviceId(),host.getAddress());
|
||||
Address toAddress = layer.getAddressFactory().createAddress(toSipURI);
|
||||
ToHeader toHeader = layer.getHeaderFactory().createToHeader(toAddress,null);
|
||||
|
||||
//callid
|
||||
CallIdHeader callIdHeader = null;
|
||||
if(device.getTransport().equals("TCP")) {
|
||||
callIdHeader = layer.getTcpSipProvider().getNewCallId();
|
||||
}
|
||||
if(device.getTransport().equals("UDP")) {
|
||||
callIdHeader = layer.getUdpSipProvider().getNewCallId();
|
||||
}
|
||||
|
||||
//Forwards
|
||||
MaxForwardsHeader maxForwards = layer.getHeaderFactory().createMaxForwardsHeader(70);
|
||||
//ceq
|
||||
CSeqHeader cSeqHeader = layer.getHeaderFactory().createCSeqHeader(1L, Request.INVITE);
|
||||
request = layer.getMessageFactory().createRequest(requestLine, Request.INVITE, callIdHeader, cSeqHeader,fromHeader, toHeader, viaHeaders, maxForwards);
|
||||
ContentTypeHeader contentTypeHeader = layer.getHeaderFactory().createContentTypeHeader("Application", "SDP");
|
||||
request.setContent(content, contentTypeHeader);
|
||||
return request;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl;
|
||||
|
||||
public class PtzCmdHelper {
|
||||
/**
|
||||
*
|
||||
* @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
|
||||
* @param upDown 镜头上移下移 0:停止 1:上移 2:下移
|
||||
* @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
|
||||
* @param moveSpeed 镜头移动速度 默认 0XFF (0-255)
|
||||
* @param zoomSpeed 镜头缩放速度 默认 0X1 (0-255)
|
||||
* @return
|
||||
*/
|
||||
//云台控制发送了消息,相机会一直执行,直到其他命令或者发送了停止命令,切记要考虑这个机制
|
||||
public static String create(int leftRight, int upDown, int inOut, int moveSpeed, int zoomSpeed) {
|
||||
int cmdCode = 0;
|
||||
if (leftRight == 2) cmdCode|=0x01; // 右移
|
||||
else if(leftRight == 1) cmdCode|=0x02; // 左移
|
||||
if (upDown == 2) cmdCode|=0x04; // 下移
|
||||
else if(upDown == 1) cmdCode|=0x08; // 上移
|
||||
if (inOut == 2) cmdCode |= 0x10; // 放大
|
||||
else if(inOut == 1) cmdCode |= 0x20; // 缩小
|
||||
char[] szCmd = new char[16];
|
||||
String strTmp;
|
||||
szCmd[0] = 'A'; //字节1 A5
|
||||
szCmd[1] = '5';
|
||||
szCmd[2] = '0'; //字节2 0F
|
||||
szCmd[3] = 'F';
|
||||
szCmd[4] = '0'; //字节3 地址的低8位
|
||||
szCmd[5] = '1';
|
||||
strTmp = String.format("%02X", cmdCode);
|
||||
szCmd[6] = strTmp.charAt(0); //字节4 控制码
|
||||
szCmd[7] = strTmp.charAt(1);
|
||||
strTmp = String.format("%02X", moveSpeed);
|
||||
szCmd[8] = strTmp.charAt(0); //字节5 水平控制速度
|
||||
szCmd[9] = strTmp.charAt(1);
|
||||
szCmd[10] = strTmp.charAt(0); //字节6 垂直控制速度
|
||||
szCmd[11] = strTmp.charAt(1);
|
||||
strTmp = String.format("%X", zoomSpeed);
|
||||
szCmd[12] = strTmp.charAt(0); //字节7高4位 缩放控制速度
|
||||
szCmd[13] = '0'; //字节7低4位 地址的高4位
|
||||
//计算校验码
|
||||
int nCheck = (0XA5 + 0X0F + 0X01 + cmdCode + moveSpeed + moveSpeed + (zoomSpeed << 4 & 0XF0)) % 0X100;
|
||||
strTmp = String.format("%02X", nCheck);
|
||||
szCmd[14] = strTmp.charAt(0); //字节8 校验码
|
||||
szCmd[15] = strTmp.charAt(1);
|
||||
return String.valueOf(szCmd);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,387 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit.cmd.impl;
|
||||
|
||||
import java.text.ParseException;
|
||||
import java.util.Random;
|
||||
|
||||
import javax.sip.InvalidArgumentException;
|
||||
import javax.sip.SipException;
|
||||
import javax.sip.message.Request;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.ISIPCommander;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.SIPRequestHeaderProvider;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||
|
||||
/**
|
||||
* @Description:设备能力接口,用于定义设备的控制、查询能力
|
||||
* @author: songww
|
||||
* @date: 2020年5月3日 下午9:22:48
|
||||
*/
|
||||
@Component
|
||||
public class SIPCommander implements ISIPCommander {
|
||||
|
||||
@Autowired
|
||||
private SipConfig config;
|
||||
|
||||
@Autowired
|
||||
private SIPRequestHeaderProvider headerProvider;
|
||||
|
||||
@Autowired
|
||||
private SipLayer sipLayer;
|
||||
|
||||
@Autowired
|
||||
private IVideoManagerStorager storager;
|
||||
|
||||
/**
|
||||
* 云台方向放控制,使用配置文件中的默认镜头移动速度
|
||||
*
|
||||
* @param deviceId 控制设备
|
||||
* @param channelId 预览通道
|
||||
* @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
|
||||
* @param upDown 镜头上移下移 0:停止 1:上移 2:下移
|
||||
* @param moveSpeed 镜头移动速度
|
||||
*/
|
||||
@Override
|
||||
public boolean ptzdirectCmd(String deviceId, String channelId, int leftRight, int upDown) {
|
||||
return ptzCmd(deviceId, channelId, leftRight, upDown, 0, config.getSpeed(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 云台方向放控制
|
||||
*
|
||||
* @param deviceId 控制设备
|
||||
* @param channelId 预览通道
|
||||
* @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
|
||||
* @param upDown 镜头上移下移 0:停止 1:上移 2:下移
|
||||
* @param moveSpeed 镜头移动速度
|
||||
*/
|
||||
@Override
|
||||
public boolean ptzdirectCmd(String deviceId, String channelId, int leftRight, int upDown, int moveSpeed) {
|
||||
return ptzCmd(deviceId, channelId, leftRight, upDown, 0, moveSpeed, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 云台缩放控制,使用配置文件中的默认镜头缩放速度
|
||||
*
|
||||
* @param deviceId 控制设备
|
||||
* @param channelId 预览通道
|
||||
* @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
|
||||
*/
|
||||
@Override
|
||||
public boolean ptzZoomCmd(String deviceId, String channelId, int inOut) {
|
||||
return ptzCmd(deviceId, channelId, 0, 0, inOut, 0, config.getSpeed());
|
||||
}
|
||||
|
||||
/**
|
||||
* 云台缩放控制
|
||||
*
|
||||
* @param deviceId 控制设备
|
||||
* @param channelId 预览通道
|
||||
* @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
|
||||
* @param zoomSpeed 镜头缩放速度
|
||||
*/
|
||||
@Override
|
||||
public boolean ptzZoomCmd(String deviceId, String channelId, int inOut, int zoomSpeed) {
|
||||
return ptzCmd(deviceId, channelId, 0, 0, inOut, 0, zoomSpeed);
|
||||
}
|
||||
|
||||
/**
|
||||
* 云台控制,支持方向与缩放控制
|
||||
*
|
||||
* @param deviceId 控制设备
|
||||
* @param channelId 预览通道
|
||||
* @param leftRight 镜头左移右移 0:停止 1:左移 2:右移
|
||||
* @param upDown 镜头上移下移 0:停止 1:上移 2:下移
|
||||
* @param inOut 镜头放大缩小 0:停止 1:缩小 2:放大
|
||||
* @param moveSpeed 镜头移动速度
|
||||
* @param zoomSpeed 镜头缩放速度
|
||||
*/
|
||||
@Override
|
||||
public boolean ptzCmd(String deviceId, String channelId, int leftRight, int upDown, int inOut, int moveSpeed,
|
||||
int zoomSpeed) {
|
||||
try {
|
||||
Device device = storager.queryVideoDevice(deviceId);
|
||||
StringBuffer ptzXml = new StringBuffer(200);
|
||||
ptzXml.append("<?xml version=\"1.0\" ?>");
|
||||
ptzXml.append("<Control>");
|
||||
ptzXml.append("<CmdType>DeviceControl</CmdType>");
|
||||
ptzXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>");
|
||||
ptzXml.append("<DeviceID>" + channelId + "</DeviceID>");
|
||||
ptzXml.append("<PTZCmd>" + PtzCmdHelper.create(leftRight, upDown, inOut, moveSpeed, zoomSpeed) + "</PTZCmd>");
|
||||
ptzXml.append("<Info>");
|
||||
ptzXml.append("</Info>");
|
||||
ptzXml.append("</Control>");
|
||||
|
||||
Request request = headerProvider.createMessageRequest(device, ptzXml.toString(), "ViaPtzBranch", "FromPtzTag", "ToPtzTag");
|
||||
|
||||
transmitRequest(device.getTransport(), request);
|
||||
|
||||
return true;
|
||||
} catch (SipException | ParseException | InvalidArgumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求预览视频流
|
||||
*
|
||||
* @param deviceId 视频设备
|
||||
* @param channelId 预览通道
|
||||
*/
|
||||
@Override
|
||||
public String playStreamCmd(String deviceId, String channelId) {
|
||||
try {
|
||||
|
||||
Device device = storager.queryVideoDevice(deviceId);
|
||||
|
||||
//生成ssrc标识数据流 10位数字
|
||||
String ssrc = "";
|
||||
Random random = new Random();
|
||||
// ZLMediaServer最大识别7FFFFFFF即2147483647,所以随机数不能超过这个数
|
||||
ssrc = String.valueOf(random.nextInt(2147483647));
|
||||
//
|
||||
StringBuffer content = new StringBuffer(200);
|
||||
content.append("v=0\r\n");
|
||||
content.append("o="+channelId+" 0 0 IN IP4 "+config.getSipIp()+"\r\n");
|
||||
content.append("s=Play\r\n");
|
||||
content.append("c=IN IP4 "+config.getMediaIp()+"\r\n");
|
||||
content.append("t=0 0\r\n");
|
||||
if(device.getTransport().equals("TCP")) {
|
||||
content.append("m=video "+config.getMediaPort()+" TCP/RTP/AVP 96 98 97\r\n");
|
||||
}
|
||||
if(device.getTransport().equals("UDP")) {
|
||||
content.append("m=video "+config.getMediaPort()+" RTP/AVP 96 98 97\r\n");
|
||||
}
|
||||
content.append("a=sendrecv\r\n");
|
||||
content.append("a=rtpmap:96 PS/90000\r\n");
|
||||
content.append("a=rtpmap:98 H264/90000\r\n");
|
||||
content.append("a=rtpmap:97 MPEG4/90000\r\n");
|
||||
if(device.getTransport().equals("TCP")){
|
||||
content.append("a=setup:passive\r\n");
|
||||
content.append("a=connection:new\r\n");
|
||||
}
|
||||
content.append("y="+ssrc+"\r\n");//ssrc
|
||||
|
||||
Request request = headerProvider.createInviteRequest(device, content.toString(), null, "live", null);
|
||||
|
||||
transmitRequest(device.getTransport(), request);
|
||||
return ssrc;
|
||||
} catch ( SipException | ParseException | InvalidArgumentException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 语音广播
|
||||
*
|
||||
* @param deviceId 视频设备
|
||||
* @param channelId 预览通道
|
||||
*/
|
||||
@Override
|
||||
public String audioBroadcastCmd(String deviceId, String channelId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 音视频录像控制
|
||||
*
|
||||
* @param deviceId 视频设备
|
||||
* @param channelId 预览通道
|
||||
*/
|
||||
@Override
|
||||
public String recordCmd(String deviceId, String channelId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 报警布防/撤防命令
|
||||
*
|
||||
* @param deviceId 视频设备
|
||||
*/
|
||||
@Override
|
||||
public String guardCmd(String deviceId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 报警复位命令
|
||||
*
|
||||
* @param deviceId 视频设备
|
||||
*/
|
||||
@Override
|
||||
public String alarmCmd(String deviceId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 强制关键帧命令,设备收到此命令应立刻发送一个IDR帧
|
||||
*
|
||||
* @param deviceId 视频设备
|
||||
* @param channelId 预览通道
|
||||
*/
|
||||
@Override
|
||||
public String iFameCmd(String deviceId, String channelId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 看守位控制命令
|
||||
*
|
||||
* @param deviceId 视频设备
|
||||
*/
|
||||
@Override
|
||||
public String homePositionCmd(String deviceId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备配置命令
|
||||
*
|
||||
* @param deviceId 视频设备
|
||||
*/
|
||||
@Override
|
||||
public String deviceConfigCmd(String deviceId) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询设备状态
|
||||
*
|
||||
* @param device 视频设备
|
||||
*/
|
||||
@Override
|
||||
public boolean deviceStatusQuery(Device device) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询设备信息
|
||||
*
|
||||
* @param device 视频设备
|
||||
*/
|
||||
@Override
|
||||
public boolean deviceInfoQuery(Device device) {
|
||||
try {
|
||||
StringBuffer catalogXml = new StringBuffer(200);
|
||||
catalogXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>");
|
||||
catalogXml.append("<Query>");
|
||||
catalogXml.append("<CmdType>DeviceInfo</CmdType>");
|
||||
catalogXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>");
|
||||
catalogXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>");
|
||||
catalogXml.append("</Query>");
|
||||
|
||||
Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaDeviceInfoBranch", "FromDeviceInfoTag", "ToDeviceInfoTag");
|
||||
|
||||
transmitRequest(device.getTransport(), request);
|
||||
} catch (SipException | ParseException | InvalidArgumentException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询目录列表
|
||||
*
|
||||
* @param device 视频设备
|
||||
*/
|
||||
@Override
|
||||
public boolean catalogQuery(Device device) {
|
||||
try {
|
||||
StringBuffer catalogXml = new StringBuffer(200);
|
||||
catalogXml.append("<?xml version=\"1.0\" encoding=\"GB2312\"?>");
|
||||
catalogXml.append("<Query>");
|
||||
catalogXml.append("<CmdType>Catalog</CmdType>");
|
||||
catalogXml.append("<SN>" + (int)((Math.random()*9+1)*100000) + "</SN>");
|
||||
catalogXml.append("<DeviceID>" + device.getDeviceId() + "</DeviceID>");
|
||||
catalogXml.append("</Query>");
|
||||
|
||||
Request request = headerProvider.createMessageRequest(device, catalogXml.toString(), "ViaCatalogBranch", "FromCatalogTag", "ToCatalogTag");
|
||||
|
||||
transmitRequest(device.getTransport(), request);
|
||||
|
||||
} catch (SipException | ParseException | InvalidArgumentException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询录像信息
|
||||
*
|
||||
* @param device 视频设备
|
||||
*/
|
||||
@Override
|
||||
public boolean recordInfoQuery(Device device) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询报警信息
|
||||
*
|
||||
* @param device 视频设备
|
||||
*/
|
||||
@Override
|
||||
public boolean alarmInfoQuery(Device device) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询设备配置
|
||||
*
|
||||
* @param device 视频设备
|
||||
*/
|
||||
@Override
|
||||
public boolean configQuery(Device device) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询设备预置位置
|
||||
*
|
||||
* @param device 视频设备
|
||||
*/
|
||||
@Override
|
||||
public boolean presetQuery(Device device) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询移动设备位置数据
|
||||
*
|
||||
* @param device 视频设备
|
||||
*/
|
||||
@Override
|
||||
public boolean mobilePostitionQuery(Device device) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
private void transmitRequest(String transport, Request request) throws SipException {
|
||||
if(transport.equals("TCP")) {
|
||||
sipLayer.getTcpSipProvider().sendRequest(request);
|
||||
} else if(transport.equals("UDP")) {
|
||||
sipLayer.getUdpSipProvider().sendRequest(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit.request;
|
||||
|
||||
import javax.sip.RequestEvent;
|
||||
import javax.sip.ServerTransaction;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
||||
|
||||
/**
|
||||
* @Description:处理接收IPCamera发来的SIP协议请求消息
|
||||
* @author: songww
|
||||
* @date: 2020年5月3日 下午4:42:22
|
||||
*/
|
||||
public interface ISIPRequestProcessor {
|
||||
|
||||
public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
|
||||
|
||||
import javax.sip.Dialog;
|
||||
import javax.sip.InvalidArgumentException;
|
||||
import javax.sip.RequestEvent;
|
||||
import javax.sip.ServerTransaction;
|
||||
import javax.sip.SipException;
|
||||
import javax.sip.message.Request;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
|
||||
|
||||
import gov.nist.javax.sip.header.CSeq;
|
||||
|
||||
/**
|
||||
* @Description:ACK请求处理器
|
||||
* @author: songww
|
||||
* @date: 2020年5月3日 下午5:31:45
|
||||
*/
|
||||
@Component
|
||||
public class AckRequestProcessor implements ISIPRequestProcessor {
|
||||
|
||||
/**
|
||||
* 处理 ACK请求
|
||||
*
|
||||
* @param evt
|
||||
* @param layer
|
||||
* @param transaction
|
||||
* @param config
|
||||
*/
|
||||
@Override
|
||||
public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) {
|
||||
Request request = evt.getRequest();
|
||||
Dialog dialog = evt.getDialog();
|
||||
try {
|
||||
Request ackRequest = null;
|
||||
CSeq csReq = (CSeq) request.getHeader(CSeq.NAME);
|
||||
ackRequest = dialog.createAck(csReq.getSeqNumber());
|
||||
dialog.sendAck(ackRequest);
|
||||
System.out.println("send ack to callee:" + ackRequest.toString());
|
||||
} catch (SipException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvalidArgumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
|
||||
|
||||
import javax.sip.RequestEvent;
|
||||
import javax.sip.ServerTransaction;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
|
||||
|
||||
/**
|
||||
* @Description: BYE请求处理器
|
||||
* @author: songww
|
||||
* @date: 2020年5月3日 下午5:32:05
|
||||
*/
|
||||
@Component
|
||||
public class ByeRequestProcessor implements ISIPRequestProcessor {
|
||||
|
||||
/**
|
||||
* 处理BYE请求
|
||||
*
|
||||
* @param evt
|
||||
* @param layer
|
||||
* @param transaction
|
||||
* @param config
|
||||
*/
|
||||
@Override
|
||||
public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
|
||||
|
||||
import javax.sip.RequestEvent;
|
||||
import javax.sip.ServerTransaction;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
|
||||
|
||||
/**
|
||||
* @Description:CANCEL请求处理器
|
||||
* @author: songww
|
||||
* @date: 2020年5月3日 下午5:32:23
|
||||
*/
|
||||
@Component
|
||||
public class CancelRequestProcessor implements ISIPRequestProcessor {
|
||||
|
||||
/**
|
||||
* 处理CANCEL请求
|
||||
*
|
||||
* @param evt
|
||||
* @param layer
|
||||
* @param transaction
|
||||
* @param config
|
||||
*/
|
||||
@Override
|
||||
public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
|
||||
|
||||
import javax.sip.RequestEvent;
|
||||
import javax.sip.ServerTransaction;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
|
||||
|
||||
/**
|
||||
* @Description:处理INVITE请求
|
||||
* @author: songww
|
||||
* @date: 2020年5月3日 下午4:43:52
|
||||
*/
|
||||
@Component
|
||||
public class InviteRequestProcessor implements ISIPRequestProcessor {
|
||||
|
||||
/**
|
||||
* 处理invite请求
|
||||
*
|
||||
* @param request
|
||||
* 请求消息
|
||||
*/
|
||||
@Override
|
||||
public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) {
|
||||
// TODO Auto-generated method stub
|
||||
// Request request = requestEvent.getRequest();
|
||||
//
|
||||
// try {
|
||||
// // 发送100 Trying
|
||||
// ServerTransaction serverTransaction = getServerTransaction(requestEvent);
|
||||
// // 查询目标地址
|
||||
// URI reqUri = request.getRequestURI();
|
||||
// URI contactURI = currUser.get(reqUri);
|
||||
//
|
||||
// System.out.println("processInvite rqStr=" + reqUri + " contact=" + contactURI);
|
||||
//
|
||||
// // 根据Request uri来路由,后续的响应消息通过VIA来路由
|
||||
// Request cliReq = messageFactory.createRequest(request.toString());
|
||||
// cliReq.setRequestURI(contactURI);
|
||||
//
|
||||
// HeaderFactory headerFactory = SipFactory.getInstance().createHeaderFactory();
|
||||
// Via callerVia = (Via) request.getHeader(Via.NAME);
|
||||
// Via via = (Via) headerFactory.createViaHeader(SIPMain.ip, SIPMain.port, "UDP",
|
||||
// callerVia.getBranch() + "sipphone");
|
||||
//
|
||||
// // FIXME 需要测试是否能够通过设置VIA头域来修改VIA头域值
|
||||
// cliReq.removeHeader(Via.NAME);
|
||||
// cliReq.addHeader(via);
|
||||
//
|
||||
// // 更新contact的地址
|
||||
// ContactHeader contactHeader = headerFactory.createContactHeader();
|
||||
// Address address = SipFactory.getInstance().createAddressFactory()
|
||||
// .createAddress("sip:sipsoft@" + SIPMain.ip + ":" + SIPMain.port);
|
||||
// contactHeader.setAddress(address);
|
||||
// contactHeader.setExpires(3600);
|
||||
// cliReq.setHeader(contactHeader);
|
||||
//
|
||||
// clientTransactionId = sipProvider.getNewClientTransaction(cliReq);
|
||||
// clientTransactionId.sendRequest();
|
||||
//
|
||||
// System.out.println("processInvite clientTransactionId=" + clientTransactionId.toString());
|
||||
//
|
||||
// System.out.println("send invite to callee: " + cliReq);
|
||||
// } catch (TransactionUnavailableException e1) {
|
||||
// e1.printStackTrace();
|
||||
// } catch (SipException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (ParseException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.text.ParseException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.sip.InvalidArgumentException;
|
||||
import javax.sip.RequestEvent;
|
||||
import javax.sip.ServerTransaction;
|
||||
import javax.sip.SipException;
|
||||
import javax.sip.message.Request;
|
||||
import javax.sip.message.Response;
|
||||
|
||||
import org.dom4j.Document;
|
||||
import org.dom4j.DocumentException;
|
||||
import org.dom4j.Element;
|
||||
import org.dom4j.io.SAXReader;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.DeviceChannel;
|
||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
|
||||
import com.genersoft.iot.vmp.gb28181.utils.XmlUtil;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||
|
||||
/**
|
||||
* @Description:MESSAGE请求处理器
|
||||
* @author: songww
|
||||
* @date: 2020年5月3日 下午5:32:41
|
||||
*/
|
||||
@Component
|
||||
public class MessageRequestProcessor implements ISIPRequestProcessor {
|
||||
|
||||
private ServerTransaction transaction;
|
||||
|
||||
private SipLayer layer;
|
||||
|
||||
@Autowired
|
||||
private SIPCommander cmder;
|
||||
|
||||
@Autowired
|
||||
private IVideoManagerStorager storager;
|
||||
|
||||
@Autowired
|
||||
private EventPublisher publisher;
|
||||
|
||||
/**
|
||||
* 处理MESSAGE请求
|
||||
*
|
||||
* @param evt
|
||||
* @param layer
|
||||
* @param transaction
|
||||
*/
|
||||
@Override
|
||||
public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) {
|
||||
|
||||
this.layer = layer;
|
||||
this.transaction = transaction;
|
||||
|
||||
Request request = evt.getRequest();
|
||||
|
||||
if (new String(request.getRawContent()).contains("<CmdType>Keepalive</CmdType>")) {
|
||||
processMessageKeepAlive(evt);
|
||||
} else if (new String(request.getRawContent()).contains("<CmdType>Catalog</CmdType>")) {
|
||||
processMessageCatalogList(evt);
|
||||
} else if (new String(request.getRawContent()).contains("<CmdType>DeviceInfo</CmdType>")) {
|
||||
processMessageDeviceInfo(evt);
|
||||
} else if (new String(request.getRawContent()).contains("<CmdType>Alarm</CmdType>")) {
|
||||
processMessageAlarm(evt);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/***
|
||||
* 收到catalog设备目录列表请求 处理
|
||||
* @param evt
|
||||
*/
|
||||
private void processMessageCatalogList(RequestEvent evt) {
|
||||
try {
|
||||
Request request = evt.getRequest();
|
||||
SAXReader reader = new SAXReader();
|
||||
reader.setEncoding("GB2312");
|
||||
Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
|
||||
Element rootElement = xml.getRootElement();
|
||||
Element deviceIdElement = rootElement.element("DeviceID");
|
||||
String deviceId = deviceIdElement.getText().toString();
|
||||
Element deviceListElement = rootElement.element("DeviceList");
|
||||
if (deviceListElement == null) {
|
||||
return;
|
||||
}
|
||||
Iterator<Element> deviceListIterator = deviceListElement.elementIterator();
|
||||
if (deviceListIterator != null) {
|
||||
Device device = storager.queryVideoDevice(deviceId);
|
||||
if (device == null) {
|
||||
return;
|
||||
}
|
||||
Map<String, DeviceChannel> channelMap = device.getChannelMap();
|
||||
if (channelMap == null) {
|
||||
channelMap = new HashMap<String, DeviceChannel>(5);
|
||||
device.setChannelMap(channelMap);
|
||||
}
|
||||
// 遍历DeviceList
|
||||
while (deviceListIterator.hasNext()) {
|
||||
Element itemDevice = deviceListIterator.next();
|
||||
Element channelDeviceElement = itemDevice.element("DeviceID");
|
||||
if (channelDeviceElement == null) {
|
||||
continue;
|
||||
}
|
||||
String channelDeviceId = channelDeviceElement.getText().toString();
|
||||
Element channdelNameElement = itemDevice.element("Name");
|
||||
String channelName = channdelNameElement != null ? channdelNameElement.getText().toString() : "";
|
||||
Element statusElement = itemDevice.element("Status");
|
||||
String status = statusElement != null ? statusElement.getText().toString() : "ON";
|
||||
DeviceChannel deviceChannel = channelMap.containsKey(channelDeviceId) ? channelMap.get(channelDeviceId) : new DeviceChannel();
|
||||
deviceChannel.setName(channelName);
|
||||
deviceChannel.setChannelId(channelDeviceId);
|
||||
if(status.equals("ON")) {
|
||||
deviceChannel.setStatus(1);
|
||||
}
|
||||
if(status.equals("OFF")) {
|
||||
deviceChannel.setStatus(0);
|
||||
}
|
||||
|
||||
deviceChannel.setManufacture(XmlUtil.getText(itemDevice,"Manufacturer"));
|
||||
deviceChannel.setModel(XmlUtil.getText(itemDevice,"Model"));
|
||||
deviceChannel.setOwner(XmlUtil.getText(itemDevice,"Owner"));
|
||||
deviceChannel.setCivilCode(XmlUtil.getText(itemDevice,"CivilCode"));
|
||||
deviceChannel.setBlock(XmlUtil.getText(itemDevice,"Block"));
|
||||
deviceChannel.setAddress(XmlUtil.getText(itemDevice,"Address"));
|
||||
deviceChannel.setParental(itemDevice.element("Parental") == null? 0:Integer.parseInt(XmlUtil.getText(itemDevice,"Parental")));
|
||||
deviceChannel.setParentId(XmlUtil.getText(itemDevice,"ParentId"));
|
||||
deviceChannel.setSafetyWay(itemDevice.element("SafetyWay") == null? 0:Integer.parseInt(XmlUtil.getText(itemDevice,"SafetyWay")));
|
||||
deviceChannel.setRegisterWay(itemDevice.element("RegisterWay") == null? 1:Integer.parseInt(XmlUtil.getText(itemDevice,"RegisterWay")));
|
||||
deviceChannel.setCertNum(XmlUtil.getText(itemDevice,"CertNum"));
|
||||
deviceChannel.setCertifiable(itemDevice.element("Certifiable") == null? 0:Integer.parseInt(XmlUtil.getText(itemDevice,"Certifiable")));
|
||||
deviceChannel.setErrCode(itemDevice.element("ErrCode") == null? 0:Integer.parseInt(XmlUtil.getText(itemDevice,"ErrCode")));
|
||||
deviceChannel.setEndTime(XmlUtil.getText(itemDevice,"EndTime"));
|
||||
deviceChannel.setSecrecy(XmlUtil.getText(itemDevice,"Secrecy"));
|
||||
deviceChannel.setIpAddress(XmlUtil.getText(itemDevice,"IPAddress"));
|
||||
deviceChannel.setPort(itemDevice.element("Port") == null? 0:Integer.parseInt(XmlUtil.getText(itemDevice,"Port")));
|
||||
deviceChannel.setPassword(XmlUtil.getText(itemDevice,"Password"));
|
||||
deviceChannel.setLongitude(itemDevice.element("Longitude") == null? 0.00:Double.parseDouble(XmlUtil.getText(itemDevice,"Longitude")));
|
||||
deviceChannel.setLatitude(itemDevice.element("Latitude") == null? 0.00:Double.parseDouble(XmlUtil.getText(itemDevice,"Latitude")));
|
||||
channelMap.put(channelDeviceId, deviceChannel);
|
||||
}
|
||||
// 更新
|
||||
storager.update(device);
|
||||
}
|
||||
} catch (DocumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* 收到deviceInfo设备信息请求 处理
|
||||
* @param evt
|
||||
*/
|
||||
private void processMessageDeviceInfo(RequestEvent evt) {
|
||||
try {
|
||||
Request request = evt.getRequest();
|
||||
SAXReader reader = new SAXReader();
|
||||
// reader.setEncoding("GB2312");
|
||||
Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
|
||||
Element rootElement = xml.getRootElement();
|
||||
Element deviceIdElement = rootElement.element("DeviceID");
|
||||
String deviceId = deviceIdElement.getText().toString();
|
||||
|
||||
Device device = storager.queryVideoDevice(deviceId);
|
||||
if (device == null) {
|
||||
return;
|
||||
}
|
||||
device.setName(XmlUtil.getText(rootElement,"DeviceName"));
|
||||
device.setManufacturer(XmlUtil.getText(rootElement,"Manufacturer"));
|
||||
device.setModel(XmlUtil.getText(rootElement,"Model"));
|
||||
device.setFirmware(XmlUtil.getText(rootElement,"Firmware"));
|
||||
storager.update(device);
|
||||
cmder.catalogQuery(device);
|
||||
} catch (DocumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* 收到alarm设备报警信息 处理
|
||||
* @param evt
|
||||
*/
|
||||
private void processMessageAlarm(RequestEvent evt) {
|
||||
try {
|
||||
Request request = evt.getRequest();
|
||||
SAXReader reader = new SAXReader();
|
||||
// reader.setEncoding("GB2312");
|
||||
Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
|
||||
Element rootElement = xml.getRootElement();
|
||||
Element deviceIdElement = rootElement.element("DeviceID");
|
||||
String deviceId = deviceIdElement.getText().toString();
|
||||
|
||||
Device device = storager.queryVideoDevice(deviceId);
|
||||
if (device == null) {
|
||||
return;
|
||||
}
|
||||
device.setName(XmlUtil.getText(rootElement,"DeviceName"));
|
||||
device.setManufacturer(XmlUtil.getText(rootElement,"Manufacturer"));
|
||||
device.setModel(XmlUtil.getText(rootElement,"Model"));
|
||||
device.setFirmware(XmlUtil.getText(rootElement,"Firmware"));
|
||||
storager.update(device);
|
||||
cmder.catalogQuery(device);
|
||||
} catch (DocumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/***
|
||||
* 收到keepalive请求 处理
|
||||
* @param evt
|
||||
*/
|
||||
private void processMessageKeepAlive(RequestEvent evt){
|
||||
try {
|
||||
Request request = evt.getRequest();
|
||||
Response response = layer.getMessageFactory().createResponse(Response.OK,request);
|
||||
SAXReader reader = new SAXReader();
|
||||
Document xml = reader.read(new ByteArrayInputStream(request.getRawContent()));
|
||||
// reader.setEncoding("GB2312");
|
||||
Element rootElement = xml.getRootElement();
|
||||
Element deviceIdElement = rootElement.element("DeviceID");
|
||||
transaction.sendResponse(response);
|
||||
publisher.onlineEventPublish(deviceIdElement.getText(), VideoManagerConstants.EVENT_ONLINE_KEEPLIVE);
|
||||
} catch (ParseException | SipException | InvalidArgumentException | DocumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
|
||||
|
||||
import javax.sip.RequestEvent;
|
||||
import javax.sip.ServerTransaction;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
|
||||
|
||||
/**
|
||||
* @Description:暂不支持的消息请求处理器
|
||||
* @author: songww
|
||||
* @date: 2020年5月3日 下午5:32:59
|
||||
*/
|
||||
@Component
|
||||
public class OtherRequestProcessor implements ISIPRequestProcessor {
|
||||
|
||||
/**
|
||||
* <p>Title: process</p>
|
||||
* <p>Description: </p>
|
||||
* @param evt
|
||||
* @param layer
|
||||
* @param transaction
|
||||
* @param config
|
||||
*/
|
||||
@Override
|
||||
public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) {
|
||||
System.out.println("no support the method! Method:" + evt.getRequest().getMethod());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.text.ParseException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.sip.InvalidArgumentException;
|
||||
import javax.sip.RequestEvent;
|
||||
import javax.sip.ServerTransaction;
|
||||
import javax.sip.SipException;
|
||||
import javax.sip.header.AuthorizationHeader;
|
||||
import javax.sip.header.ContactHeader;
|
||||
import javax.sip.header.ExpiresHeader;
|
||||
import javax.sip.header.FromHeader;
|
||||
import javax.sip.header.ViaHeader;
|
||||
import javax.sip.message.Request;
|
||||
import javax.sip.message.Response;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.genersoft.iot.vmp.common.VideoManagerConstants;
|
||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
||||
import com.genersoft.iot.vmp.gb28181.auth.DigestServerAuthenticationHelper;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Device;
|
||||
import com.genersoft.iot.vmp.gb28181.bean.Host;
|
||||
import com.genersoft.iot.vmp.gb28181.event.EventPublisher;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.cmd.impl.SIPCommander;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
|
||||
import com.genersoft.iot.vmp.storager.IVideoManagerStorager;
|
||||
|
||||
import gov.nist.javax.sip.address.AddressImpl;
|
||||
import gov.nist.javax.sip.address.SipUri;
|
||||
import gov.nist.javax.sip.header.Expires;
|
||||
|
||||
/**
|
||||
* @Description:收到注册请求 处理
|
||||
* @author: songww
|
||||
* @date: 2020年5月3日 下午4:47:25
|
||||
*/
|
||||
@Component
|
||||
public class RegisterRequestProcessor implements ISIPRequestProcessor {
|
||||
|
||||
@Autowired
|
||||
private SipConfig config;
|
||||
|
||||
@Autowired
|
||||
private SIPCommander cmder;
|
||||
|
||||
@Autowired
|
||||
private IVideoManagerStorager storager;
|
||||
|
||||
@Autowired
|
||||
private EventPublisher publisher;
|
||||
|
||||
/***
|
||||
* 收到注册请求 处理
|
||||
*
|
||||
* @param request
|
||||
* 请求消息
|
||||
*/
|
||||
@Override
|
||||
public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) {
|
||||
try {
|
||||
System.out.println("收到注册请求,开始处理");
|
||||
Request request = evt.getRequest();
|
||||
|
||||
Response response = null;
|
||||
boolean passwordCorrect = false;
|
||||
// 注册标志 0:未携带授权头或者密码错误 1:注册成功 2:注销成功
|
||||
int registerFlag = 0;
|
||||
Device device = null;
|
||||
AuthorizationHeader authorhead = (AuthorizationHeader) request.getHeader(AuthorizationHeader.NAME);
|
||||
// 校验密码是否正确
|
||||
if (authorhead != null) {
|
||||
passwordCorrect = new DigestServerAuthenticationHelper().doAuthenticatePlainTextPassword(request,
|
||||
config.getSipPassword());
|
||||
}
|
||||
|
||||
// 未携带授权头或者密码错误 回复401
|
||||
if (authorhead == null || !passwordCorrect) {
|
||||
|
||||
if (authorhead == null) {
|
||||
System.out.println("未携带授权头 回复401");
|
||||
} else if (!passwordCorrect) {
|
||||
System.out.println("密码错误 回复401");
|
||||
}
|
||||
response = layer.getMessageFactory().createResponse(Response.UNAUTHORIZED, request);
|
||||
new DigestServerAuthenticationHelper().generateChallenge(layer.getHeaderFactory(), response, config.getSipDomain());
|
||||
}
|
||||
// 携带授权头并且密码正确
|
||||
else if (passwordCorrect) {
|
||||
response = layer.getMessageFactory().createResponse(Response.OK, request);
|
||||
// 添加date头
|
||||
response.addHeader(layer.getHeaderFactory().createDateHeader(Calendar.getInstance(Locale.ENGLISH)));
|
||||
ExpiresHeader expiresHeader = (ExpiresHeader) request.getHeader(Expires.NAME);
|
||||
// 添加Contact头
|
||||
response.addHeader(request.getHeader(ContactHeader.NAME));
|
||||
// 添加Expires头
|
||||
response.addHeader(request.getExpires());
|
||||
|
||||
// 1.获取到通信地址等信息,保存到Redis
|
||||
FromHeader fromHeader = (FromHeader) request.getHeader(FromHeader.NAME);
|
||||
ViaHeader viaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
|
||||
String received = viaHeader.getReceived();
|
||||
int rPort = viaHeader.getRPort();
|
||||
// 本地模拟设备 received 为空 rPort 为 -1
|
||||
// 解析本地地址替代
|
||||
if (StringUtils.isEmpty(received) || rPort == -1) {
|
||||
received = viaHeader.getHost();
|
||||
rPort = viaHeader.getPort();
|
||||
}
|
||||
//
|
||||
Host host = new Host();
|
||||
host.setIp(received);
|
||||
host.setPort(rPort);
|
||||
host.setAddress(received.concat(":").concat(String.valueOf(rPort)));
|
||||
AddressImpl address = (AddressImpl) fromHeader.getAddress();
|
||||
SipUri uri = (SipUri) address.getURI();
|
||||
String deviceId = uri.getUser();
|
||||
device = new Device();
|
||||
device.setDeviceId(deviceId);
|
||||
device.setHost(host);
|
||||
// 注销成功
|
||||
if (expiresHeader != null && expiresHeader.getExpires() == 0) {
|
||||
registerFlag = 2;
|
||||
}
|
||||
// 注册成功
|
||||
else {
|
||||
registerFlag = 1;
|
||||
// 判断TCP还是UDP
|
||||
boolean isTcp = false;
|
||||
ViaHeader reqViaHeader = (ViaHeader) request.getHeader(ViaHeader.NAME);
|
||||
String transport = reqViaHeader.getTransport();
|
||||
if (transport.equals("TCP")) {
|
||||
isTcp = true;
|
||||
}
|
||||
device.setTransport(isTcp ? "TCP" : "UDP");
|
||||
}
|
||||
}
|
||||
transaction.sendResponse(response);
|
||||
// 注册成功
|
||||
// 保存到redis
|
||||
// 下发catelog查询目录
|
||||
if (registerFlag == 1 && device != null) {
|
||||
System.out.println("注册成功! deviceId:" + device.getDeviceId());
|
||||
storager.update(device);
|
||||
publisher.onlineEventPublish(device.getDeviceId(), VideoManagerConstants.EVENT_ONLINE_REGISTER);
|
||||
cmder.deviceInfoQuery(device);
|
||||
} else if (registerFlag == 2) {
|
||||
System.out.println("注销成功! deviceId:" + device.getDeviceId());
|
||||
publisher.outlineEventPublish(device.getDeviceId(), VideoManagerConstants.EVENT_OUTLINE_UNREGISTER);
|
||||
}
|
||||
} catch (SipException | InvalidArgumentException | NoSuchAlgorithmException | ParseException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit.request.impl;
|
||||
|
||||
import java.text.ParseException;
|
||||
|
||||
import javax.sip.InvalidArgumentException;
|
||||
import javax.sip.RequestEvent;
|
||||
import javax.sip.ServerTransaction;
|
||||
import javax.sip.SipException;
|
||||
import javax.sip.header.ExpiresHeader;
|
||||
import javax.sip.message.Request;
|
||||
import javax.sip.message.Response;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.request.ISIPRequestProcessor;
|
||||
|
||||
/**
|
||||
* @Description:SUBSCRIBE请求处理器
|
||||
* @author: songww
|
||||
* @date: 2020年5月3日 下午5:31:20
|
||||
*/
|
||||
@Component
|
||||
public class SubscribeRequestProcessor implements ISIPRequestProcessor {
|
||||
|
||||
/**
|
||||
* 处理SUBSCRIBE请求
|
||||
*
|
||||
* @param evt
|
||||
* @param layer
|
||||
* @param transaction
|
||||
* @param config
|
||||
*/
|
||||
@Override
|
||||
public void process(RequestEvent evt, SipLayer layer, ServerTransaction transaction) {
|
||||
Request request = evt.getRequest();
|
||||
|
||||
try {
|
||||
Response response = null;
|
||||
response = layer.getMessageFactory().createResponse(200, request);
|
||||
if (response != null) {
|
||||
ExpiresHeader expireHeader = layer.getHeaderFactory().createExpiresHeader(30);
|
||||
response.setExpires(expireHeader);
|
||||
}
|
||||
System.out.println("response : " + response.toString());
|
||||
|
||||
if (transaction != null) {
|
||||
transaction.sendResponse(response);
|
||||
transaction.terminate();
|
||||
} else {
|
||||
System.out.println("processRequest serverTransactionId is null.");
|
||||
}
|
||||
|
||||
} catch (ParseException e) {
|
||||
e.printStackTrace();
|
||||
} catch (SipException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvalidArgumentException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit.response;
|
||||
|
||||
import javax.sip.ResponseEvent;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
||||
|
||||
/**
|
||||
* @Description:处理接收IPCamera发来的SIP协议响应消息
|
||||
* @author: songww
|
||||
* @date: 2020年5月3日 下午4:42:22
|
||||
*/
|
||||
public interface ISIPResponseProcessor {
|
||||
|
||||
public void process(ResponseEvent evt, SipLayer layer, SipConfig config);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit.response.impl;
|
||||
|
||||
import javax.sip.ResponseEvent;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
|
||||
|
||||
/**
|
||||
* @Description: BYE请求响应器
|
||||
* @author: songww
|
||||
* @date: 2020年5月3日 下午5:32:05
|
||||
*/
|
||||
@Component
|
||||
public class ByeResponseProcessor implements ISIPResponseProcessor {
|
||||
|
||||
/**
|
||||
* 处理BYE响应
|
||||
*
|
||||
* @param evt
|
||||
* @param layer
|
||||
* @param transaction
|
||||
* @param config
|
||||
*/
|
||||
@Override
|
||||
public void process(ResponseEvent evt, SipLayer layer, SipConfig config) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit.response.impl;
|
||||
|
||||
import javax.sip.ResponseEvent;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
|
||||
|
||||
/**
|
||||
* @Description:CANCEL响应处理器
|
||||
* @author: songww
|
||||
* @date: 2020年5月3日 下午5:32:23
|
||||
*/
|
||||
@Component
|
||||
public class CancelResponseProcessor implements ISIPResponseProcessor {
|
||||
|
||||
/**
|
||||
* 处理CANCEL响应
|
||||
*
|
||||
* @param evt
|
||||
* @param layer
|
||||
* @param transaction
|
||||
* @param config
|
||||
*/
|
||||
@Override
|
||||
public void process(ResponseEvent evt, SipLayer layer, SipConfig config) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit.response.impl;
|
||||
|
||||
import javax.sip.Dialog;
|
||||
import javax.sip.InvalidArgumentException;
|
||||
import javax.sip.ResponseEvent;
|
||||
import javax.sip.SipException;
|
||||
import javax.sip.message.Request;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
|
||||
|
||||
/**
|
||||
* @Description:处理INVITE响应
|
||||
* @author: songww
|
||||
* @date: 2020年5月3日 下午4:43:52
|
||||
*/
|
||||
@Component
|
||||
public class InviteResponseProcessor implements ISIPResponseProcessor {
|
||||
|
||||
/**
|
||||
* 处理invite响应
|
||||
*
|
||||
* @param request
|
||||
* 响应消息
|
||||
*/
|
||||
@Override
|
||||
public void process(ResponseEvent evt, SipLayer layer, SipConfig config) {
|
||||
try {
|
||||
Dialog dialog = evt.getDialog();
|
||||
Request reqAck =dialog.createAck(1L);
|
||||
dialog.sendAck(reqAck);
|
||||
} catch (InvalidArgumentException | SipException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.genersoft.iot.vmp.gb28181.transmit.response.impl;
|
||||
|
||||
import javax.sip.ResponseEvent;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.genersoft.iot.vmp.conf.SipConfig;
|
||||
import com.genersoft.iot.vmp.gb28181.SipLayer;
|
||||
import com.genersoft.iot.vmp.gb28181.transmit.response.ISIPResponseProcessor;
|
||||
|
||||
/**
|
||||
* @Description:暂不支持的消息响应处理器
|
||||
* @author: songww
|
||||
* @date: 2020年5月3日 下午5:32:59
|
||||
*/
|
||||
@Component
|
||||
public class OtherResponseProcessor implements ISIPResponseProcessor {
|
||||
|
||||
/**
|
||||
* <p>Title: process</p>
|
||||
* <p>Description: </p>
|
||||
* @param evt
|
||||
* @param layer
|
||||
* @param config
|
||||
*/
|
||||
@Override
|
||||
public void process(ResponseEvent evt, SipLayer layer, SipConfig config) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user