diff --git a/gb28181-sip/src/main/java/cn/skcks/docking/gb28181/sip/generic/SipBuilder.java b/gb28181-sip/src/main/java/cn/skcks/docking/gb28181/sip/generic/SipBuilder.java index 6d68559..757fb0f 100644 --- a/gb28181-sip/src/main/java/cn/skcks/docking/gb28181/sip/generic/SipBuilder.java +++ b/gb28181-sip/src/main/java/cn/skcks/docking/gb28181/sip/generic/SipBuilder.java @@ -133,6 +133,11 @@ public class SipBuilder { return getHeaderFactory().createContentTypeHeader(contentType, subType); } + @SneakyThrows + public static SubjectHeader createSubjectHeader(String subject){ + return getHeaderFactory().createSubjectHeader(subject); + } + @SneakyThrows public static ContentTypeHeader createSDPContentTypeHeader(){ return getHeaderFactory().createContentTypeHeader("APPLICATION", "SDP"); diff --git a/gb28181-sip/src/main/java/cn/skcks/docking/gb28181/sip/method/invite/InviteBuilder.java b/gb28181-sip/src/main/java/cn/skcks/docking/gb28181/sip/method/invite/InviteBuilder.java new file mode 100644 index 0000000..44bfedb --- /dev/null +++ b/gb28181-sip/src/main/java/cn/skcks/docking/gb28181/sip/method/invite/InviteBuilder.java @@ -0,0 +1,9 @@ +package cn.skcks.docking.gb28181.sip.method.invite; + +import javax.sip.message.Request; + + +public interface InviteBuilder { + String METHOD = Request.INVITE; + +} diff --git a/gb28181-sip/src/main/java/cn/skcks/docking/gb28181/sip/method/invite/request/InviteRequestBuilder.java b/gb28181-sip/src/main/java/cn/skcks/docking/gb28181/sip/method/invite/request/InviteRequestBuilder.java new file mode 100644 index 0000000..4bc84dc --- /dev/null +++ b/gb28181-sip/src/main/java/cn/skcks/docking/gb28181/sip/method/invite/request/InviteRequestBuilder.java @@ -0,0 +1,44 @@ +package cn.skcks.docking.gb28181.sip.method.invite.request; + +import cn.skcks.docking.gb28181.sdp.GB28181Description; +import cn.skcks.docking.gb28181.sdp.GB28181SDPBuilder; +import cn.skcks.docking.gb28181.sdp.media.MediaStreamMode; +import cn.skcks.docking.gb28181.sip.generic.SipBuilder; +import cn.skcks.docking.gb28181.sip.method.RequestBuilder; +import cn.skcks.docking.gb28181.sip.method.invite.InviteBuilder; +import gov.nist.javax.sip.message.SIPRequest; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.ToString; +import lombok.experimental.SuperBuilder; +import org.apache.commons.lang3.StringUtils; + +import javax.sdp.Connection; +import javax.sip.address.Address; +import javax.sip.message.Request; + +@Data +@SuperBuilder +@EqualsAndHashCode(callSuper = true) +@ToString(callSuper = true) +public class InviteRequestBuilder extends RequestBuilder implements InviteBuilder { + public Request createPlayInviteRequest(String callId, long cSeq, String channelId, String rtpIp, int rtpPort, String ssrc, MediaStreamMode mediaStreamMode, int receiveId){ + GB28181Description description = GB28181SDPBuilder.Receiver.play(getTargetId(), channelId, Connection.IP4,rtpIp,rtpPort,ssrc,mediaStreamMode); + + SIPRequest request = (SIPRequest) createRequest(METHOD, callId, cSeq, description); + Address address = request.getFrom().getAddress(); + + String subject = StringUtils.joinWith(",", + // 发送者 channelId:流序号 + StringUtils.joinWith(":", channelId, ssrc), + // 接收者 id:流序号号 + StringUtils.joinWith(":", getLocalId(), receiveId)); + return SipBuilder.addHeaders(request, + SipBuilder.createContactHeader(address), + SipBuilder.createSubjectHeader(subject)); + } + + public Request createPlayInviteRequest(String callId, long cSeq, String channelId, String rtpIp, int rtpPort, String ssrc, MediaStreamMode mediaStreamMode) { + return createPlayInviteRequest(callId, cSeq, channelId, rtpIp, rtpPort, ssrc, mediaStreamMode, 0); + } +} diff --git a/gb28181-sip/src/test/java/cn/skcks/docking/gb28181/sip/process/RequestTest.java b/gb28181-sip/src/test/java/cn/skcks/docking/gb28181/sip/process/RequestTest.java index 0e399ea..8d0c107 100644 --- a/gb28181-sip/src/test/java/cn/skcks/docking/gb28181/sip/process/RequestTest.java +++ b/gb28181-sip/src/test/java/cn/skcks/docking/gb28181/sip/process/RequestTest.java @@ -1,12 +1,15 @@ package cn.skcks.docking.gb28181.sip.process; import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.RandomUtil; import cn.skcks.docking.gb28181.constant.CmdType; +import cn.skcks.docking.gb28181.sdp.media.MediaStreamMode; import cn.skcks.docking.gb28181.sip.manscdp.catalog.query.CatalogQueryDTO; import cn.skcks.docking.gb28181.sip.manscdp.catalog.response.CatalogDeviceListDTO; import cn.skcks.docking.gb28181.sip.manscdp.catalog.response.CatalogResponseDTO; import cn.skcks.docking.gb28181.sip.manscdp.catalog.response.CatalogSubscribeResponseDTO; import cn.skcks.docking.gb28181.sip.manscdp.keepalive.notify.KeepaliveNotifyDTO; +import cn.skcks.docking.gb28181.sip.method.invite.request.InviteRequestBuilder; import cn.skcks.docking.gb28181.sip.method.message.request.MessageRequestBuilder; import cn.skcks.docking.gb28181.sip.method.message.response.MessageResponseBuilder; import cn.skcks.docking.gb28181.sip.method.notify.request.NotifyRequestBuilder; @@ -40,6 +43,35 @@ public class RequestTest { public static final String domain = "4405010000"; + public static final String rtpIp = "10.10.10.200"; + public static int rtpPort = RandomUtil.randomInt(30000,50000); + + @Test + void inviteTest(){ + // 服务端 向 客户端 发起 请求 + InviteRequestBuilder inviteRequestBuilder = InviteRequestBuilder.builder() + .localIp(remoteIp) + .localPort(remotePort) + .localId(remoteId) + .targetIp(localIp) + .targetPort(localPort) + .targetId(localId) + .transport(ListeningPoint.TCP) + .build(); + String callId = SipUtil.nanoId(10); + // 2~6位为 域 4~8位 + String ssrcPrefix = domain.substring(3, 8); + // 7~10 为 流标识 + String ssrc = String.format("%s%04d", ssrcPrefix, RandomUtil.randomInt(1,10000)); + // 0 开头的为实时 + String playSsrc = "0" + ssrc; + // 1 开头的为历史 + String playBackSsrc = "1" + ssrc; + Request playInviteRequest = inviteRequestBuilder.createPlayInviteRequest(callId, 1, localId, rtpIp, rtpPort, playSsrc, MediaStreamMode.TCP_ACTIVE); + log.info("\n{}", playInviteRequest); + } + + @Test void messageTest(){ MessageRequestBuilder messageRequestBuilder = MessageRequestBuilder.builder()