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