diff --git a/src/core/SIP/SIPConstants.cs b/src/core/SIP/SIPConstants.cs index 922db9c3a..c0367d974 100644 --- a/src/core/SIP/SIPConstants.cs +++ b/src/core/SIP/SIPConstants.cs @@ -603,15 +603,16 @@ public static string SIPURIParameterUnescape(string escapedString) /// /// List of SIP extensions to RFC3262. - /// + /// + [Flags] public enum SIPExtensions { None = 0, Prack = 1, // Reliable provisional responses as per RFC3262. NoReferSub = 2, // No subscription for REFERs as per RFC4488. - Replaces = 3, - SipRec = 4, - MultipleRefer = 5, + Replaces = 4, + SipRec = 8, + MultipleRefer = 16, } /// @@ -627,51 +628,66 @@ public static class SIPExtensionHeaders public const string MULTIPLE_REFER = "multiple-refer"; /// - /// Parses a string containing a list of SIP extensions into a list of extensions that this library + /// Parses a string containing a list of SIP extensions into a bitfield of extensions that this library /// understands. /// /// The string containing the list of extensions to parse. /// A comma separated list of the unsupported extensions. - /// A list of extensions that were understood and a boolean indicating whether any unknown extensions were present. - public static List ParseSIPExtensions(string extensionList, out string unknownExtensions) + /// A bitfield of SIP extensions that were understood. + public static SIPExtensions ParseSIPExtensions(string extensionList, out string unknownExtensions) { - List knownExtensions = new List(); + SIPExtensions knownExtensions = 0; + var unknownExtensionsStringBuilder = new StringBuilder(); unknownExtensions = null; - if (String.IsNullOrEmpty(extensionList) == false) + if (String.IsNullOrEmpty(extensionList)) { - string[] extensions = extensionList.Trim().Split(','); + return knownExtensions; + } - foreach (string extension in extensions) + var extensions = extensionList.Split(','); + + foreach (var extension in extensions) + { + if (!String.IsNullOrEmpty(extension)) { - if (String.IsNullOrEmpty(extension) == false) + var trimmedExtension = extension.Trim().ToLower(); + switch (trimmedExtension) { - string trimmedExtension = extension.Trim().ToLower(); - switch (trimmedExtension) - { - case PRACK: - knownExtensions.Add(SIPExtensions.Prack); - break; - case NO_REFER_SUB: - knownExtensions.Add(SIPExtensions.NoReferSub); - break; - case REPLACES: - knownExtensions.Add(SIPExtensions.Replaces); - break; - case SIPREC: - knownExtensions.Add(SIPExtensions.SipRec); - break; - case MULTIPLE_REFER: - knownExtensions.Add(SIPExtensions.MultipleRefer); - break; - default: - unknownExtensions += (unknownExtensions != null) ? $",{extension.Trim()}" : extension.Trim(); - break; - } + case PRACK: + knownExtensions |= SIPExtensions.Prack; + break; + + case NO_REFER_SUB: + knownExtensions |= SIPExtensions.NoReferSub; + break; + + case REPLACES: + knownExtensions |= SIPExtensions.Replaces; + break; + + case SIPREC: + knownExtensions |= SIPExtensions.SipRec; + break; + + case MULTIPLE_REFER: + knownExtensions |= SIPExtensions.MultipleRefer; + break; + + default: + unknownExtensionsStringBuilder.Append(extension.Trim()); + unknownExtensionsStringBuilder.Append(','); + break; } } } + if (unknownExtensionsStringBuilder.Length > 0) + { + unknownExtensionsStringBuilder.Length--; // Get rid of the last comma + unknownExtensions = unknownExtensionsStringBuilder.ToString(); + } + return knownExtensions; } } diff --git a/src/core/SIP/SIPHeader.cs b/src/core/SIP/SIPHeader.cs index 2e937bf0e..645816331 100644 --- a/src/core/SIP/SIPHeader.cs +++ b/src/core/SIP/SIPHeader.cs @@ -1516,9 +1516,9 @@ public class SIPHeader public List UnknownHeaders = new List(); // Holds any unrecognised headers. - public List RequiredExtensions = new List(); + public SIPExtensions RequiredExtensions = 0; + public SIPExtensions SupportedExtensions = 0; public string UnknownRequireExtension = null; - public List SupportedExtensions = new List(); public bool HasAuthenticationHeader => AuthenticationHeaders.Count > 0; diff --git a/src/core/SIPTransactions/SIPTransaction.cs b/src/core/SIPTransactions/SIPTransaction.cs index 8ef0dfc7e..7ff63c5fe 100644 --- a/src/core/SIPTransactions/SIPTransaction.cs +++ b/src/core/SIPTransactions/SIPTransaction.cs @@ -265,8 +265,8 @@ protected SIPTransaction( m_sentBy = transactionRequest.Header.Vias.TopViaHeader.ContactAddress; OutboundProxy = outboundProxy; - if (transactionRequest.Header.RequiredExtensions.Contains(SIPExtensions.Prack) || - transactionRequest.Header.SupportedExtensions.Contains(SIPExtensions.Prack)) + if (transactionRequest.Header.RequiredExtensions.HasFlag(SIPExtensions.Prack) || + transactionRequest.Header.SupportedExtensions.HasFlag(SIPExtensions.Prack)) { PrackSupported = true; } diff --git a/test/unit/core/SIP/SIPHeaderUnitTest.cs b/test/unit/core/SIP/SIPHeaderUnitTest.cs index 8c83efcf6..ed6dea33d 100644 --- a/test/unit/core/SIP/SIPHeaderUnitTest.cs +++ b/test/unit/core/SIP/SIPHeaderUnitTest.cs @@ -777,8 +777,8 @@ public void ParseRequireAndSupportedExtensionsTest() string[] headersCollection = Regex.Split(inviteHeaders, "\r\n"); SIPHeader sipHeader = SIPHeader.ParseSIPHeaders(headersCollection); - Assert.True(sipHeader.RequiredExtensions.Contains(SIPExtensions.Prack), "The required header extensions was missing Prack."); - Assert.True(sipHeader.SupportedExtensions.Contains(SIPExtensions.Prack), "The supported header extensions was missing Prack."); + Assert.True(sipHeader.RequiredExtensions.HasFlag(SIPExtensions.Prack), "The required header extensions was missing Prack."); + Assert.True(sipHeader.SupportedExtensions.HasFlag(SIPExtensions.Prack), "The supported header extensions was missing Prack."); Assert.True(sipHeader.UnknownRequireExtension != null, "The had unknown required header extension was not correctly set."); logger.LogDebug("---------------------------------------------------");