diff --git a/src/net/SDP/SDP.cs b/src/net/SDP/SDP.cs old mode 100644 new mode 100755 index 73951608a..927e4ca06 --- a/src/net/SDP/SDP.cs +++ b/src/net/SDP/SDP.cs @@ -1,4 +1,4 @@ -//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- // Filename: SDP.cs // // Description: Session Description Protocol implementation as defined in RFC 2327. @@ -234,13 +234,21 @@ public static SDP ParseSDPDescription(string sdpDescription) break; case var l when l.StartsWith("o="): - string[] ownerFields = sdpLineTrimmed.Substring(2).Split(' '); - sdp.Username = ownerFields[0]; - sdp.SessionId = ownerFields[1]; - UInt64.TryParse(ownerFields[2], out sdp.AnnouncementVersion); - sdp.NetworkType = ownerFields[3]; - sdp.AddressType = ownerFields[4]; - sdp.AddressOrHost = ownerFields[5]; + var ownerFields = sdpLineTrimmed.Substring(2).Split(new []{' '}, 6, StringSplitOptions.RemoveEmptyEntries); + + if (ownerFields.Length >= 5) + { + sdp.Username = ownerFields[0]; + sdp.SessionId = ownerFields[1]; + sdp.AnnouncementVersion = UInt64.TryParse(ownerFields[2], out var version) ? version : 0; + sdp.NetworkType = ownerFields[3]; + sdp.AddressType = ownerFields[4]; + sdp.AddressOrHost = ownerFields.ElementAtOrDefault(5); // Safely handle missing elements + } + else + { + logger.LogWarning($"The SDP message had an invalid SDP line format for 'o=': {sdpLineTrimmed}"); + } break; case var l when l.StartsWith("s="): @@ -779,7 +787,7 @@ public static SDP ParseSDPDescription(string sdpDescription) } catch (Exception excp) { - logger.LogError("Exception ParseSDPDescription. " + excp.Message); + logger.LogError("Exception ParseSDPDescription. " + excp); throw; } } diff --git a/test/unit/net/SDP/SDPUnitTests.cs b/test/unit/net/SDP/SDPUnitTests.cs index 1c0e74c47..d7e2248d7 100755 --- a/test/unit/net/SDP/SDPUnitTests.cs +++ b/test/unit/net/SDP/SDPUnitTests.cs @@ -9,6 +9,7 @@ // BSD 3-Clause "New" or "Revised" License, see included LICENSE.md file. //----------------------------------------------------------------------------- +using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Net; @@ -1280,5 +1281,34 @@ public void AnnoucementMediaCheckTest() Assert.Equal("text/plain", sdp.Media.First().MessageMediaFormat.AcceptTypes[0]); Assert.Equal("text/x-msrp-heartbeat", sdp.Media.First().MessageMediaFormat.AcceptTypes[1]); } + + /// + /// The media format negotiation rules specify that the first common format in the offer and answer + /// should be chiosen. This test checks that the media formats are maintained in the order they were added. + /// + [Fact] + public void Media_Formats_Order_Test() + { + logger.LogDebug("--> " + System.Reflection.MethodBase.GetCurrentMethod().Name); + + var sdp = new SDP(); + + sdp.Media.Add(new SDPMediaAnnouncement() + { + Media = SDPMediaTypesEnum.audio, + MediaFormats = new Dictionary + { + { 8, new SDPAudioVideoMediaFormat(SDPMediaTypesEnum.audio, 8, "PCMA", 8000) }, + { 0, new SDPAudioVideoMediaFormat(SDPMediaTypesEnum.audio, 0, "PCMU", 8000) }, + { 101, new SDPAudioVideoMediaFormat(SDPMediaTypesEnum.audio, 101, "telephone-event", 8000) } + } + }); + + logger.LogDebug(sdp.ToString()); + + var sdpParsed = SDP.ParseSDPDescription(sdp.ToString()); + + Assert.Equal(8, sdpParsed.Media.Where(x => x.Media == SDPMediaTypesEnum.audio).First().MediaFormats.First().Key); + } } }