初始提交

This commit is contained in:
songww
2020-05-07 21:55:45 +08:00
commit 70091f29f2
48 changed files with 4650 additions and 0 deletions

View File

@@ -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;
}
}
}

View File

@@ -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);
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}

View File

@@ -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();
}
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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();
// }
}
}

View File

@@ -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();
}
}
}

View File

@@ -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());
}
}

View File

@@ -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();
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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);
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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();
}
}
}

View File

@@ -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
}
}