Exemple #1
0
        private static SDP GetSDP(IPEndPoint rtpSocket, string rtpFlowAttribute)
        {
            var sdp = new SDP()
            {
                SessionId   = Crypto.GetRandomInt(5).ToString(),
                Address     = rtpSocket.Address.ToString(),
                SessionName = "sipsorcery",
                Timing      = "0 0",
                Connection  = new SDPConnectionInformation(rtpSocket.Address.ToString()),
            };

            var audioAnnouncement = new SDPMediaAnnouncement()
            {
                Media        = SDPMediaTypesEnum.audio,
                MediaFormats = new List <SDPMediaFormat>()
                {
                    new SDPMediaFormat((int)SDPMediaFormatsEnum.PCMU, "PCMU", 8000)
                }
            };

            audioAnnouncement.Port = rtpSocket.Port;
            audioAnnouncement.ExtraAttributes.Add($"a={rtpFlowAttribute}");
            sdp.Media.Add(audioAnnouncement);

            return(sdp);
        }
        public RTPMediaSession(SDPMediaTypesEnum mediaType, int formatTypeID, AddressFamily addrFamily)
            : base(mediaType, formatTypeID, addrFamily, false, false)
        {
            // Construct the local SDP. There are a number of assumptions being made here:
            // PCMU audio, RTP event support etc.
            var mediaFormat       = new SDPMediaFormat(formatTypeID);
            var mediaAnnouncement = new SDPMediaAnnouncement
            {
                Media        = mediaType,
                MediaFormats = new List <SDPMediaFormat> {
                    mediaFormat
                },
                MediaStreamStatus = MediaStreamStatusEnum.SendRecv,
                Port = base.RtpChannel.RTPPort
            };

            if (mediaType == SDPMediaTypesEnum.audio)
            {
                // RTP event support.
                int            clockRate      = mediaFormat.GetClockRate();
                SDPMediaFormat rtpEventFormat = new SDPMediaFormat(DTMF_EVENT_PAYLOAD_ID);
                rtpEventFormat.SetFormatAttribute($"{TELEPHONE_EVENT_ATTRIBUTE}/{clockRate}");
                rtpEventFormat.SetFormatParameterAttribute("0-16");
                mediaAnnouncement.MediaFormats.Add(rtpEventFormat);
            }

            MediaAnnouncements.Add(mediaAnnouncement);
        }
        /// <summary>
        /// 获取接收方端口号码
        /// </summary>
        /// <param name="sdpStr">SDP</param>
        /// <returns></returns>
        public int GetReceivePort(string sdpStr, SDPMediaTypesEnum mediaType)
        {
            string[] sdpLines = sdpStr.Split('\n');

            foreach (var line in sdpLines)
            {
                if (line.Trim().StartsWith("m="))
                {
                    Match mediaMatch = Regex.Match(line.Substring(2).Trim(), @"(?<type>\w+)\s+(?<port>\d+)\s+(?<transport>\S+)\s+(?<formats>.*)$");
                    if (mediaMatch.Success)
                    {
                        SDPMediaAnnouncement announcement = new SDPMediaAnnouncement
                        {
                            Media = SDPMediaTypes.GetSDPMediaType(mediaMatch.Result("${type}"))
                        };
                        Int32.TryParse(mediaMatch.Result("${port}"), out announcement.Port);
                        announcement.Transport = mediaMatch.Result("${transport}");
                        announcement.ParseMediaFormats(mediaMatch.Result("${formats}"));
                        if (announcement.Media != mediaType)
                        {
                            continue;
                        }
                        return(announcement.Port);
                    }
                }
            }
            return(0);
        }
Exemple #4
0
        /// <summary>
        /// 设置媒体参数请求(实时)
        /// </summary>
        /// <param name="localIp">本地ip</param>
        /// <param name="mediaPort">rtp/rtcp媒体端口(10000/10001)</param>
        /// <returns></returns>
        private string SetMediaAudio(string localIp, int port, string audioId)
        {
            SDPConnectionInformation sdpConn = new SDPConnectionInformation(localIp);

            SDP sdp = new SDP();

            sdp.Version     = 0;
            sdp.SessionId   = "0";
            sdp.Username    = audioId;
            sdp.SessionName = CommandType.Play.ToString();
            sdp.Connection  = sdpConn;
            sdp.Timing      = "0 0";
            sdp.Address     = localIp;

            SDPMediaFormat psFormat = new SDPMediaFormat(SDPMediaFormatsEnum.PS);

            psFormat.IsStandardAttribute = false;

            SDPMediaAnnouncement media = new SDPMediaAnnouncement();

            media.Media = SDPMediaTypesEnum.audio;

            media.MediaFormats.Add(psFormat);
            media.AddExtra("a=sendonly");
            media.AddExtra("y=0100000002");
            //media.AddExtra("f=v/////a/1/8/1");
            media.AddFormatParameterAttribute(psFormat.FormatID, psFormat.Name);
            media.Port = port;

            sdp.Media.Add(media);

            return(sdp.ToString());
        }
Exemple #5
0
        private static SDP GetSDP(IPEndPoint rtpSocket, RTPPayloadTypesEnum audioPayloadType)
        {
            int samplingFrequency = RTPPayloadTypes.GetSamplingFrequency(audioPayloadType);

            var sdp = new SDP()
            {
                SessionId   = Crypto.GetRandomInt(5).ToString(),
                Address     = rtpSocket.Address.ToString(),
                SessionName = "sipsorcery",
                Timing      = "0 0",
                Connection  = new SDPConnectionInformation(rtpSocket.Address.ToString()),
            };

            var audioAnnouncement = new SDPMediaAnnouncement()
            {
                Media        = SDPMediaTypesEnum.audio,
                MediaFormats = new List <SDPMediaFormat>()
                {
                    new SDPMediaFormat((int)audioPayloadType, "PCMU", samplingFrequency)
                }
            };

            audioAnnouncement.Port = rtpSocket.Port;
            audioAnnouncement.ExtraAttributes.Add("a=sendrecv");
            audioAnnouncement.ExtraAttributes.Add($"a=rtpmap:{DTMF_EVENT_PAYLOAD_ID} telephone-event/{samplingFrequency}");
            audioAnnouncement.ExtraAttributes.Add($"a=fmtp:{DTMF_EVENT_PAYLOAD_ID} 0-15");
            sdp.Media.Add(audioAnnouncement);

            return(sdp);
        }
Exemple #6
0
        private static SDP GetSDP(IPEndPoint rtpSocket)
        {
            var sdp = new SDP(rtpSocket.Address)
            {
                SessionId   = Crypto.GetRandomInt(5).ToString(),
                SessionName = "sipsorcery",
                Timing      = "0 0",
                Connection  = new SDPConnectionInformation(rtpSocket.Address),
            };

            var audioAnnouncement = new SDPMediaAnnouncement()
            {
                Media        = SDPMediaTypesEnum.audio,
                MediaFormats = new List <SDPMediaFormat>()
                {
                    new SDPMediaFormat((int)SDPMediaFormatsEnum.PCMU, "PCMU", 8000),
                    new SDPMediaFormat((int)SDPMediaFormatsEnum.G722, "G722", 8000)
                }
            };

            audioAnnouncement.Port = rtpSocket.Port;
            audioAnnouncement.MediaStreamStatus = MediaStreamStatusEnum.SendRecv;
            sdp.Media.Add(audioAnnouncement);

            return(sdp);
        }
        /// <summary>
        /// 设置媒体参数请求(实时)
        /// </summary>
        /// <param name="localIp">本地ip</param>
        /// <param name="mediaPort">rtp/rtcp媒体端口(10000/10001)</param>
        /// <returns></returns>
        private string SetMediaReq(string localIp, int[] mediaPort)
        {
            SDPConnectionInformation sdpConn = new SDPConnectionInformation(localIp);

            SDP sdp = new SDP();

            sdp.Version     = 0;
            sdp.SessionId   = "0";
            sdp.Username    = _msgCore.LocalSIPId;
            sdp.SessionName = CommandType.Play.ToString();
            sdp.Connection  = sdpConn;
            sdp.Timing      = "0 0";
            sdp.Address     = localIp;

            SDPMediaFormat psFormat = new SDPMediaFormat(SDPMediaFormatsEnum.PS);

            psFormat.IsStandardAttribute = false;
            SDPMediaFormat h264Format = new SDPMediaFormat(SDPMediaFormatsEnum.H264);

            h264Format.IsStandardAttribute = false;
            SDPMediaAnnouncement media = new SDPMediaAnnouncement();

            media.Media = SDPMediaTypesEnum.video;

            media.MediaFormats.Add(psFormat);
            media.MediaFormats.Add(h264Format);
            media.AddExtra("a=recvonly");
            media.AddFormatParameterAttribute(psFormat.FormatID, psFormat.Name);
            media.AddFormatParameterAttribute(h264Format.FormatID, h264Format.Name);
            media.Port = mediaPort[0];

            sdp.Media.Add(media);

            return(sdp.ToString());
        }
Exemple #8
0
        public void Start(string endpoint)
        {
            this.endpoint = endpoint;

            var caller   = "1003";
            var password = passwords[0];
            var port     = FreePort.FindNextAvailableUDPPort(15090);

            rtpChannel = new RTPChannel
            {
                DontTimeout    = true,
                RemoteEndPoint = new IPEndPoint(IPAddress.Parse(asterisk), port)
            };

            rtpChannel.SetFrameType(FrameTypesEnum.Audio);
            rtpChannel.ReservePorts(15000, 15090);
            rtpChannel.OnFrameReady += RtpChannel_OnFrameReady;

            uac = new SIPClientUserAgent(transport, null, null, null, null);

            var uri    = SIPURI.ParseSIPURIRelaxed($"{ endpoint }@{ asterisk }");
            var from   = (new SIPFromHeader(caller, new SIPURI(caller, asterisk, null), null)).ToString();
            var random = Crypto.GetRandomInt(5).ToString();
            var sdp    = new SDP
            {
                Version     = 2,
                Username    = "******",
                SessionId   = random,
                Address     = localIPEndPoint.Address.ToString(),
                SessionName = "redfox_" + random,
                Timing      = "0 0",
                Connection  = new SDPConnectionInformation(publicIPAddress.ToString())
            };

            var announcement = new SDPMediaAnnouncement
            {
                Media        = SDPMediaTypesEnum.audio,
                MediaFormats = new List <SDPMediaFormat>()
                {
                    new SDPMediaFormat((int)SDPMediaFormatsEnum.PCMU, "PCMU", 8000)
                },
                Port = rtpChannel.RTPPort
            };

            sdp.Media.Add(announcement);

            var descriptor = new SIPCallDescriptor(caller, password, uri.ToString(), from, null, null, null, null, SIPCallDirection.Out, SDP.SDP_MIME_CONTENTTYPE, sdp.ToString(), null);

            uac.CallTrying   += Uac_CallTrying;
            uac.CallRinging  += Uac_CallRinging;
            uac.CallAnswered += Uac_CallAnswered;
            uac.CallFailed   += Uac_CallFailed;

            uac.Call(descriptor);
        }
Exemple #9
0
        /// <summary>
        /// Gets an SDP packet that can be used by VoIP clients to negotiate an audio connection. The SDP will only
        /// offer PCMU since that's all I've gotten around to handling.
        /// </summary>
        /// <param name="usePublicIP">If true and the public IP address is available from the STUN client then
        /// the public IP address will be used in the SDP otherwise the host machine's default IPv4 address will
        /// be used.</param>
        /// <returns>An SDP packet that can be used by a VoIP client when initiating a call.</returns>
        public SDP GetSDP(bool usePublicIP)
        {
            IPAddress rtpIPAddress = (usePublicIP && SoftphoneSTUNClient.PublicIPAddress != null) ? SoftphoneSTUNClient.PublicIPAddress : _defaultLocalAddress;

            var sdp = new SDP()
            {
                SessionId   = Crypto.GetRandomInt(5).ToString(),
                Address     = rtpIPAddress.ToString(),
                SessionName = "sipsorcery",
                Timing      = "0 0",
                Connection  = new SDPConnectionInformation(rtpIPAddress.ToString()),
            };

            if (_rtpAudioChannel != null)
            {
                var audioAnnouncement = new SDPMediaAnnouncement()
                {
                    Media        = SDPMediaTypesEnum.audio,
                    MediaFormats = new List <SDPMediaFormat>()
                    {
                        new SDPMediaFormat((int)SDPMediaFormatsEnum.PCMU, "PCMU", 8000)
                    }
                };
                audioAnnouncement.Port = _rtpAudioChannel.RTPPort;
                sdp.Media.Add(audioAnnouncement);
            }

            if (_rtpVideoChannel != null)
            {
                var videoAnnouncement = new SDPMediaAnnouncement()
                {
                    Media        = SDPMediaTypesEnum.video,
                    MediaFormats = new List <SDPMediaFormat>()
                    {
                        new SDPMediaFormat(96, "VP8", 90000)
                    }
                };
                videoAnnouncement.Port = _rtpVideoChannel.RTPPort;
                sdp.Media.Add(videoAnnouncement);
            }

            return(sdp);
        }
        public void InvalidPortInRemoteOfferTest()
        {
            logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name);
            logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name);

            var remoteOffer = new SDP();

            var sessionPort     = 5523;
            var sessionEndpoint = "10vMB2Ee;tcp";

            remoteOffer.Connection = new SDPConnectionInformation(IPAddress.Loopback);

            var messageMediaFormat = new SDPMessageMediaFormat();

            messageMediaFormat.IP          = remoteOffer.Connection.ConnectionAddress;
            messageMediaFormat.Port        = sessionPort.ToString();
            messageMediaFormat.Endpoint    = sessionEndpoint;
            messageMediaFormat.AcceptTypes = new List <string>
            {
                "text/plain",
                "text/x-msrp-heartbeat"
            };

            SDPMediaAnnouncement messageAnnouncement = new SDPMediaAnnouncement(
                SDPMediaTypesEnum.message,
                remoteOffer.Connection,
                sessionPort,
                messageMediaFormat);

            messageAnnouncement.Transport = "TCP/MSRP";

            remoteOffer.Media.Add(messageAnnouncement);

            var sdpOffer           = remoteOffer.ToString();
            var msrpMediaAttribute =
                $"{SDPMediaAnnouncement.MEDIA_FORMAT_PATH_MSRP_PREFIX}//{remoteOffer.Connection.ConnectionAddress}:{sessionPort}/{sessionEndpoint}";
            var msrpMediaTypes   = $"{SDPMediaAnnouncement.MEDIA_FORMAT_PATH_ACCEPT_TYPES_PREFIX}text/plain text/x-msrp-heartbeat";
            var mediaDescription = $"m=message {sessionPort} TCP/MSRP *";

            Assert.Contains(msrpMediaAttribute, sdpOffer);
            Assert.Contains(msrpMediaTypes, sdpOffer);
            Assert.Contains(mediaDescription, sdpOffer);
        }
Exemple #11
0
        public Task <SDP> createOffer(RTCOfferOptions options)
        {
            SDP offerSdp = new SDP(IPAddress.Loopback);

            offerSdp.SessionId = Crypto.GetRandomInt(5).ToString();

            offerSdp.Connection = new SDPConnectionInformation(IPAddress.Loopback);

            SDPMediaAnnouncement audioAnnouncement = new SDPMediaAnnouncement(
                SDPMediaTypesEnum.audio,
                1234,
                new List <SDPMediaFormat> {
                new SDPMediaFormat(SDPMediaFormatsEnum.PCMU)
            });

            audioAnnouncement.Transport = RTP_MEDIA_PROFILE;

            offerSdp.Media.Add(audioAnnouncement);

            return(Task.FromResult(offerSdp));
        }
Exemple #12
0
        public SDP CreateAnswer(IPAddress connectionAddress)
        {
            SDP answerSdp = new SDP(IPAddress.Loopback);

            answerSdp.SessionId = Crypto.GetRandomInt(5).ToString();

            answerSdp.Connection = new SDPConnectionInformation(connectionAddress ?? IPAddress.Loopback);

            SDPMediaAnnouncement audioAnnouncement = new SDPMediaAnnouncement(
                SDPMediaTypesEnum.audio,
                1234,
                new List <SDPMediaFormat> {
                new SDPMediaFormat(SDPMediaFormatsEnum.PCMU)
            });

            audioAnnouncement.Transport = RTP_MEDIA_PROFILE;

            answerSdp.Media.Add(audioAnnouncement);

            return(answerSdp);
        }
        public void InvalidPortInRemoteOfferTest()
        {
            logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name);
            logger.BeginScope(System.Reflection.MethodBase.GetCurrentMethod().Name);

            RTPSession       localSession    = new RTPSession(false, false, false);
            MediaStreamTrack localAudioTrack = new MediaStreamTrack(SDPMediaTypesEnum.audio, false, new List <SDPAudioVideoMediaFormat> {
                new SDPAudioVideoMediaFormat(SDPWellKnownMediaFormatsEnum.PCMU)
            });

            localSession.addTrack(localAudioTrack);

            var remoteOffer = new SDP();

            remoteOffer.SessionId = Crypto.GetRandomInt(5).ToString();

            remoteOffer.Connection = new SDPConnectionInformation(IPAddress.Loopback);

            SDPMediaAnnouncement audioAnnouncement = new SDPMediaAnnouncement(
                SDPMediaTypesEnum.audio,
                66000,
                new List <SDPAudioVideoMediaFormat> {
                new SDPAudioVideoMediaFormat(SDPWellKnownMediaFormatsEnum.PCMU)
            });

            audioAnnouncement.Transport = RTPSession.RTP_MEDIA_PROFILE;

            remoteOffer.Media.Add(audioAnnouncement);

            var result = localSession.SetRemoteDescription(SIP.App.SdpType.offer, remoteOffer);

            logger.LogDebug($"Set remote description on local session result {result}.");

            Assert.Null(localSession.AudioDestinationEndPoint);

            localSession.Close("normal");
        }
        /// <summary>
        /// 设置媒体参数请求(实时)
        /// </summary>
        /// <param name="localIp">本地ip</param>
        /// <param name="mediaPort">rtp/rtcp媒体端口(10000/10001)</param>
        /// <returns></returns>
        private string SetMediaAudio(string localIp, int port, string audioId)
        {
            var sdpConn = new SDPConnectionInformation(localIp);

            var sdp = new SDP
            {
                Version     = 0,
                SessionId   = "0",
                Username    = audioId,
                SessionName = CommandType.Play.ToString(),
                Connection  = sdpConn,
                Timing      = "0 0",
                Address     = localIp
            };

            var psFormat = new SDPMediaFormat(SDPMediaFormatsEnum.PS)
            {
                IsStandardAttribute = false
            };

            var media = new SDPMediaAnnouncement
            {
                Media = SDPMediaTypesEnum.audio
            };

            media.MediaFormats.Add(psFormat);
            media.AddExtra("a=sendonly");
            media.AddExtra("y=0100000002");
            //media.AddExtra("f=v/////a/1/8/1");
            media.AddFormatParameterAttribute(psFormat.FormatID, psFormat.Name);
            media.Port = port;

            sdp.Media.Add(media);

            return(sdp.ToString());
        }
        private void Transport_SIPTransportRequestReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPRequest sipRequest)
        {
            var endpoint = new SIPEndPoint(SIPProtocolsEnum.udp, publicIPAddress, localSIPEndPoint.Port);

            if (sipRequest.Method == SIPMethodsEnum.INVITE)
            {
                if (transaction != null)
                {
                    return;
                }

                logger.DebugFormat("{0} Incoming call from {1}", prefix, sipRequest.Header.From.FromURI.User);

                transaction = transport.CreateUASTransaction(sipRequest, remoteEndPoint, endpoint, null);
                agent       = new SIPServerUserAgent(
                    transport,
                    null,
                    sipRequest.Header.From.FromURI.User,
                    null,
                    SIPCallDirection.In,
                    null,
                    null,
                    null,
                    transaction);

                agent.CallCancelled       += Agent_CallCancelled;
                agent.TransactionComplete += Agent_TransactionComplete;

                agent.Progress(SIPResponseStatusCodesEnum.Trying, null, null, null, null);
                agent.Progress(SIPResponseStatusCodesEnum.Ringing, null, null, null, null);

                var answer  = SDP.ParseSDPDescription(agent.CallRequest.Body);
                var address = IPAddress.Parse(answer.Connection.ConnectionAddress);
                var port    = answer.Media.FirstOrDefault(m => m.Media == SDPMediaTypesEnum.audio).Port;
                var random  = Crypto.GetRandomInt(5).ToString();
                var sdp     = new SDP
                {
                    Version     = 2,
                    Username    = "******",
                    SessionId   = random,
                    Address     = localIPEndPoint.Address.ToString(),
                    SessionName = "redfox_" + random,
                    Timing      = "0 0",
                    Connection  = new SDPConnectionInformation(publicIPAddress.ToString())
                };

                rtpChannel = new RTPChannel
                {
                    DontTimeout    = true,
                    RemoteEndPoint = new IPEndPoint(address, port)
                };

                rtpChannel.SetFrameType(FrameTypesEnum.Audio);
                // TODO Fix hardcoded ports
                rtpChannel.ReservePorts(15000, 15090);
                rtpChannel.OnFrameReady += Channel_OnFrameReady;
                rtpChannel.Start();

                // Send some setup parameters to punch a hole in the firewall/router
                rtpChannel.SendRTPRaw(new byte[] { 80, 95, 198, 88, 55, 96, 225, 141, 215, 205, 185, 242, 00 });

                rtpChannel.OnControlDataReceived       += (b) => { logger.Debug($"{prefix} Control Data Received; {b.Length} bytes"); };
                rtpChannel.OnControlSocketDisconnected += () => { logger.Debug($"{prefix} Control Socket Disconnected"); };

                var announcement = new SDPMediaAnnouncement
                {
                    Media        = SDPMediaTypesEnum.audio,
                    MediaFormats = new List <SDPMediaFormat>()
                    {
                        new SDPMediaFormat((int)SDPMediaFormatsEnum.PCMU, "PCMU", 8000)
                    },
                    Port = rtpChannel.RTPPort
                };

                sdp.Media.Add(announcement);

                SetState(State.Listening, sipRequest.Header.From.FromURI.User);

                agent.Progress(SIPResponseStatusCodesEnum.Accepted, null, null, null, null);
                agent.Answer(SDP.SDP_MIME_CONTENTTYPE, sdp.ToString(), null, SIPDialogueTransferModesEnum.NotAllowed);

                SetState(State.Busy, "");
                return;
            }
            if (sipRequest.Method == SIPMethodsEnum.BYE)
            {
                if (State != State.Busy)
                {
                    return;
                }

                logger.DebugFormat("{0} Hangup from {1}", prefix, sipRequest.Header.From.FromURI.User);

                var noninvite = transport.CreateNonInviteTransaction(sipRequest, remoteEndPoint, endpoint, null);
                var response  = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null);

                noninvite.SendFinalResponse(response);

                SetState(State.Finished, Endpoint);

                rtpChannel.OnFrameReady -= Channel_OnFrameReady;
                rtpChannel.Close();

                agent.TransactionComplete -= Agent_TransactionComplete;
                agent.CallCancelled       -= Agent_CallCancelled;
                agent       = null;
                transaction = null;

                SetState(State.Ready, Endpoint);

                return;
            }
            if (sipRequest.Method == SIPMethodsEnum.ACK)
            {
            }
            if (sipRequest.Method == SIPMethodsEnum.CANCEL)
            {
            }
        }