├── .gitignore ├── .gitmodules ├── Certificate ├── MakeCert.bat ├── OfficeSIP.cer ├── OfficeSIP.pfx └── OfficeSIP.pvk ├── ControlPanel.sln ├── ControlPanel ├── AddUser.xaml ├── AddUser.xaml.cs ├── AddVoipProvider.xaml ├── AddVoipProvider.xaml.cs ├── Bitmap.cs ├── Commands.cs ├── CompletionData.cs ├── ConfigData.cs ├── ControlPanel.csproj ├── Converters │ ├── AvailabilityConverter.cs │ ├── LoadingConverter.cs │ ├── TrueFalseConverter.cs │ └── VisibilityConverter.cs ├── Crash.xaml ├── Crash.xaml.cs ├── EditUser.xaml ├── EditUser.xaml.cs ├── EditXmlConfig.xaml ├── EditXmlConfig.xaml.cs ├── Error.xaml ├── Error.xaml.cs ├── Images │ ├── MainTab │ │ ├── group.png │ │ ├── home_page.png │ │ ├── setting_tools.png │ │ └── telephone.png │ ├── OfficeSIP Server.ico │ ├── PresenceImages.xaml │ └── Windows-Security.png ├── Login.xaml ├── Login.xaml.cs ├── Main.xaml ├── Main.xaml.cs ├── MainResources.xaml ├── NewPassword.xaml ├── NewPassword.xaml.cs ├── NewVersion.xaml ├── NewVersion.xaml.cs ├── Programme.Crash.cs ├── Programme.xaml ├── Programme.xaml.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ ├── Settings.settings │ └── app.manifest ├── Service References │ ├── Service1 │ │ ├── Arrays.xsd │ │ ├── ControlPanel.Service1.Configurations.datasource │ │ ├── ControlPanel.Service1.TURNConfigurations.datasource │ │ ├── ControlPanel.Service1.User.datasource │ │ ├── ControlPanel.Service1.VoipProvider.datasource │ │ ├── Reference.cs │ │ ├── Reference.svcmap │ │ ├── System.Net.Sockets.xsd │ │ ├── System.Net.xsd │ │ ├── System.xsd │ │ ├── configuration.svcinfo │ │ ├── configuration91.svcinfo │ │ ├── server.control.wsdl │ │ ├── server.control.xsd │ │ ├── service.wsdl │ │ └── service.xsd │ └── TurnService1 │ │ ├── Arrays.xsd │ │ ├── ControlPanel.TurnService1.WcfTurnConfiguration.datasource │ │ ├── Reference.cs │ │ ├── Reference.svcmap │ │ ├── System.Net.Sockets.xsd │ │ ├── System.Net.xsd │ │ ├── configuration.svcinfo │ │ ├── configuration91.svcinfo │ │ ├── service.wsdl │ │ ├── service.xsd │ │ ├── turn.server.control.wsdl │ │ └── turn.server.control.xsd ├── ServiceControl.xaml ├── ServiceControl.xaml.cs ├── ServiceOpen.xaml ├── ServiceOpen.xaml.cs ├── TurnGui │ ├── EditTurnServer.xaml │ ├── EditTurnServer.xaml.cs │ ├── LoginTurnServer.xaml │ └── LoginTurnServer.xaml.cs ├── UsersFetcher.cs ├── UsersTabContent.xaml ├── UsersTabContent.xaml.cs ├── UsersTabHeader.xaml ├── UsersTabHeader.xaml.cs ├── ValidationRules │ ├── DisplayNameValidationRule.cs │ ├── EmailValidationRule.cs │ ├── HostnameValidationRule.cs │ ├── IPAddressValidationRule.cs │ ├── IPEndPointValidationRule.cs │ ├── Key12ValidationRule.cs │ ├── MaxLength.cs │ ├── OkEnabler.cs │ ├── OptionalValidationRule.cs │ ├── PortValidationRule.cs │ ├── UriValidationRule.cs │ ├── UsernameValidationRule.cs │ └── Validator.cs ├── VistaSecurity.cs └── app.config ├── LICENSE ├── OfficeSIP Server.sln ├── README.md ├── Server ├── Accounts │ ├── Account.cs │ ├── AccountFiles.cs │ ├── AccountPath.cs │ ├── AccountsException.cs │ ├── Accountx.cs │ ├── IAccount.cs │ └── IAccounts.cs ├── App.config ├── Application.cs ├── Authorization │ ├── AuthorizationManager.cs │ ├── DigestAuthentication.cs │ ├── Http │ │ ├── HttpAuthorizationManager.cs │ │ ├── HttpDigestAuthentication.cs │ │ └── IHttpAuthorizationManager.cs │ ├── IAuthorizationManager.cs │ └── Sip │ │ ├── ISipAuthorizationManager.cs │ │ ├── SipAuthorizationManager.cs │ │ ├── SipDigestAuthentication.cs │ │ ├── SipMicrosoftAuthentication.cs │ │ └── SspiDigestAuthorizationManager.cs ├── BufferManagerProxy.cs ├── Bugreport │ └── CrashHandler.cs ├── Collections │ ├── BinaryHeap.cs │ ├── EmptyEnumerator.cs │ ├── FastResizablePool.cs │ ├── SkipNullArrayEnumerator.cs │ ├── ThreadSafeDictionary.cs │ └── ThreadSafeList.cs ├── Configuration │ ├── ByteArrayConverter.cs │ ├── ConfigurationMonitor.cs │ ├── ConfigurationSectionEx.cs │ ├── DefaultConfiguration.xml │ ├── IPEndPointConverter.cs │ ├── PortForwardingConfigurationElement.cs │ ├── PortForwardingConfigurationElementCollection.cs │ ├── ProtocolConverter.cs │ ├── SipServerConfigurationSection.cs │ ├── TurnServerConfigurationElement.cs │ ├── TurnServerConfigurationElementCollection.cs │ ├── TypedEnumerator.cs │ ├── VoipProviderConfigurationElement.cs │ └── VoipProviderConfigurationElementCollection.cs ├── Dialog │ ├── Dialog.cs │ └── DialogManager.cs ├── EnhancedPresence │ ├── EnhancedPresence.cs │ ├── EnhancedPresenceException.cs │ ├── ExpiresList.cs │ ├── Publication.cs │ ├── Schemas │ │ ├── BatchSubscribeRequest.xsd │ │ ├── Categories.xsd │ │ ├── RichPresenceCommon.xsd │ │ └── categoryList.xsd │ ├── Subscription.cs │ ├── SubscriptionResource.cs │ └── XmlContent │ │ ├── BatchSubscribe.cs │ │ ├── Categories.cs │ │ ├── Category.cs │ │ ├── ContactCardCategory.cs │ │ ├── ICategoryValue.cs │ │ ├── OutContent.cs │ │ ├── Rlmi.cs │ │ ├── RoamingData.cs │ │ ├── Schemas.cs │ │ ├── StateCategory.cs │ │ └── UserPropertiesCategory.cs ├── Http │ ├── BaseHttpConnection.cs │ ├── BaseHttpServer.cs │ ├── HttpFileServer.cs │ ├── HttpServer.cs │ └── WebSocketHeader.cs ├── Initializer.cs ├── LocationService │ ├── Binding.cs │ ├── Bindings.cs │ ├── ILocationService.cs │ └── LocationService.cs ├── Mras │ ├── Mras.cs │ ├── MrasException.cs │ ├── Password.cs │ ├── TokenBlob.cs │ ├── TurnServerInfo.cs │ ├── Username.cs │ └── XmlContent │ │ ├── Common.cs │ │ ├── CredentialsRequest.cs │ │ ├── CredentialsResponse.cs │ │ ├── MediaRelay.cs │ │ ├── Request.cs │ │ └── Response.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── AssemblyInfoVersion.cs │ └── OfficeSIP Server.ico ├── Restapi │ ├── Bnf │ │ ├── api.bat │ │ ├── api.bnf │ │ ├── api.mrk │ │ └── api.xml │ ├── JsonContractResolver.cs │ ├── RestapiService.cs │ ├── RestapiUriParser.cs │ └── Server.Restapi.dfa ├── Rtp │ ├── DtmfDecoder.cs │ ├── DtmfEventMessage.cs │ ├── JitterBuffer.cs │ ├── ParseException.cs │ ├── RtcpMessage.cs │ ├── RtpMessage.cs │ ├── RtpReceiver.cs │ ├── Ssrc.cs │ ├── dtmf-rfc4733.txt │ └── rtp-rfc3550.txt ├── Sdp │ └── Helpers.cs ├── Server.cs ├── Server.csproj ├── Service.cs ├── ServiceSoap │ ├── ServiceSoap.cs │ └── XmlContent │ │ ├── DirectorySearchRequest.cs │ │ └── DirectorySearchResponse.cs ├── Simple │ ├── PresenceDocument.cs │ ├── Publication.cs │ ├── SimpleModule.cs │ └── Subscription.cs ├── Tools │ ├── Bigendian.cs │ ├── BitTwiddling.cs │ ├── ByteArray.cs │ ├── Crc32.cs │ ├── HashAlgorithmHelpers.cs │ ├── HexEncoding.cs │ ├── ISO3166.cs │ ├── IpEndPointExt.cs │ ├── MultiTimer.cs │ ├── NtpTimestamp.cs │ ├── Saslprep.cs │ └── TupleStruct.cs ├── Tracer.cs ├── Transaction │ ├── AcceptedRequest.cs │ ├── BadServerTransactionKey.cs │ ├── BaseTransactionUser.cs │ ├── ClientTransactionStorage.cs │ ├── GeneralVerifier.cs │ ├── IncomingMessageEx.cs │ ├── InviteClientTransaction.cs │ ├── InviteServerTransaction.cs │ ├── NonInviteClientTransaction.cs │ ├── NonInviteServerTransaction.cs │ ├── ProducedRequest.cs │ ├── ServerTransactionStorage.cs │ ├── Transaction.cs │ └── TransactionLayer.cs ├── TransactionUsers │ ├── DirectorySearchTU.cs │ ├── ErrorTU.cs │ ├── MessageSummaryTU.cs │ ├── MrasTU.cs │ ├── MsPresTU.cs │ ├── OptionsTU.cs │ ├── ProxyServerTU │ │ ├── BaseProxie.cs │ │ ├── IProxie.cs │ │ ├── LocalProxie.cs │ │ ├── LocalTrunkProxie.cs │ │ ├── ProxieFactory.cs │ │ ├── ProxyServerTU.cs │ │ ├── RequestProxy.cs │ │ ├── RequestProxyFactory.cs │ │ ├── TrunkDialogProxie.cs │ │ └── TrunkLocalProxie.cs │ ├── RegistrarTU.cs │ ├── SimpleTU.cs │ └── TrunkTU.cs ├── Transport │ ├── AjaxWebsocket.cs │ ├── AjaxWebsocketWriter.cs │ ├── BufferHandle.cs │ ├── Connection.cs │ ├── ConnectionAddresses.cs │ ├── IncomingMessage.cs │ ├── OutgoingMessage.cs │ └── TransportLayer.cs ├── Trunk │ ├── ITrunkManager.cs │ ├── Trunk.cs │ └── TrunkManager.cs ├── Users │ ├── AdUser.cs │ ├── AdUsers.cs │ ├── BaseUser.cs │ ├── BaseUsers.cs │ ├── CsvUser.cs │ ├── CsvUsers.cs │ ├── IUser.cs │ ├── IUsers.cs │ ├── IUserz.cs │ ├── UsersException.cs │ └── Userz.cs ├── WcfService │ ├── IWcfService.cs │ ├── IWcfServiceCallback.cs │ ├── WcfConfiguration.cs │ ├── WcfService.cs │ ├── WcfTurnConfiguration.cs │ ├── WcfUser.cs │ ├── WcfUsers.cs │ └── WcfVoipProvider.cs ├── Www │ ├── assets │ │ ├── bootstrap │ │ │ ├── bootstrap-alert.js │ │ │ ├── bootstrap-button.js │ │ │ ├── bootstrap-carousel.js │ │ │ ├── bootstrap-collapse.js │ │ │ ├── bootstrap-dropdown.js │ │ │ ├── bootstrap-modal.js │ │ │ ├── bootstrap-tab.js │ │ │ ├── bootstrap-transition.js │ │ │ ├── css │ │ │ │ ├── bootstrap-responsive.css │ │ │ │ ├── bootstrap-responsive.min.css │ │ │ │ ├── bootstrap.css │ │ │ │ └── bootstrap.min.css │ │ │ ├── img │ │ │ │ ├── glyphicons-halflings-white.png │ │ │ │ └── glyphicons-halflings.png │ │ │ └── js │ │ │ │ ├── bootstrap.js │ │ │ │ └── bootstrap.min.js │ │ ├── codemirror │ │ │ ├── closetag.js │ │ │ ├── codemirror.css │ │ │ ├── codemirror.js │ │ │ ├── simple-hint.css │ │ │ ├── simple-hint.js │ │ │ ├── xml-hint.js │ │ │ └── xml.js │ │ ├── handlebars-1.0.0.beta.6.js │ │ ├── hmac-md5.js │ │ ├── html5.js │ │ ├── jquery-1.7.1.min.js │ │ ├── jquery-1.8.3.min.js │ │ ├── jquery.validate.min.js │ │ └── md5.js │ ├── index.css │ ├── index.html │ ├── index.js │ ├── jquery.officesipApi.js │ ├── xmlEditorHints.js │ └── xmlHelper.js ├── Xcap │ ├── PidfManipulationHandler.cs │ └── ResourceListsHandler.cs ├── app.manifest └── dll │ ├── CsvReader.dll │ ├── CsvReader.xml │ ├── CsvReader_src.zip │ ├── DataVirtualization.dll │ ├── DataVirtualization.zip │ ├── DnDns.dll │ ├── Http.Message.dfa │ ├── Http.Message.dll │ ├── ICSharpCode.AvalonEdit.dll │ ├── Json45r7.zip │ ├── Newtonsoft.Json.dll │ ├── Newtonsoft.Json.xml │ ├── Sip.Message.dfa │ ├── Sip.Message.dll │ └── SocketServers.dll ├── Setup ├── License.rtf ├── Product.wxs ├── Setup.wixproj ├── WwwFiles.bat ├── WwwFiles.wxs ├── bannrbmp.bmp └── dlgbmp.bmp └── Tests ├── Collections └── BinaryHeapTest.cs ├── ConnectionTest.cs ├── LoadTables.cs ├── MultiTimerTest.cs ├── Properties └── AssemblyInfo.cs ├── ProxyServerTU ├── ConnectionAddressTest.cs ├── LocalTrunkProxieTest.cs └── ProxyServerTUTest.cs ├── Rtp ├── DtmfDecoderTest.cs ├── DtmfEventMessageTest.cs ├── JitterBufferTest.cs ├── NtpTimestampTest.cs ├── RtcpMessageTest.cs ├── RtpMessageTest.cs └── SsrcTest.cs ├── ServiceSoap ├── DirectorySearchRequestTest.cs ├── DirectorySearchResponseTest.cs └── Helpers.cs ├── Simple └── PresenceDocumentTest.cs ├── Test.csproj └── Transaction ├── BaseClientTransactionTest.cs ├── BaseServerTransactionTest.cs ├── BaseTransactionTest.cs ├── InviteClientTransactionTest.cs ├── InviteServerTransactionTest.cs ├── NonInviteClientTransactionTest.cs └── NonInviteServerTransactionTest.cs /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | 9 | # Build results 10 | 11 | [Dd]ebug*/ 12 | [Rr]elease/ 13 | 14 | build/ 15 | 16 | 17 | [Tt]est[Rr]esult 18 | [Bb]uild[Ll]og.* 19 | 20 | *_i.c 21 | *_p.c 22 | *.ilk 23 | *.meta 24 | *.obj 25 | *.pch 26 | *.pdb 27 | *.pgc 28 | *.pgd 29 | *.rsp 30 | *.sbr 31 | *.tlb 32 | *.tli 33 | *.tlh 34 | *.tmp 35 | *.vspscc 36 | *.vssscc 37 | .builds 38 | 39 | *.pidb 40 | 41 | *.log 42 | *.scc 43 | # Visual C++ cache files 44 | ipch/ 45 | *.aps 46 | *.ncb 47 | *.opensdf 48 | *.sdf 49 | 50 | # Visual Studio profiler 51 | *.psess 52 | *.vsp 53 | 54 | # Guidance Automation Toolkit 55 | *.gpState 56 | 57 | # ReSharper is a .NET coding add-in 58 | _ReSharper*/ 59 | 60 | *.[Rr]e[Ss]harper 61 | 62 | # NCrunch 63 | *.ncrunch* 64 | .*crunch*.local.xml 65 | 66 | # Installshield output folder 67 | [Ee]xpress 68 | 69 | # DocProject is a documentation generator add-in 70 | DocProject/buildhelp/ 71 | DocProject/Help/*.HxT 72 | DocProject/Help/*.HxC 73 | DocProject/Help/*.hhc 74 | DocProject/Help/*.hhk 75 | DocProject/Help/*.hhp 76 | DocProject/Help/Html2 77 | DocProject/Help/html 78 | 79 | # Click-Once directory 80 | publish 81 | 82 | # Publish Web Output 83 | *.Publish.xml 84 | 85 | # Others 86 | [Bb]in 87 | [Oo]bj 88 | sql 89 | TestResults 90 | [Tt]est[Rr]esult* 91 | *.Cache 92 | ClientBin 93 | [Ss]tyle[Cc]op.* 94 | ~$* 95 | *.dbmdl 96 | 97 | *.[Pp]ublish.xml 98 | 99 | Generated_Code #added for RIA/Silverlight projects 100 | 101 | # Backup & report files from converting an old project file to a newer 102 | # Visual Studio version. Backup files are not needed, because we have git ;-) 103 | _UpgradeReport_Files/ 104 | Backup*/ 105 | UpgradeLog*.XML 106 | 107 | # NuGet 108 | packages/ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "XcapServer"] 2 | path = XcapServer 3 | url = https://github.com/vf1/xcap.org.git 4 | -------------------------------------------------------------------------------- /Certificate/MakeCert.bat: -------------------------------------------------------------------------------- 1 | "C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\makecert" -r -pe -n "CN=OfficeSIP Server" -b 01/01/2007 -e 01/01/2020 -sky exchange OfficeSIP.cer -sv OfficeSIP.pvk 2 | "C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\pvk2pfx.exe" -pvk OfficeSIP.pvk -spc OfficeSIP.cer -pfx OfficeSIP.pfx 3 | -------------------------------------------------------------------------------- /Certificate/OfficeSIP.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Certificate/OfficeSIP.cer -------------------------------------------------------------------------------- /Certificate/OfficeSIP.pfx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Certificate/OfficeSIP.pfx -------------------------------------------------------------------------------- /Certificate/OfficeSIP.pvk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Certificate/OfficeSIP.pvk -------------------------------------------------------------------------------- /ControlPanel.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlPanel", "ControlPanel\ControlPanel.csproj", "{33F1286D-4242-44C3-A396-C87A78E80A09}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Any CPU = Debug|Any CPU 9 | Release|Any CPU = Release|Any CPU 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {33F1286D-4242-44C3-A396-C87A78E80A09}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 13 | {33F1286D-4242-44C3-A396-C87A78E80A09}.Debug|Any CPU.Build.0 = Debug|Any CPU 14 | {33F1286D-4242-44C3-A396-C87A78E80A09}.Release|Any CPU.ActiveCfg = Release|Any CPU 15 | {33F1286D-4242-44C3-A396-C87A78E80A09}.Release|Any CPU.Build.0 = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /ControlPanel/AddUser.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | using System.Windows.Data; 8 | using System.Windows.Documents; 9 | using System.Windows.Input; 10 | using System.Windows.Media; 11 | using System.Windows.Media.Imaging; 12 | using System.Windows.Shapes; 13 | 14 | namespace ControlPanel 15 | { 16 | /// 17 | /// Interaction logic for AddUser.xaml 18 | /// 19 | public partial class AddUser : Window 20 | { 21 | private OkEnabler okEnabler; 22 | 23 | public AddUser() 24 | { 25 | this.okEnabler = new OkEnabler(this); 26 | 27 | InitializeComponent(); 28 | } 29 | 30 | private void Ok_Click(object sender, RoutedEventArgs e) 31 | { 32 | DialogResult = true; 33 | Close(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ControlPanel/AddVoipProvider.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Text; 4 | using System.Windows; 5 | 6 | namespace ControlPanel 7 | { 8 | /// 9 | /// Interaction logic for AddVoipProvider.xaml 10 | /// 11 | public partial class AddVoipProvider : Window 12 | { 13 | private OkEnabler okEnabler; 14 | 15 | public AddVoipProvider() 16 | { 17 | this.okEnabler = new OkEnabler(this); 18 | 19 | InitializeComponent(); 20 | } 21 | 22 | private void Ok_Click(object sender, RoutedEventArgs e) 23 | { 24 | DialogResult = true; 25 | Close(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ControlPanel/CompletionData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Media; 3 | using ICSharpCode.AvalonEdit.CodeCompletion; 4 | using ICSharpCode.AvalonEdit.Document; 5 | using ICSharpCode.AvalonEdit.Editing; 6 | 7 | namespace ControlPanel 8 | { 9 | public class CompletionData : ICompletionData 10 | { 11 | public CompletionData(string text) 12 | { 13 | this.Text = text; 14 | } 15 | 16 | public ImageSource Image 17 | { 18 | get { return null; } 19 | } 20 | 21 | public string Text 22 | { 23 | get; 24 | private set; 25 | } 26 | 27 | public object Content 28 | { 29 | get { return this.Text; } 30 | } 31 | 32 | public object Description 33 | { 34 | get { return this.Text; } 35 | } 36 | 37 | public double Priority 38 | { 39 | get { return 0; } 40 | } 41 | 42 | public void Complete(TextArea textArea, ISegment completionSegment, EventArgs insertionRequestEventArgs) 43 | { 44 | textArea.Document.Replace(completionSegment, this.Text); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ControlPanel/Converters/AvailabilityConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | using System.Windows.Controls; 6 | using System.Globalization; 7 | using System.Windows.Media; 8 | 9 | namespace ControlPanel 10 | { 11 | [ValueConversion(typeof(int), typeof(DrawingImage))] 12 | [ValueConversion(typeof(int), typeof(string))] 13 | class AvailabilityConverter 14 | : IValueConverter 15 | { 16 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 17 | { 18 | int availability = (int)value; 19 | 20 | string imageName; 21 | string availabilityName; 22 | 23 | if (availability < 3000) 24 | { 25 | imageName = @"presenceUnknown"; 26 | availabilityName = @"Unknown"; 27 | } 28 | else if (availability < 4500) 29 | { 30 | imageName = @"presenceOnline"; 31 | availabilityName = @"Available"; 32 | } 33 | else if (availability < 6000) 34 | { 35 | imageName = @"presenceIdleOnline"; 36 | availabilityName = @"Idle"; 37 | } 38 | else if (availability < 7500) 39 | { 40 | imageName = @"presenceBusy"; 41 | availabilityName = @"Busy"; 42 | } 43 | else if (availability < 9000) 44 | { 45 | imageName = @"presenceIdleBusy"; 46 | availabilityName = @"Busy (Away)"; 47 | } 48 | else if (availability < 12000) 49 | { 50 | imageName = @"presenceDnd"; 51 | availabilityName = @"Do Not Disturb"; 52 | } 53 | else if (availability < 15000) 54 | { 55 | imageName = @"presenceAway"; 56 | availabilityName = @"Be Right Back"; 57 | } 58 | else if (availability < 18000) 59 | { 60 | imageName = @"presenceAway"; 61 | availabilityName = @"Away"; 62 | } 63 | else 64 | { 65 | imageName = @"presenceOffline"; 66 | availabilityName = @"Offline"; 67 | } 68 | 69 | if (targetType == typeof(ImageSource)) 70 | return Application.Current.FindResource(imageName) as DrawingImage; 71 | 72 | return availabilityName; 73 | } 74 | 75 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 76 | { 77 | throw new NotSupportedException(); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /ControlPanel/Converters/LoadingConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | using System.Windows.Controls; 6 | using System.Globalization; 7 | 8 | namespace ControlPanel 9 | { 10 | [ValueConversion(typeof(Service1.User), typeof(string))] 11 | class LoadingConverter 12 | : IValueConverter 13 | { 14 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 15 | { 16 | var user = value as Service1.User; 17 | 18 | if (user == null) 19 | return @"Loading..."; 20 | 21 | return user.Name; 22 | } 23 | 24 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 25 | { 26 | throw new NotSupportedException(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ControlPanel/Converters/TrueFalseConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Data; 3 | using System.Globalization; 4 | 5 | namespace ControlPanel 6 | { 7 | [ValueConversion(typeof(bool), typeof(bool))] 8 | public class TrueFalseConverter 9 | : IValueConverter 10 | { 11 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 12 | { 13 | return !((bool)value); 14 | } 15 | 16 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 17 | { 18 | return !((bool)value); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ControlPanel/Converters/VisibilityConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Windows; 4 | using System.Windows.Data; 5 | using System.Windows.Controls; 6 | using System.Globalization; 7 | 8 | namespace ControlPanel 9 | { 10 | [ValueConversion(typeof(string[]), typeof(Visibility))] 11 | [ValueConversion(typeof(string), typeof(Visibility))] 12 | [ValueConversion(typeof(bool), typeof(Visibility))] 13 | class VisibilityConverter 14 | : IValueConverter 15 | { 16 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 17 | { 18 | if (value == null) 19 | return Visibility.Collapsed; 20 | if (value is string[]) 21 | if ((value as string[]).Length == 0) 22 | return Visibility.Collapsed; 23 | if (value is bool) 24 | if ((bool)value == false) 25 | return Visibility.Collapsed; 26 | return Visibility.Visible; 27 | } 28 | 29 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 30 | { 31 | throw new NotSupportedException(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ControlPanel/Crash.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Windows; 5 | using System.Windows.Controls; 6 | using System.Windows.Data; 7 | using System.Windows.Documents; 8 | using System.Windows.Input; 9 | using System.Windows.Media; 10 | using System.Windows.Media.Imaging; 11 | using System.Windows.Shapes; 12 | 13 | namespace ControlPanel 14 | { 15 | /// 16 | /// Interaction logic for Exception.xaml 17 | /// 18 | public partial class Crash : Window 19 | { 20 | public Crash() 21 | { 22 | InitializeComponent(); 23 | } 24 | 25 | private void Hyperlink_Click(object sender, RoutedEventArgs e) 26 | { 27 | this.Report.SelectAll(); 28 | this.Report.Copy(); 29 | 30 | using (System.Diagnostics.Process process = new System.Diagnostics.Process()) 31 | { 32 | process.StartInfo.FileName = "http://www.officesip.com/crash.html"; 33 | process.StartInfo.UseShellExecute = true; 34 | process.Start(); 35 | } 36 | 37 | Ok.IsEnabled = true; 38 | } 39 | 40 | private void Ok_Click(object sender, RoutedEventArgs e) 41 | { 42 | this.Close(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ControlPanel/EditUser.xaml: -------------------------------------------------------------------------------- 1 |  8 | 9 | 10 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /ControlPanel/EditUser.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | using System.Windows.Data; 8 | using System.Windows.Documents; 9 | using System.Windows.Input; 10 | using System.Windows.Media; 11 | using System.Windows.Media.Imaging; 12 | using System.Windows.Shapes; 13 | 14 | namespace ControlPanel 15 | { 16 | /// 17 | /// Interaction logic for EditUser.xaml 18 | /// 19 | public partial class EditUser : Window 20 | { 21 | private OkEnabler okEnabler; 22 | 23 | public EditUser() 24 | { 25 | this.okEnabler = new OkEnabler(this); 26 | 27 | InitializeComponent(); 28 | } 29 | 30 | private void Ok_Click(object sender, RoutedEventArgs e) 31 | { 32 | DialogResult = true; 33 | Close(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ControlPanel/Error.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /ControlPanel/Error.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | using System.Windows.Data; 8 | using System.Windows.Documents; 9 | using System.Windows.Input; 10 | using System.Windows.Media; 11 | using System.Windows.Media.Imaging; 12 | using System.Windows.Shapes; 13 | using System.ServiceModel; 14 | 15 | namespace ControlPanel 16 | { 17 | /// 18 | /// Interaction logic for Disconnected.xaml 19 | /// 20 | public partial class Error : Window 21 | { 22 | public Error() 23 | { 24 | InitializeComponent(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ControlPanel/Images/MainTab/group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/ControlPanel/Images/MainTab/group.png -------------------------------------------------------------------------------- /ControlPanel/Images/MainTab/home_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/ControlPanel/Images/MainTab/home_page.png -------------------------------------------------------------------------------- /ControlPanel/Images/MainTab/setting_tools.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/ControlPanel/Images/MainTab/setting_tools.png -------------------------------------------------------------------------------- /ControlPanel/Images/MainTab/telephone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/ControlPanel/Images/MainTab/telephone.png -------------------------------------------------------------------------------- /ControlPanel/Images/OfficeSIP Server.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/ControlPanel/Images/OfficeSIP Server.ico -------------------------------------------------------------------------------- /ControlPanel/Images/Windows-Security.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/ControlPanel/Images/Windows-Security.png -------------------------------------------------------------------------------- /ControlPanel/Login.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | using System.Windows.Data; 8 | using System.Windows.Documents; 9 | using System.Windows.Input; 10 | using System.Windows.Media; 11 | using System.Windows.Media.Imaging; 12 | using System.Windows.Shapes; 13 | 14 | namespace ControlPanel 15 | { 16 | /// 17 | /// Interaction logic for Login.xaml 18 | /// 19 | public partial class Login : Window 20 | { 21 | public Login() 22 | { 23 | InitializeComponent(); 24 | 25 | if (VistaSecurity.IsAdmin()) 26 | shield.Visibility = Visibility.Collapsed; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ControlPanel/Main.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | using System.Windows.Data; 8 | using System.Windows.Documents; 9 | using System.Windows.Input; 10 | using System.Windows.Media; 11 | using System.Windows.Media.Imaging; 12 | using System.Windows.Navigation; 13 | using System.Windows.Shapes; 14 | 15 | namespace ControlPanel 16 | { 17 | /// 18 | /// Interaction logic for Window1.xaml 19 | /// 20 | public partial class Main : Window 21 | { 22 | public Main() 23 | { 24 | InitializeComponent(); 25 | CommandBindings.AddRange(Programme.Instance.CommandBindings); 26 | } 27 | 28 | private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) 29 | { 30 | Commands.Close.Execute(null, null); 31 | } 32 | 33 | public new void Close() 34 | { 35 | this.Closing -= Window_Closing; 36 | base.Close(); 37 | } 38 | 39 | //private int processingIndicatorCount; 40 | 41 | //private void ShowProcessingIndicator() 42 | //{ 43 | // if (processingIndicatorCount++ == 0) 44 | // processingIndicator.Visibility = Visibility.Visible; 45 | //} 46 | 47 | //private void HideProcessingIndicator() 48 | //{ 49 | // if (processingIndicatorCount > 0) 50 | // if (--processingIndicatorCount == 0) 51 | // processingIndicator.Visibility = Visibility.Hidden; 52 | //} 53 | 54 | //private void Button_Click(object sender, RoutedEventArgs e) 55 | //{ 56 | // ShowProcessingIndicator(); 57 | //} 58 | 59 | //private void Button_Click_1(object sender, RoutedEventArgs e) 60 | //{ 61 | // HideProcessingIndicator(); 62 | //} 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /ControlPanel/MainResources.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 14 | 15 | 19 | 20 | 21 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ControlPanel/NewPassword.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | using System.Windows.Data; 8 | using System.Windows.Documents; 9 | using System.Windows.Input; 10 | using System.Windows.Media; 11 | using System.Windows.Media.Imaging; 12 | using System.Windows.Shapes; 13 | using System.Windows.Threading; 14 | 15 | namespace ControlPanel 16 | { 17 | /// 18 | /// Interaction logic for NewPassword.xaml 19 | /// 20 | public partial class NewPassword : Window 21 | { 22 | private DispatcherTimer timer; 23 | 24 | public NewPassword() 25 | { 26 | timer = new DispatcherTimer(); 27 | timer.Interval = new TimeSpan(0, 0, 0, 0, 1000); 28 | timer.Tick += timer_Tick; 29 | timer.IsEnabled = true; 30 | 31 | InitializeComponent(); 32 | } 33 | 34 | private void timer_Tick(object sender, EventArgs e) 35 | { 36 | Indicator.Background = (Password.Password == Validation.Password) ? Brushes.Green : Brushes.Red; 37 | } 38 | 39 | private void Ok_Click(object sender, RoutedEventArgs e) 40 | { 41 | DialogResult = true; 42 | Close(); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ControlPanel/NewVersion.xaml: -------------------------------------------------------------------------------- 1 |  8 | 9 | 11 | 12 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /ControlPanel/NewVersion.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | using System.Windows.Data; 8 | using System.Windows.Documents; 9 | using System.Windows.Input; 10 | using System.Windows.Media; 11 | using System.Windows.Media.Imaging; 12 | using System.Windows.Shapes; 13 | 14 | namespace ControlPanel 15 | { 16 | /// 17 | /// Interaction logic for NewVersion.xaml 18 | /// 19 | public partial class NewVersion : Window 20 | { 21 | public NewVersion() 22 | { 23 | InitializeComponent(); 24 | 25 | DataContext = this; 26 | } 27 | 28 | public string Version { get; set; } 29 | public string Url { get; set; } 30 | 31 | private void Button_Click(object sender, RoutedEventArgs e) 32 | { 33 | Close(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ControlPanel/Programme.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 12 | 16 | 19 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /ControlPanel/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.18010 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace ControlPanel.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ControlPanel/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ControlPanel/Properties/app.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /ControlPanel/Service References/Service1/Arrays.xsd: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ControlPanel/Service References/Service1/ControlPanel.Service1.Configurations.datasource: -------------------------------------------------------------------------------- 1 |  2 | 8 | 9 | ControlPanel.Service1.Configurations, Service References.Service1.Reference.cs, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null 10 | -------------------------------------------------------------------------------- /ControlPanel/Service References/Service1/ControlPanel.Service1.TURNConfigurations.datasource: -------------------------------------------------------------------------------- 1 |  2 | 8 | 9 | ControlPanel.Service1.TURNConfigurations, Service References.Service1.Reference.cs, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null 10 | -------------------------------------------------------------------------------- /ControlPanel/Service References/Service1/ControlPanel.Service1.User.datasource: -------------------------------------------------------------------------------- 1 |  2 | 8 | 9 | ControlPanel.Service1.User, Service References.Service1.Reference.cs, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null 10 | -------------------------------------------------------------------------------- /ControlPanel/Service References/Service1/ControlPanel.Service1.VoipProvider.datasource: -------------------------------------------------------------------------------- 1 |  2 | 8 | 9 | ControlPanel.Service1.VoipProvider, Service References.Service1.Reference.cs, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null 10 | -------------------------------------------------------------------------------- /ControlPanel/Service References/Service1/System.Net.xsd: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /ControlPanel/Service References/Service1/System.xsd: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /ControlPanel/Service References/TurnService1/Arrays.xsd: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ControlPanel/Service References/TurnService1/ControlPanel.TurnService1.WcfTurnConfiguration.datasource: -------------------------------------------------------------------------------- 1 |  2 | 8 | 9 | ControlPanel.TurnService1.WcfTurnConfiguration, Service References.TurnService1.Reference.cs, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null 10 | -------------------------------------------------------------------------------- /ControlPanel/Service References/TurnService1/System.Net.xsd: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /ControlPanel/ServiceControl.xaml: -------------------------------------------------------------------------------- 1 |  7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /ControlPanel/ServiceControl.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | using System.Windows.Data; 8 | using System.Windows.Documents; 9 | using System.Windows.Input; 10 | using System.Windows.Media; 11 | using System.Windows.Media.Imaging; 12 | using System.Windows.Shapes; 13 | using System.ServiceProcess; 14 | 15 | namespace ControlPanel 16 | { 17 | public partial class ServiceControl : Window 18 | { 19 | public ServiceControl() 20 | { 21 | InitializeComponent(); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /ControlPanel/ServiceOpen.xaml: -------------------------------------------------------------------------------- 1 |  7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /ControlPanel/ServiceOpen.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | using System.Windows.Data; 8 | using System.Windows.Documents; 9 | using System.Windows.Input; 10 | using System.Windows.Media; 11 | using System.Windows.Media.Imaging; 12 | using System.Windows.Shapes; 13 | 14 | namespace ControlPanel 15 | { 16 | public partial class ServiceOpen : Window 17 | { 18 | public ServiceOpen() 19 | { 20 | InitializeComponent(); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ControlPanel/TurnGui/EditTurnServer.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | using System.Windows.Data; 8 | using System.Windows.Documents; 9 | using System.Windows.Input; 10 | using System.Windows.Media; 11 | using System.Windows.Media.Imaging; 12 | using System.Windows.Shapes; 13 | 14 | namespace ControlPanel 15 | { 16 | /// 17 | /// Interaction logic for EditTurnServer.xaml 18 | /// 19 | public partial class EditTurnServer : Window 20 | { 21 | private OkEnabler okEnabler; 22 | 23 | public EditTurnServer() 24 | { 25 | this.okEnabler = new OkEnabler(this); 26 | 27 | InitializeComponent(); 28 | } 29 | 30 | private void Ok_Click(object sender, RoutedEventArgs e) 31 | { 32 | DialogResult = true; 33 | Close(); 34 | } 35 | 36 | private void NewKeys_Click(object sender, RoutedEventArgs e) 37 | { 38 | byte[] key = new byte[20]; 39 | 40 | Random random = new Random(Environment.TickCount); 41 | 42 | random.NextBytes(key); 43 | key1.Text = Convert.ToBase64String(key); 44 | 45 | random.NextBytes(key); 46 | key2.Text = Convert.ToBase64String(key); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ControlPanel/TurnGui/LoginTurnServer.xaml: -------------------------------------------------------------------------------- 1 |  8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | administrator 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /ControlPanel/TurnGui/LoginTurnServer.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | using System.Windows.Data; 8 | using System.Windows.Documents; 9 | using System.Windows.Input; 10 | using System.Windows.Media; 11 | using System.Windows.Media.Imaging; 12 | using System.Windows.Shapes; 13 | 14 | namespace ControlPanel 15 | { 16 | /// 17 | /// Interaction logic for AuthTurnServer.xaml 18 | /// 19 | public partial class LoginTurnServer : Window 20 | { 21 | public LoginTurnServer() 22 | { 23 | InitializeComponent(); 24 | } 25 | 26 | private void ok_Click(object sender, RoutedEventArgs e) 27 | { 28 | this.DialogResult = true; 29 | this.Close(); 30 | } 31 | 32 | private void address_TextChanged(object sender, TextChangedEventArgs e) 33 | { 34 | url.Text = string.IsNullOrEmpty(address.Text) ? 35 | "" : String.Format(@"net.tcp://{0}:10002/officesip.turn.server.n1", address.Text); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ControlPanel/UsersFetcher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using ControlPanel.Service1; 5 | // http://bea.stollnitz.com/blog/?p=426 6 | // based on Paul McClean's 7 | // http://www.codeproject.com/KB/WPF/WpfDataVirtualization.aspx 8 | using DataVirtualization; 9 | 10 | namespace ControlPanel 11 | { 12 | class UsersFetcher 13 | : IItemsProvider 14 | { 15 | private string id; 16 | private IWcfService service; 17 | 18 | public UsersFetcher(IWcfService service, string id) 19 | { 20 | this.id = id; 21 | this.service = service; 22 | } 23 | 24 | public int FetchCount() 25 | { 26 | return service.GetUsersCount(id); 27 | } 28 | 29 | public IList FetchRange(int startIndex, int pageCount, out int overallCount) 30 | { 31 | return service.GetUsers(out overallCount, id, startIndex, pageCount); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ControlPanel/UsersTabContent.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | using System.Windows.Data; 8 | using System.Windows.Documents; 9 | using System.Windows.Input; 10 | using System.Windows.Media; 11 | using System.Windows.Media.Imaging; 12 | using System.Windows.Navigation; 13 | using System.Windows.Shapes; 14 | 15 | namespace ControlPanel 16 | { 17 | /// 18 | /// Interaction logic for UsersTabContent.xaml 19 | /// 20 | public partial class UsersTabContent : UserControl 21 | { 22 | public UsersTabContent(Service1.Users users) 23 | { 24 | Id = users.Id; 25 | 26 | InitializeComponent(); 27 | } 28 | 29 | public string Id 30 | { 31 | get; 32 | private set; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ControlPanel/UsersTabHeader.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /ControlPanel/UsersTabHeader.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | using System.Windows.Data; 8 | using System.Windows.Documents; 9 | using System.Windows.Input; 10 | using System.Windows.Media; 11 | using System.Windows.Media.Imaging; 12 | using System.Windows.Navigation; 13 | using System.Windows.Shapes; 14 | 15 | namespace ControlPanel 16 | { 17 | /// 18 | /// Interaction logic for UsersTabHeader.xaml 19 | /// 20 | public partial class UsersTabHeader : UserControl 21 | { 22 | public UsersTabHeader(string text) 23 | { 24 | HeaderText = text; 25 | 26 | DataContext = this; 27 | 28 | InitializeComponent(); 29 | } 30 | 31 | public string HeaderText 32 | { 33 | get; 34 | private set; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ControlPanel/ValidationRules/DisplayNameValidationRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Globalization; 4 | using System.Windows.Controls; 5 | using System.Text.RegularExpressions; 6 | 7 | namespace ControlPanel 8 | { 9 | public class DisplayNameValidationRule 10 | : ValidationRule 11 | { 12 | public override ValidationResult Validate(object value, CultureInfo cultureInfo) 13 | { 14 | Regex regex = new Regex("^[^\"]*$"); 15 | 16 | if (regex.IsMatch(value as string)) 17 | return new ValidationResult(true, null); 18 | 19 | return new ValidationResult(false, "Invalid simbols"); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ControlPanel/ValidationRules/EmailValidationRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Globalization; 4 | using System.Windows.Controls; 5 | using System.Text.RegularExpressions; 6 | 7 | namespace ControlPanel 8 | { 9 | public class EmailValidationRule 10 | : ValidationRule 11 | { 12 | public override ValidationResult Validate(object value, CultureInfo cultureInfo) 13 | { 14 | Regex regex = new Regex( 15 | @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" + 16 | @"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" + 17 | @".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"); 18 | 19 | if(regex.IsMatch(value as string)) 20 | return new ValidationResult(true, null); 21 | 22 | return new ValidationResult(false, "Invalid email"); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ControlPanel/ValidationRules/HostnameValidationRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Globalization; 4 | using System.Windows.Controls; 5 | using System.Text.RegularExpressions; 6 | 7 | namespace ControlPanel 8 | { 9 | public class HostnameValidationRule 10 | : ValidationRule 11 | { 12 | public override ValidationResult Validate(object value, CultureInfo cultureInfo) 13 | { 14 | Regex regex = new Regex( 15 | @"^(([a-zA-Z0-9_\-]+)\.)+([a-zA-Z0-9_\-]+)$"); 16 | 17 | if (regex.IsMatch(value as string)) 18 | return new ValidationResult(true, null); 19 | 20 | return new ValidationResult(false, "Invalid hostname"); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ControlPanel/ValidationRules/IPAddressValidationRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Globalization; 4 | using System.Windows.Controls; 5 | using System.Net; 6 | 7 | namespace ControlPanel 8 | { 9 | public class IPAddressValidationRule 10 | : ValidationRule 11 | { 12 | public override ValidationResult Validate(object value, CultureInfo cultureInfo) 13 | { 14 | IPAddress ip; 15 | if (IPAddress.TryParse(value as string, out ip)) 16 | return new ValidationResult(true, null); 17 | 18 | return new ValidationResult(false, "Invalid IP address"); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ControlPanel/ValidationRules/IPEndPointValidationRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Globalization; 4 | using System.Windows.Controls; 5 | using System.Net; 6 | 7 | namespace ControlPanel 8 | { 9 | public class IPEndPointValidationRule 10 | : ValidationRule 11 | { 12 | public override ValidationResult Validate(object value1, CultureInfo cultureInfo) 13 | { 14 | var value = value1 as string; 15 | 16 | int hcolon = value.IndexOf(':'); 17 | if (hcolon >= 0) 18 | { 19 | int port; 20 | if (int.TryParse(value.Substring(hcolon + 1), out port) == false || port > 65535 || port < 0) 21 | return new ValidationResult(false, "Invalid port number"); 22 | 23 | value = value.Substring(0, hcolon); 24 | } 25 | 26 | IPAddress ip; 27 | if (IPAddress.TryParse(value as string, out ip) == false) 28 | return new ValidationResult(false, "Invalid IP address"); 29 | 30 | return new ValidationResult(true, null); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ControlPanel/ValidationRules/Key12ValidationRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Globalization; 4 | using System.Windows.Controls; 5 | 6 | namespace ControlPanel 7 | { 8 | public class Key12ValidationRule 9 | : ValidationRule 10 | { 11 | public override ValidationResult Validate(object value, CultureInfo cultureInfo) 12 | { 13 | try 14 | { 15 | byte[] key = Convert.FromBase64String(value as string); 16 | if (key.Length != 20) 17 | throw new Exception(); 18 | } 19 | catch 20 | { 21 | return new ValidationResult(false, "Invalid key, it must base64 encoded value 20 bytes length"); 22 | } 23 | 24 | return new ValidationResult(true, null); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ControlPanel/ValidationRules/MaxLength.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ControlPanel 4 | { 5 | public static class MaxLength 6 | { 7 | static MaxLength() 8 | { 9 | Username = 128; 10 | DisplayName = 128; 11 | Email = 128; 12 | Password = 64; 13 | Port = 5; 14 | Hostname = 255; 15 | IPEndPoint = 64; 16 | Uri = 128; 17 | } 18 | 19 | public static int Username { get; private set; } 20 | public static int DisplayName { get; private set; } 21 | public static int Email { get; private set; } 22 | public static int Password { get; private set; } 23 | public static int Port { get; private set; } 24 | public static int Hostname { get; private set; } 25 | public static int IPEndPoint { get; private set; } 26 | public static int Uri { get; private set; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ControlPanel/ValidationRules/OkEnabler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | 8 | namespace ControlPanel 9 | { 10 | public class OkEnabler 11 | { 12 | private int errorCount; 13 | private Button ok; 14 | private Window window; 15 | 16 | public OkEnabler(Window window) 17 | { 18 | this.errorCount = 0; 19 | 20 | this.window = window; 21 | this.window.Loaded += Window_Loaded; 22 | this.window.Closed += Window_Closed; 23 | Validation.AddErrorHandler(this.window, new EventHandler(Validation_Error)); 24 | } 25 | 26 | void Window_Closed(object sender, EventArgs e) 27 | { 28 | window.Loaded -= Window_Loaded; 29 | window.Closed -= Window_Closed; 30 | Validation.RemoveErrorHandler(window, new EventHandler(Validation_Error)); 31 | } 32 | 33 | void Window_Loaded(object sender, RoutedEventArgs e) 34 | { 35 | DependencyObject element = LogicalTreeHelper.FindLogicalNode(this.window, @"ok"); 36 | if (element != null && element is Button) 37 | { 38 | this.ok = element as Button; 39 | this.ok.IsEnabled = (errorCount == 0); 40 | } 41 | } 42 | 43 | private void Validation_Error(object sender, ValidationErrorEventArgs e) 44 | { 45 | if (e.Action == ValidationErrorEventAction.Added) 46 | errorCount++; 47 | if (e.Action == ValidationErrorEventAction.Removed) 48 | errorCount--; 49 | 50 | if (this.ok != null) 51 | this.ok.IsEnabled = (errorCount == 0); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ControlPanel/ValidationRules/OptionalValidationRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Globalization; 4 | using System.Windows.Controls; 5 | using System.Net; 6 | 7 | namespace ControlPanel 8 | { 9 | public class OptionalValidationRule 10 | : ValidationRule 11 | { 12 | private ValidationRule rule; 13 | 14 | public OptionalValidationRule(ValidationRule rule) 15 | { 16 | this.rule = rule; 17 | } 18 | 19 | public override ValidationResult Validate(object value, CultureInfo cultureInfo) 20 | { 21 | if (string.IsNullOrEmpty(value as string) == false) 22 | return rule.Validate(value, cultureInfo); 23 | 24 | return new ValidationResult(true, null); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ControlPanel/ValidationRules/PortValidationRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Globalization; 4 | using System.Windows.Controls; 5 | 6 | namespace ControlPanel 7 | { 8 | public class PortValidationRule 9 | : ValidationRule 10 | { 11 | public override ValidationResult Validate(object value, CultureInfo cultureInfo) 12 | { 13 | int port; 14 | if (int.TryParse(value as string, out port)) 15 | { 16 | if (port > 0 && port <= 65535) 17 | return new ValidationResult(true, null); 18 | } 19 | 20 | return new ValidationResult(false, "Port in integer value from 0 to 65535"); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ControlPanel/ValidationRules/UriValidationRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Globalization; 4 | using System.Windows.Controls; 5 | using System.Text.RegularExpressions; 6 | 7 | namespace ControlPanel 8 | { 9 | public class UriValidationRule 10 | : ValidationRule 11 | { 12 | public override ValidationResult Validate(object value, CultureInfo cultureInfo) 13 | { 14 | Regex regex = new Regex( 15 | @"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" + 16 | @"\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" + 17 | @".)+))([a-zA-Z0-9]+)(\]?)$"); 18 | 19 | if (regex.IsMatch(value as string)) 20 | return new ValidationResult(true, null); 21 | 22 | return new ValidationResult(false, "Invalid URI"); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ControlPanel/ValidationRules/UsernameValidationRule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Globalization; 4 | using System.Windows.Controls; 5 | using System.Text.RegularExpressions; 6 | 7 | namespace ControlPanel 8 | { 9 | public class UsernameValidationRule 10 | : ValidationRule 11 | { 12 | public override ValidationResult Validate(object value, CultureInfo cultureInfo) 13 | { 14 | Regex regex = new Regex(@"^[a-z0-9\.\-_]+$"); 15 | 16 | if(regex.IsMatch(value as string)) 17 | return new ValidationResult(true, null); 18 | 19 | return new ValidationResult(false, "Invalid username"); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ControlPanel/ValidationRules/Validator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Windows.Data; 4 | using System.Windows.Markup; 5 | using System.Windows.Controls; 6 | 7 | namespace ControlPanel 8 | { 9 | public class Validator : MarkupExtension 10 | { 11 | Binding binding; 12 | 13 | public Validator() 14 | { 15 | binding = new Binding(@"None"); 16 | binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; 17 | binding.Mode = BindingMode.OneWayToSource; 18 | binding.Source = this; 19 | binding.NotifyOnValidationError = true; 20 | } 21 | 22 | public override object ProvideValue(IServiceProvider serviceProvider) 23 | { 24 | return binding.ProvideValue(serviceProvider); 25 | } 26 | 27 | public string Rule 28 | { 29 | get 30 | { 31 | return binding.ValidationRules[0].ToString(); 32 | } 33 | set 34 | { 35 | binding.ValidationRules.Clear(); 36 | 37 | if (value.StartsWith("~")) 38 | binding.ValidationRules.Add(new OptionalValidationRule(GetValidationRule(value.Substring(1)))); 39 | else 40 | binding.ValidationRules.Add(GetValidationRule(value)); 41 | } 42 | } 43 | 44 | private ValidationRule GetValidationRule(string value) 45 | { 46 | switch (value) 47 | { 48 | case "UsernameValidationRule": 49 | return new UsernameValidationRule(); 50 | case "DisplayNameValidationRule": 51 | return new DisplayNameValidationRule(); 52 | case "EmailValidationRule": 53 | return new EmailValidationRule(); 54 | case "PortValidationRule": 55 | return new PortValidationRule(); 56 | case "Key12ValidationRule": 57 | return new Key12ValidationRule(); 58 | case "IPAddressValidationRule": 59 | return new IPAddressValidationRule(); 60 | case "IPEndPointValidationRule": 61 | return new IPEndPointValidationRule(); 62 | case "HostnameValidationRule": 63 | return new HostnameValidationRule(); 64 | case "UriValidationRule": 65 | return new UriValidationRule(); 66 | default: 67 | throw new NotSupportedException(); 68 | } 69 | } 70 | 71 | // Do NOT remove!!! 72 | public object None 73 | { 74 | get; 75 | set; 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /ControlPanel/VistaSecurity.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Runtime.InteropServices; 5 | using System.Diagnostics; 6 | //using System.Windows.Forms; 7 | using System.Security.Principal; 8 | 9 | namespace ControlPanel 10 | { 11 | public static class VistaSecurity 12 | { 13 | //[DllImport("user32")] 14 | //public static extern UInt32 SendMessage(IntPtr hWnd, UInt32 msg, UInt32 wParam, UInt32 lParam); 15 | 16 | //internal const int BCM_FIRST = 0x1600; 17 | //internal const int BCM_SETSHIELD = (BCM_FIRST + 0x000C); 18 | 19 | //static internal bool IsVistaOrHigher() 20 | //{ 21 | // return Environment.OSVersion.Version.Major < 6; 22 | //} 23 | 24 | /// 25 | /// Checks if the process is elevated 26 | /// 27 | /// If is elevated 28 | static internal bool IsAdmin() 29 | { 30 | WindowsIdentity id = WindowsIdentity.GetCurrent(); 31 | WindowsPrincipal p = new WindowsPrincipal(id); 32 | return p.IsInRole(WindowsBuiltInRole.Administrator); 33 | } 34 | 35 | ///// 36 | ///// Add a shield icon to a button 37 | ///// 38 | ///// The button 39 | //static internal void AddShieldToButton(Button b) 40 | //{ 41 | // b.FlatStyle = FlatStyle.System; 42 | // SendMessage(b.Handle, BCM_SETSHIELD, 0, 0xFFFFFFFF); 43 | //} 44 | 45 | /// 46 | /// Restart the current process with administrator credentials 47 | /// 48 | internal static void RestartElevated() 49 | { 50 | ProcessStartInfo startInfo = new ProcessStartInfo(); 51 | startInfo.UseShellExecute = true; 52 | startInfo.WorkingDirectory = Environment.CurrentDirectory; 53 | startInfo.FileName = System.Reflection.Assembly.GetExecutingAssembly().Location; 54 | startInfo.Verb = "runas"; 55 | try 56 | { 57 | Process p = Process.Start(startInfo); 58 | } 59 | catch (System.ComponentModel.Win32Exception) 60 | { 61 | return; //If cancelled, do nothing 62 | } 63 | 64 | Programme.Current.Shutdown(); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2007-2015 Vitali Fomine 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | OfficeSIP Server 2 | ================ 3 | 4 | OfficeSIP is a SIP server for Windows written in C#. 5 | 6 | 7 | Website and Documentation 8 | ========================= 9 | 10 | [officesip.com](https://officesip.com) 11 | -------------------------------------------------------------------------------- /Server/Accounts/AccountPath.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Globalization; 4 | 5 | namespace Sip.Server.Accounts 6 | { 7 | class AccountPath 8 | { 9 | public const string AccountTag = @"{account-id}"; 10 | 11 | private readonly string baseFileName; 12 | private readonly int expectedLength; 13 | 14 | public AccountPath(string baseFileName) 15 | { 16 | this.baseFileName = baseFileName; 17 | this.expectedLength = GetFileName(0).Length; 18 | } 19 | 20 | public string RootDirectory 21 | { 22 | get 23 | { 24 | int index = baseFileName.IndexOf(AccountTag); 25 | if (index >= 0) 26 | return baseFileName.Substring(0, index); 27 | 28 | return Path.GetDirectoryName(baseFileName); 29 | } 30 | } 31 | 32 | public string GetAccountRootDirectory(int accountId) 33 | { 34 | int index = baseFileName.IndexOf(AccountTag); 35 | 36 | if (index >= 0) 37 | return baseFileName 38 | .Substring(0, index + AccountTag.Length) 39 | .Replace(AccountTag, accountId.ToString("x8")); 40 | 41 | return null; 42 | } 43 | 44 | public string SearchPattern 45 | { 46 | get 47 | { 48 | return Path.GetFileName(baseFileName); 49 | } 50 | } 51 | 52 | public string GetFileName(int accountId) 53 | { 54 | return baseFileName.Replace(AccountTag, accountId.ToString("x8")); 55 | } 56 | 57 | public int? GetAccountId(string fileName) 58 | { 59 | int start = baseFileName.IndexOf(AccountTag); 60 | 61 | if (start > 0 && expectedLength == fileName.Length) 62 | { 63 | int result = -1; 64 | if (int.TryParse(fileName.Substring(start, 8), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out result)) 65 | if (GetFileName(result) == fileName) 66 | return result; 67 | } 68 | 69 | return null; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Server/Accounts/AccountsException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Sip.Server.Accounts 4 | { 5 | enum AccountsErrors 6 | { 7 | InvalidId, 8 | DomainUsed, 9 | IdUsed, 10 | OldNotFound, 11 | DomainRequred, 12 | } 13 | 14 | public class AccountsException 15 | : Exception 16 | { 17 | internal AccountsException(AccountsErrors code) 18 | : base(GetMessage(code)) 19 | { 20 | 21 | } 22 | 23 | internal static string GetMessage(AccountsErrors code) 24 | { 25 | switch (code) 26 | { 27 | case AccountsErrors.InvalidId: 28 | return @"account.Id == Account.InvalidId"; 29 | case AccountsErrors.DomainUsed: 30 | return @"Domain name is used by another account"; 31 | case AccountsErrors.IdUsed: 32 | return @"Failed to add account, id was used"; 33 | case AccountsErrors.OldNotFound: 34 | return @"Old account not found"; 35 | case AccountsErrors.DomainRequred: 36 | return @"Domain name is not specified"; 37 | } 38 | 39 | return null; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Server/Accounts/IAccount.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Sip.Server.Accounts 4 | { 5 | public interface IAccount 6 | { 7 | int Id { get; } 8 | string Email { get; } 9 | string Password { get; } 10 | string DomainName { get; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Server/Accounts/IAccounts.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Base.Message; 3 | 4 | namespace Sip.Server.Accounts 5 | { 6 | interface IAccounts 7 | { 8 | IAccount GetAccount(int id); 9 | IAccount GetAccount(ByteArrayPart domain); 10 | bool HasDomain(ByteArrayPart domain); 11 | 12 | void ForEach(Action action); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Server/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Server/Application.cs: -------------------------------------------------------------------------------- 1 | using System.ServiceProcess; 2 | 3 | namespace Sip.Server 4 | { 5 | static class Application 6 | { 7 | static void Main(string[] args) 8 | { 9 | bool b = true; 10 | 11 | if (args.Length == 1) 12 | switch (char.Parse(args[0])) 13 | { 14 | case 'd': 15 | new Service().Emulate(); 16 | b = false; 17 | break; 18 | } 19 | 20 | 21 | if (b == true) 22 | ServiceBase.Run(new Service()); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /Server/Authorization/DigestAuthentication.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Server/Authorization/DigestAuthentication.cs -------------------------------------------------------------------------------- /Server/Authorization/Http/HttpAuthorizationManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Base.Message; 3 | using Http.Message; 4 | 5 | namespace Server.Authorization.Http 6 | { 7 | class HttpAuthorizationManager 8 | : AuthorizationManager 9 | , IHttpAuthorizationManager 10 | { 11 | public Func ValidateAuthorization { set; get; } 12 | 13 | protected override bool ValidateAuthorizationInternal(HttpMessageReader reader, ByteArrayPart username, int param) 14 | { 15 | return ValidateAuthorization(reader, username, param); 16 | } 17 | 18 | protected override HttpMessageWriter GetResponseBegin(HttpMessageReader reader) 19 | { 20 | var writer = new HttpMessageWriter(); 21 | writer.WriteStatusLine(StatusCodes.Unauthorized); 22 | writer.WriteAccessControlAllowOrigin(true); 23 | writer.WriteAccessControlAllowCredentials(true); 24 | writer.WriteAccessControlAllowMethods(Methods.Get, Methods.Put, Methods.Post, Methods.Delete, Methods.Options); 25 | writer.WriteAccessControlAllowHeaders(System.Text.Encoding.UTF8.GetBytes("Authorization")); 26 | writer.WriteAccessControlExposeHeaders(System.Text.Encoding.UTF8.GetBytes("WWW-Authenticate")); 27 | 28 | return writer; 29 | } 30 | 31 | protected override void WriteMessageEnd(HttpMessageWriter writer) 32 | { 33 | writer.WriteContentLength(0); 34 | writer.WriteCRLF(); 35 | } 36 | 37 | protected override bool CanTryAgainWhenFail(AuthSchemes scheme) 38 | { 39 | return scheme == AuthSchemes.Digest; 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Server/Authorization/Http/IHttpAuthorizationManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Base.Message; 3 | using Http.Message; 4 | 5 | namespace Server.Authorization.Http 6 | { 7 | interface IHttpAuthorizationManager 8 | : IAuthorizationManager 9 | { 10 | Func ValidateAuthorization { set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Server/Authorization/Sip/ISipAuthorizationManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Sip.Message; 3 | using Server.Authorization; 4 | 5 | namespace Server.Authorization.Sip 6 | { 7 | interface ISipAuthorizationManager 8 | : IAuthorizationManager 9 | { 10 | void WriteSignature(SipMessageWriter writer); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Server/Authorization/Sip/SipAuthorizationManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Base.Message; 4 | using Sip.Message; 5 | using Server.Authorization; 6 | 7 | namespace Server.Authorization.Sip 8 | { 9 | class SipAuthorizationManager 10 | : AuthorizationManager 11 | , ISipAuthorizationManager 12 | { 13 | protected override bool ValidateAuthorizationInternal(SipMessageReader reader, ByteArrayPart username, int param) 14 | { 15 | return true; 16 | } 17 | 18 | public void WriteSignature(SipMessageWriter writer) 19 | { 20 | SipMicrosoftAuthentication.SignMessage(writer); 21 | } 22 | 23 | protected override SipMessageWriter GetResponseBegin(SipMessageReader reader) 24 | { 25 | var writer = new SipResponseWriter(); 26 | writer.WriteStatusLine(StatusCodes.Unauthorized); 27 | writer.CopyViaToFromCallIdRecordRouteCSeq(reader, StatusCodes.Unauthorized); 28 | 29 | return writer; 30 | } 31 | 32 | protected override void WriteMessageEnd(SipMessageWriter writer) 33 | { 34 | writer.WriteContentLength(0); 35 | writer.WriteCRLF(); 36 | } 37 | 38 | protected override bool CanTryAgainWhenFail(AuthSchemes scheme) 39 | { 40 | return scheme == AuthSchemes.Digest; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Server/Authorization/Sip/SipDigestAuthentication.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Server/Authorization/Sip/SipDigestAuthentication.cs -------------------------------------------------------------------------------- /Server/Authorization/Sip/SipMicrosoftAuthentication.cs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Server/Authorization/Sip/SipMicrosoftAuthentication.cs -------------------------------------------------------------------------------- /Server/BufferManagerProxy.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Base.Message; 3 | using Sip.Message; 4 | 5 | namespace Sip.Server 6 | { 7 | class BufferManagerProxy 8 | : IBufferManager 9 | { 10 | public ArraySegment Allocate(int size) 11 | { 12 | return SocketServers.BufferManager.Allocate(size); 13 | } 14 | 15 | public void Reallocate(ref ArraySegment segment, int extraSize) 16 | { 17 | var newSegment = SocketServers.BufferManager.Allocate(segment.Count + extraSize); 18 | 19 | Buffer.BlockCopy(segment.Array, segment.Offset, newSegment.Array, newSegment.Offset, segment.Count); 20 | 21 | SocketServers.BufferManager.Free(ref segment); 22 | 23 | segment = newSegment; 24 | } 25 | 26 | public void Free(ref ArraySegment segment) 27 | { 28 | SocketServers.BufferManager.Free(ref segment); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Server/Collections/BinaryHeap.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace System.Collections.Generic 5 | { 6 | class BinaryHeap 7 | { 8 | private IList list; 9 | private IComparer comparer; 10 | 11 | public BinaryHeap(IList list, IComparer comparer) 12 | { 13 | this.list = list; 14 | this.comparer = (comparer != null) ? comparer : Comparer.Default; 15 | } 16 | 17 | public void AddRange(IEnumerable values) 18 | { 19 | foreach (var value in values) 20 | Add(value); 21 | } 22 | 23 | public void Add(T value) 24 | { 25 | list.Add(value); 26 | 27 | int newone = Count - 1; 28 | int parent = (newone - 1) / 2; 29 | 30 | while (newone > 0 && comparer.Compare(list[parent], list[newone]) < 0) 31 | { 32 | T tempValue = list[newone]; 33 | list[newone] = list[parent]; 34 | list[parent] = tempValue; 35 | 36 | newone = parent; 37 | parent = (newone - 1) / 2; 38 | } 39 | } 40 | 41 | public T DeleteRoot() 42 | { 43 | T result = list[0]; 44 | 45 | int last = Count - 1; 46 | 47 | list[0] = list[last]; 48 | list.RemoveAt(last); 49 | 50 | Heapify(0); 51 | 52 | return result; 53 | } 54 | 55 | public T PeekRoot() 56 | { 57 | return list[0]; 58 | } 59 | 60 | public void Heapify(int index) 61 | { 62 | int leftChild, rightChild, minChild; 63 | int count = Count; 64 | 65 | for (; ; ) 66 | { 67 | leftChild = 2 * index + 1; 68 | rightChild = 2 * index + 2; 69 | minChild = index; 70 | 71 | if (leftChild < count && comparer.Compare(list[leftChild], list[minChild]) > 0) 72 | minChild = leftChild; 73 | 74 | if (rightChild < count && comparer.Compare(list[rightChild], list[minChild]) > 0) 75 | minChild = rightChild; 76 | 77 | if (minChild == index) 78 | break; 79 | 80 | T tempValue = list[index]; 81 | list[index] = list[minChild]; 82 | list[minChild] = tempValue; 83 | 84 | index = minChild; 85 | } 86 | } 87 | 88 | public int Count 89 | { 90 | get { return list.Count; } 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Server/Collections/EmptyEnumerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | 5 | namespace System.Collections.Generic 6 | { 7 | class EmptyEnumerable 8 | : IEnumerable 9 | { 10 | public static readonly IEnumerable Instance = new EmptyEnumerable(); 11 | 12 | public IEnumerator GetEnumerator() 13 | { 14 | return EmptyEnumerator.Instance; 15 | } 16 | 17 | IEnumerator IEnumerable.GetEnumerator() 18 | { 19 | return EmptyEnumerator.Instance; 20 | } 21 | } 22 | 23 | class EmptyEnumerator 24 | : IEnumerator 25 | { 26 | public static readonly IEnumerator Instance = new EmptyEnumerator(); 27 | 28 | public void Dispose() 29 | { 30 | } 31 | 32 | public bool MoveNext() 33 | { 34 | return false; 35 | } 36 | 37 | public void Reset() 38 | { 39 | } 40 | 41 | public T Current 42 | { 43 | get { throw new InvalidOperationException(); } 44 | } 45 | 46 | Object IEnumerator.Current 47 | { 48 | get { throw new InvalidOperationException(); } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Server/Collections/FastResizablePool.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using SocketServers; 5 | 6 | namespace System.Collections.Generic 7 | { 8 | public sealed class FastResizablePool 9 | : ILockFreePool 10 | where T : class, IDisposable, ILockFreePoolItem, ILockFreePoolItemIndex, new() 11 | { 12 | private object sync; 13 | private int poolIndex; 14 | private LockFreeFastPool[] pools; 15 | 16 | private const int minSize = 256; 17 | private const int maxPoolsQty = 16; 18 | 19 | public FastResizablePool() 20 | { 21 | poolIndex = 0; 22 | sync = new object(); 23 | pools = new LockFreeFastPool[maxPoolsQty]; 24 | pools[0] = new LockFreeFastPool(minSize); 25 | } 26 | 27 | public void Dispose() 28 | { 29 | for (int i = 1; i < maxPoolsQty; i++) 30 | if (pools[i] != null) 31 | pools[i].Dispose(); 32 | } 33 | 34 | public T Get() 35 | { 36 | for (int i = Thread.VolatileRead(ref poolIndex); i >= 0; i--) 37 | { 38 | T value = pools[i].GetIfSpaceAvailable(); 39 | if (value != default(T)) 40 | { 41 | value.Index |= i << 24; 42 | return value; 43 | } 44 | } 45 | 46 | lock (sync) 47 | { 48 | for (; ; ) 49 | { 50 | int index = Thread.VolatileRead(ref poolIndex); 51 | 52 | T value = pools[index].GetIfSpaceAvailable(); 53 | if (value != default(T)) 54 | { 55 | value.Index |= index << 24; 56 | return value; 57 | } 58 | 59 | int newIndex = Thread.VolatileRead(ref poolIndex) + 1; 60 | pools[newIndex] = new LockFreeFastPool(minSize << newIndex); 61 | Thread.VolatileWrite(ref poolIndex, newIndex); 62 | } 63 | } 64 | } 65 | 66 | public void Put(ref T item) 67 | { 68 | Put(item); 69 | item = default(T); 70 | } 71 | 72 | public void Put(T value) 73 | { 74 | int index = value.Index >> 24; 75 | value.Index &= 0x00ffffff; 76 | 77 | pools[index].Put(value); 78 | } 79 | 80 | public int Created 81 | { 82 | get { throw new NotImplementedException(); } 83 | } 84 | 85 | public int Queued 86 | { 87 | get { throw new NotImplementedException(); } 88 | } 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /Server/Collections/SkipNullArrayEnumerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace System.Collections.Generic 5 | { 6 | class SkipNullArrayEnumerator 7 | : IEnumerator 8 | where T : class 9 | { 10 | private int index; 11 | private T[] array; 12 | 13 | public SkipNullArrayEnumerator(int capacity) 14 | { 15 | array = new T[capacity]; 16 | } 17 | 18 | public void Initialize(T[] array) 19 | { 20 | index = -1; 21 | 22 | if (this.array == null || this.array.Length < array.Length) 23 | this.array = new T[array.Length]; 24 | 25 | for (int i = 0, j = 0; i < array.Length; i++) 26 | if (array[i] != default(T)) 27 | this.array[j++] = array[i]; 28 | } 29 | 30 | public void Dispose() 31 | { 32 | Array.Clear(array, 0, array.Length); 33 | } 34 | 35 | public bool MoveNext() 36 | { 37 | return ++index < array.Length && array[index] != default(T); 38 | } 39 | 40 | public void Reset() 41 | { 42 | index = -1; 43 | } 44 | 45 | public T Current 46 | { 47 | get { return array[index]; } 48 | } 49 | 50 | Object IEnumerator.Current 51 | { 52 | get { return array[index]; } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Server/Collections/ThreadSafeList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using System.Collections.Generic; 4 | 5 | namespace System.Collections.Generic.ThreadSafe 6 | { 7 | struct List 8 | { 9 | private IList list; 10 | 11 | public List(IList list) 12 | { 13 | this.list = list; 14 | } 15 | 16 | public void AddIfAbsent(T item) 17 | { 18 | lock (list) 19 | { 20 | if (list.IndexOf(item) < 0) 21 | list.Add(item); 22 | } 23 | } 24 | 25 | public void Replace(T item) 26 | { 27 | lock (list) 28 | { 29 | list.Remove(item); 30 | list.Add(item); 31 | } 32 | } 33 | 34 | public bool Remove(T item) 35 | { 36 | bool result; 37 | 38 | lock (list) 39 | result = list.Remove(item); 40 | 41 | return result; 42 | } 43 | 44 | public bool RemoveFirst

(P param, Func predicate) 45 | { 46 | bool result = false; 47 | 48 | lock (list) 49 | { 50 | for (int i = 0; i < list.Count; i++) 51 | if (predicate(list[i], param)) 52 | { 53 | list.RemoveAt(i); 54 | result = true; 55 | break; 56 | } 57 | } 58 | 59 | return result; 60 | } 61 | 62 | public void ForEach(Action action) 63 | { 64 | lock (list) 65 | { 66 | for (int i = 0; i < list.Count; i++) 67 | action(list[i]); 68 | } 69 | } 70 | 71 | public void RecursiveForEach(Action action) 72 | { 73 | Monitor.Enter(list); 74 | 75 | if (list.Count > 0) 76 | RecursiveForEach(action, 0); 77 | else 78 | Monitor.Exit(list); 79 | } 80 | 81 | public void RecursiveForEach(Action action, int index) 82 | { 83 | var item = list[index++]; 84 | 85 | if (index < list.Count) 86 | RecursiveForEach(action, index); 87 | else 88 | Monitor.Exit(list); 89 | 90 | action(item); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Server/Configuration/ByteArrayConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Configuration; 3 | using System.ComponentModel; 4 | using System.Globalization; 5 | 6 | namespace Sip.Server.Configuration 7 | { 8 | class ByteArrayConverter 9 | : ConfigurationConverterBase 10 | { 11 | public override bool CanConvertTo(ITypeDescriptorContext ctx, Type type) 12 | { 13 | return type == typeof(string); 14 | } 15 | 16 | public override bool CanConvertFrom(ITypeDescriptorContext ctx, Type type) 17 | { 18 | return type == typeof(string); 19 | } 20 | 21 | public override object ConvertTo(ITypeDescriptorContext ctx, CultureInfo ci, object value, Type type) 22 | { 23 | if (value == null) 24 | return new ArgumentNullException(); 25 | 26 | if (value.GetType() != typeof(byte[])) 27 | throw new ArgumentException(); 28 | 29 | return Convert.ToBase64String(value as byte[]); 30 | } 31 | 32 | public override object ConvertFrom(ITypeDescriptorContext ctx, CultureInfo ci, object data) 33 | { 34 | if (data == null) 35 | return new ArgumentNullException(@"data"); 36 | 37 | return Convert.FromBase64String(data as string); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Server/Configuration/ConfigurationMonitor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Timers; 4 | using System.Configuration; 5 | 6 | namespace Server.Configuration 7 | { 8 | class ConfigurationMonitor 9 | : IDisposable 10 | { 11 | private Timer timer; 12 | private FileSystemWatcher watcher; 13 | 14 | public event EventHandler Changed; 15 | 16 | public void Dispose() 17 | { 18 | if (watcher != null) 19 | { 20 | watcher.EnableRaisingEvents = false; 21 | watcher.Dispose(); 22 | watcher = null; 23 | } 24 | 25 | if (timer == null) 26 | { 27 | timer.Dispose(); 28 | timer = null; 29 | } 30 | } 31 | 32 | public void StartMonitoring(ConfigurationSectionEx section) 33 | { 34 | if (timer == null) 35 | { 36 | timer = new Timer(500); 37 | timer.Elapsed += new ElapsedEventHandler(Timer_Elapsed); 38 | timer.AutoReset = false; 39 | } 40 | 41 | if (watcher == null) 42 | { 43 | watcher = new FileSystemWatcher(); 44 | watcher.Changed += Watcher_Changed; 45 | watcher.Created += Watcher_Changed; 46 | watcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.CreationTime; 47 | } 48 | 49 | watcher.EnableRaisingEvents = false; 50 | 51 | watcher.Path = Path.GetDirectoryName(section.FilePath); 52 | watcher.Filter = Path.GetFileName(section.FilePath); 53 | 54 | watcher.EnableRaisingEvents = true; 55 | } 56 | 57 | private void Timer_Elapsed(object sender, ElapsedEventArgs e) 58 | { 59 | var changed = Changed; 60 | if (changed != null) 61 | changed(this, EventArgs.Empty); 62 | } 63 | 64 | private void Watcher_Changed(object sender, FileSystemEventArgs e) 65 | { 66 | if (timer.Enabled) 67 | timer.Stop(); 68 | timer.Start(); 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Server/Configuration/DefaultConfiguration.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Server/Configuration/IPEndPointConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Net.Sockets; 4 | using System.Configuration; 5 | using System.ComponentModel; 6 | using System.Globalization; 7 | using System.Text.RegularExpressions; 8 | 9 | namespace Sip.Server.Configuration 10 | { 11 | class IPEndPointConverter 12 | : ConfigurationConverterBase 13 | { 14 | public override bool CanConvertTo(ITypeDescriptorContext ctx, Type type) 15 | { 16 | return type == typeof(string); 17 | } 18 | 19 | public override bool CanConvertFrom(ITypeDescriptorContext ctx, Type type) 20 | { 21 | return type == typeof(string); 22 | } 23 | 24 | public override object ConvertTo(ITypeDescriptorContext ctx, CultureInfo ci, object value, Type type) 25 | { 26 | if (value == null) 27 | return new ArgumentNullException(@"value"); 28 | 29 | var endpoint = value as IPEndPoint; 30 | 31 | if (endpoint == null) 32 | throw new ArgumentException(@"value"); 33 | 34 | if (endpoint.AddressFamily == AddressFamily.InterNetworkV6) 35 | return @"[" + endpoint.Address.ToString() + @"]:" + endpoint.Port; 36 | 37 | return endpoint.ToString(); 38 | } 39 | 40 | public override object ConvertFrom(ITypeDescriptorContext ctx, CultureInfo ci, object data) 41 | { 42 | if (data == null) 43 | throw new ArgumentOutOfRangeException(@"IP End Point"); 44 | 45 | var regex = new Regex(@"^(((\[(?

[^\]]+)\])|(?
[^:]+)):(?[0-9]+))", 46 | RegexOptions.Singleline); 47 | 48 | var match = regex.Match(data as string); 49 | 50 | if (match.Success == false) 51 | throw new ArgumentOutOfRangeException(@"IP End Point"); 52 | 53 | IPAddress address; 54 | if (IPAddress.TryParse(match.Groups["address"].Value, out address) == false) 55 | throw new ArgumentOutOfRangeException(@"IP Address"); 56 | 57 | int port; 58 | if (int.TryParse(match.Groups["port"].Value, out port) == false) 59 | throw new ArgumentOutOfRangeException(@"Port"); 60 | 61 | if (port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort) 62 | return null; 63 | 64 | return new IPEndPoint(address, port); 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Server/Configuration/PortForwardingConfigurationElement.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Configuration; 4 | using System.ComponentModel; 5 | using SocketServers; 6 | 7 | namespace Sip.Server.Configuration 8 | { 9 | public class PortForwardingConfigurationElement 10 | : ConfigurationElement 11 | { 12 | private const string protocolName = @"protocol"; 13 | private const string localEndpointName = @"localEndpoint"; 14 | private const string externalEndpointName = @"externalEndpoint"; 15 | 16 | [ConfigurationProperty(protocolName, IsRequired = true)] 17 | [TypeConverter(typeof(ProtocolConverter))] 18 | public ServerProtocol Protocol 19 | { 20 | get { return (ServerProtocol)base[protocolName]; } 21 | set { base[protocolName] = value; } 22 | } 23 | 24 | [ConfigurationProperty(localEndpointName, IsRequired = true)] 25 | [TypeConverter(typeof(IPEndPointConverter))] 26 | public IPEndPoint LocalEndpoint 27 | { 28 | get { return (IPEndPoint)base[localEndpointName]; } 29 | set { base[localEndpointName] = value; } 30 | } 31 | 32 | [ConfigurationProperty(externalEndpointName, IsRequired = true)] 33 | [TypeConverter(typeof(IPEndPointConverter))] 34 | public IPEndPoint ExternalEndpoint 35 | { 36 | get { return (IPEndPoint)base[externalEndpointName]; } 37 | set { base[externalEndpointName] = value; } 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Server/Configuration/PortForwardingConfigurationElementCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Configuration; 5 | using System.ComponentModel; 6 | 7 | namespace Sip.Server.Configuration 8 | { 9 | public class PortForwardingConfigurationElementCollection 10 | : ConfigurationElementCollection, IEnumerable 11 | { 12 | protected override ConfigurationElement CreateNewElement() 13 | { 14 | return new PortForwardingConfigurationElement(); 15 | } 16 | 17 | protected override object GetElementKey(ConfigurationElement element) 18 | { 19 | var forwarding = element as PortForwardingConfigurationElement; 20 | return forwarding.Protocol.ToString() + ":" + forwarding.LocalEndpoint.ToString(); 21 | } 22 | 23 | public new IEnumerator GetEnumerator() 24 | { 25 | return new TypedEnumerator(base.GetEnumerator()); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Server/Configuration/ProtocolConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Configuration; 3 | using System.ComponentModel; 4 | using System.Globalization; 5 | using SocketServers; 6 | 7 | namespace Sip.Server.Configuration 8 | { 9 | class ProtocolConverter 10 | : ConfigurationConverterBase 11 | { 12 | public override bool CanConvertTo(ITypeDescriptorContext ctx, Type type) 13 | { 14 | return type == typeof(string); 15 | } 16 | 17 | public override bool CanConvertFrom(ITypeDescriptorContext ctx, Type type) 18 | { 19 | return type == typeof(string); 20 | } 21 | 22 | public override object ConvertTo(ITypeDescriptorContext ctx, CultureInfo ci, object value, Type type) 23 | { 24 | if (value == null) 25 | return new ArgumentNullException(); 26 | 27 | if (value.GetType() != typeof(ServerProtocol)) 28 | throw new ArgumentException(); 29 | 30 | return value.ToString(); 31 | } 32 | 33 | public override object ConvertFrom(ITypeDescriptorContext ctx, CultureInfo ci, object data) 34 | { 35 | if (data == null) 36 | return new ArgumentNullException(@"data"); 37 | 38 | return (data as string).ConvertTo(); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Server/Configuration/TurnServerConfigurationElement.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Configuration; 3 | 4 | namespace Sip.Server.Configuration 5 | { 6 | public class TurnServerConfigurationElement 7 | : ConfigurationElement 8 | { 9 | private const string fqdnName = @"fqdn"; 10 | private const string udpPortName = @"udpPort"; 11 | private const string tcpPortName = @"tcpPort"; 12 | private const string locationName = @"location"; 13 | 14 | [ConfigurationProperty(fqdnName, IsRequired = true)] 15 | public string Fqdn 16 | { 17 | get { return (string)base[fqdnName]; } 18 | set { base[fqdnName] = value; } 19 | } 20 | 21 | [ConfigurationProperty(udpPortName, DefaultValue = 3478)] 22 | [IntegerValidator(MinValue = 0, MaxValue = 65535)] 23 | public int UdpPort 24 | { 25 | get { return (int)base[udpPortName]; } 26 | set { base[udpPortName] = value; } 27 | } 28 | 29 | [ConfigurationProperty(tcpPortName, DefaultValue = 3478)] 30 | [IntegerValidator(MinValue = 0, MaxValue = 65535)] 31 | public int TcpPort 32 | { 33 | get { return (int)base[tcpPortName]; } 34 | set { base[tcpPortName] = value; } 35 | } 36 | 37 | [ConfigurationProperty(locationName, DefaultValue = "Internet")] 38 | [RegexStringValidator("Internet|Intranet")] 39 | public string Location 40 | { 41 | get { return (string)base[locationName]; } 42 | set { base[locationName] = value; } 43 | } 44 | 45 | public bool IsInternet 46 | { 47 | get { return string.Compare(Location, "Internet") == 0; } 48 | set { Location = "Internet"; } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Server/Configuration/TurnServerConfigurationElementCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Configuration; 5 | using System.ComponentModel; 6 | 7 | namespace Sip.Server.Configuration 8 | { 9 | public class TurnServerConfigurationElementCollection 10 | : ConfigurationElementCollection, IEnumerable 11 | { 12 | private const string key1Name = @"key1"; 13 | private const string key2Name = @"key2"; 14 | 15 | protected override ConfigurationElement CreateNewElement() 16 | { 17 | return new TurnServerConfigurationElement(); 18 | } 19 | 20 | protected override object GetElementKey(ConfigurationElement element) 21 | { 22 | var turnServer = element as TurnServerConfigurationElement; 23 | return turnServer.Location + "@" + turnServer.Fqdn; 24 | } 25 | 26 | [ConfigurationProperty(key1Name)] 27 | [TypeConverter(typeof(ByteArrayConverter))] 28 | public byte[] Key1 29 | { 30 | get { return (byte[])base[key1Name]; } 31 | set { base[key1Name] = value; } 32 | } 33 | 34 | [ConfigurationProperty(key2Name)] 35 | [TypeConverter(typeof(ByteArrayConverter))] 36 | public byte[] Key2 37 | { 38 | get { return (byte[])base[key2Name]; } 39 | set { base[key2Name] = value; } 40 | } 41 | 42 | public void Clear() 43 | { 44 | BaseClear(); 45 | } 46 | 47 | public void Add(string fqdn, int tcpPort, int udpPort, bool isInternet) 48 | { 49 | BaseAdd(new TurnServerConfigurationElement() 50 | { 51 | Fqdn = fqdn, 52 | TcpPort = tcpPort, 53 | UdpPort = udpPort, 54 | IsInternet = isInternet, 55 | }); 56 | } 57 | 58 | public new IEnumerator GetEnumerator() 59 | { 60 | return new TypedEnumerator(base.GetEnumerator()); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Server/Configuration/TypedEnumerator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | 5 | namespace Sip.Server 6 | { 7 | class TypedEnumerator 8 | : IEnumerator 9 | { 10 | IEnumerator enumerator; 11 | 12 | public TypedEnumerator(IEnumerator enumerator1) 13 | { 14 | enumerator = enumerator1; 15 | } 16 | 17 | public void Dispose() 18 | { 19 | } 20 | 21 | public bool MoveNext() 22 | { 23 | return enumerator.MoveNext(); 24 | } 25 | 26 | public void Reset() 27 | { 28 | enumerator.Reset(); 29 | } 30 | 31 | Object IEnumerator.Current 32 | { 33 | get { return enumerator.Current; } 34 | } 35 | 36 | T IEnumerator.Current 37 | { 38 | get { return (T)enumerator.Current; } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Server/Configuration/VoipProviderConfigurationElementCollection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Configuration; 5 | 6 | namespace Sip.Server.Configuration 7 | { 8 | class VoipProviderConfigurationElementCollection 9 | : ConfigurationElementCollection, IEnumerable 10 | { 11 | protected override ConfigurationElement CreateNewElement() 12 | { 13 | return new VoipProviderConfigurationElement(); 14 | } 15 | 16 | protected override object GetElementKey(ConfigurationElement element) 17 | { 18 | var voipProvider = element as VoipProviderConfigurationElement; 19 | return voipProvider.Username + "@" + voipProvider.ServerHostname; 20 | } 21 | 22 | public void Clear() 23 | { 24 | BaseClear(); 25 | } 26 | 27 | public void Add(VoipProviderConfigurationElement item) 28 | { 29 | BaseAdd(item); 30 | } 31 | 32 | public void Remove(string username, string hostname) 33 | { 34 | BaseRemove(username + "@" + hostname); 35 | } 36 | 37 | public new IEnumerator GetEnumerator() 38 | { 39 | return new TypedEnumerator(base.GetEnumerator()); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Server/EnhancedPresence/EnhancedPresenceException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace EnhancedPresence 7 | { 8 | public class EnhancedPresenceException : 9 | Exception 10 | { 11 | public EnhancedPresenceException(string message, Exception innerException) 12 | : base(message, innerException) 13 | { 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Server/EnhancedPresence/ExpiresList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace EnhancedPresence 5 | { 6 | public class ExpiresList : 7 | ISubscriptionResourceEvents 8 | { 9 | private List resources; 10 | 11 | public ExpiresList() 12 | { 13 | this.resources = new List(); 14 | } 15 | 16 | public void AddResource(SubscriptionResource resource) 17 | { 18 | int tickCount = Environment.TickCount; 19 | 20 | for (int i = 0; i < resources.Count; i++) 21 | { 22 | if (resources[i].GetExpires(tickCount) > resource.GetExpires(tickCount)) 23 | { 24 | resources.Insert(i, resource); 25 | break; 26 | } 27 | } 28 | } 29 | 30 | public void RemoveResource(SubscriptionResource resource) 31 | { 32 | resources.Remove(resource); 33 | } 34 | 35 | public void UpdateResource(SubscriptionResource resource) 36 | { 37 | RemoveResource(resource); 38 | AddResource(resource); 39 | } 40 | 41 | public SubscriptionResource GetExpired() 42 | { 43 | SubscriptionResource resource = null; 44 | 45 | if (resources.Count > 0) 46 | { 47 | if (resources[0].Expires == 0) 48 | { 49 | resource = resources[0]; 50 | resources.RemoveAt(0); 51 | } 52 | } 53 | 54 | return resource; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Server/EnhancedPresence/Schemas/Categories.xsd: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Server/EnhancedPresence/Schemas/RichPresenceCommon.xsd: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Server/EnhancedPresence/Schemas/categoryList.xsd: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Server/EnhancedPresence/XmlContent/BatchSubscribe.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Xml.Schema; 4 | using System.Xml; 5 | using System.IO; 6 | 7 | namespace EnhancedPresence 8 | { 9 | public enum BatchSubscribeAction 10 | { 11 | Subscribe, 12 | Unsubscribe 13 | } 14 | 15 | public class BatchSubscribe 16 | { 17 | public BatchSubscribeAction Action { private set; get; } 18 | public List Resources { private set; get; } 19 | public List Сategories { private set; get; } 20 | 21 | protected BatchSubscribe() 22 | { 23 | Resources = new List(); 24 | Сategories = new List(); 25 | } 26 | 27 | public static BatchSubscribe Parse(XmlReader reader) 28 | { 29 | BatchSubscribe request = new BatchSubscribe(); 30 | 31 | while (reader.Read()) 32 | { 33 | if (reader.NodeType == XmlNodeType.Element) 34 | { 35 | if (reader.Name == "action") 36 | { 37 | string name = reader.GetAttribute("name"); 38 | if (name == "subscribe") 39 | request.Action = BatchSubscribeAction.Subscribe; 40 | else if (name == "unsubscribe") 41 | request.Action = BatchSubscribeAction.Unsubscribe; 42 | } 43 | 44 | if (reader.Name == "resource") 45 | request.Resources.Add(reader.GetAttribute("uri")); 46 | 47 | if (reader.Name == "category") 48 | request.Сategories.Add(reader.GetAttribute("name")); 49 | } 50 | } 51 | 52 | return request; 53 | } 54 | 55 | public static string InContentType 56 | { 57 | get { return @"application"; } 58 | } 59 | 60 | public static string InContentSubtype 61 | { 62 | get { return @"msrtc-adrl-categorylist+xml"; } 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Server/EnhancedPresence/XmlContent/ICategoryValue.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml; 3 | 4 | namespace EnhancedPresence 5 | { 6 | public interface ICategoryValue 7 | { 8 | void Generate(XmlWriter writer); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Server/EnhancedPresence/XmlContent/RoamingData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml; 3 | using System.Text; 4 | 5 | namespace EnhancedPresence 6 | { 7 | public class RoamingData : 8 | OutContentBase 9 | { 10 | private Categories categories; 11 | 12 | protected RoamingData() 13 | { 14 | } 15 | 16 | public static RoamingData Create(Categories categories) 17 | { 18 | RoamingData roamingData = new RoamingData(); 19 | 20 | roamingData.categories = categories; 21 | 22 | return roamingData; 23 | } 24 | 25 | public override void Generate(XmlWriter writer) 26 | { 27 | writer.WriteStartElement(@"roamingData", @"http://schemas.microsoft.com/2006/09/sip/roaming-self"); 28 | 29 | this.categories.Generate(writer); 30 | 31 | writer.WriteEndElement(); 32 | 33 | writer.Flush(); 34 | } 35 | 36 | public override string OutContentType 37 | { 38 | get { return @"application"; } 39 | } 40 | 41 | public override string OutContentSubtype 42 | { 43 | get { return @"vnd-microsoft-roaming-self+xml"; } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Server/EnhancedPresence/XmlContent/Schemas.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Xml.Schema; 4 | using System.Xml; 5 | using System.IO; 6 | 7 | namespace EnhancedPresence 8 | { 9 | public enum EnhancedPresenceSchema 10 | { 11 | BatchSubscribe = 0, 12 | Categories = 1, 13 | NoSchema 14 | } 15 | 16 | public class Schemas 17 | { 18 | public XmlSchemaSet[] schemas; 19 | 20 | public Schemas() 21 | { 22 | this.schemas = new XmlSchemaSet[2]; 23 | 24 | { 25 | XmlSchemaSet schemaSet = new XmlSchemaSet(); 26 | schemaSet.Add(LoadSchema("BatchSubscribeRequest.xsd")); 27 | schemaSet.Add(LoadSchema("categoryList.xsd")); 28 | this[EnhancedPresenceSchema.BatchSubscribe] = schemaSet; 29 | } 30 | 31 | { 32 | XmlSchemaSet schemaSet = new XmlSchemaSet(); 33 | schemaSet.Add(LoadSchema("Categories.xsd")); 34 | schemaSet.Add(LoadSchema("RichPresenceCommon.xsd")); 35 | this[EnhancedPresenceSchema.Categories] = schemaSet; 36 | } 37 | } 38 | 39 | public XmlSchemaSet this[EnhancedPresenceSchema id] 40 | { 41 | get 42 | { 43 | return this.schemas[(int)id]; 44 | } 45 | private set 46 | { 47 | this.schemas[(int)id] = value; 48 | } 49 | } 50 | 51 | private XmlSchema LoadSchema(string location) 52 | { 53 | string[] resources = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceNames(); 54 | 55 | foreach (string resource in resources) 56 | { 57 | if (resource.EndsWith(location)) 58 | using (Stream stream = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(@"Sip.Server.EnhancedPresence.Schemas." + location)) 59 | return XmlSchema.Read(stream, null); 60 | } 61 | 62 | throw new Exception("Schema " + location + " can not be loaded."); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Server/EnhancedPresence/XmlContent/StateCategory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Xml; 4 | using System.IO; 5 | 6 | namespace EnhancedPresence 7 | { 8 | public class StateCategory : 9 | ICategoryValue 10 | { 11 | public int Availability { /*private */set; get; } 12 | 13 | public StateCategory() 14 | { 15 | } 16 | 17 | public static StateCategory Create(int availability) 18 | { 19 | StateCategory state = new StateCategory(); 20 | 21 | state.Availability = availability; 22 | 23 | return state; 24 | } 25 | 26 | public static StateCategory Parse(XmlReader reader) 27 | { 28 | StateCategory state = new StateCategory(); 29 | 30 | while (reader.Read()) 31 | { 32 | if (reader.Name == "availability") 33 | { 34 | while (reader.Read() && reader.NodeType != XmlNodeType.Text) ; 35 | state.Availability = reader.ReadContentAsInt(); 36 | } 37 | 38 | if (reader.Name == "state" && reader.NodeType == XmlNodeType.EndElement) 39 | break; 40 | } 41 | 42 | return state; 43 | } 44 | 45 | public void Generate(XmlWriter writer) 46 | { 47 | writer.WriteStartElement(@"state", @"http://schemas.microsoft.com/2006/09/sip/state"); 48 | writer.WriteAttributeString(@"xsi", @"type", @"http://www.w3.org/2001/XMLSchema-instance", @"aggregateState"); 49 | 50 | writer.WriteStartElement(@"availability"); 51 | 52 | writer.WriteValue(this.Availability); 53 | 54 | writer.WriteEndElement(); 55 | writer.WriteEndElement(); 56 | 57 | writer.Flush(); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Server/Http/BaseHttpConnection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Http.Message; 3 | using SocketServers; 4 | 5 | namespace Server.Http 6 | { 7 | public abstract class BaseHttpConnection 8 | : HeaderContentConnection 9 | { 10 | public abstract HttpMessageReader HttpReader { get; } 11 | } 12 | } -------------------------------------------------------------------------------- /Server/LocationService/ILocationService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Sip.Message; 4 | using Base.Message; 5 | 6 | namespace Sip.Server 7 | { 8 | interface ILocationService 9 | { 10 | //IEnumerable GetEnumerableBindings(SipMessageReader reader); 11 | IEnumerable GetEnumerableBindings(ByteArrayPart user, ByteArrayPart domain); 12 | IEnumerable GetEnumerableBindings(ByteArrayPart aor); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /Server/Mras/MrasException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Mras.XmlContent; 3 | 4 | namespace Mras 5 | { 6 | public class MrasException 7 | : Exception 8 | { 9 | public ReasonPhrase ReasonPhrase { get; private set; } 10 | 11 | public MrasException() 12 | : base(Common.ToString(ReasonPhrase.RequestMalformed)) 13 | { 14 | ReasonPhrase = ReasonPhrase.RequestMalformed; 15 | } 16 | 17 | public MrasException(ReasonPhrase reasonPhrase) 18 | : base(Common.ToString(reasonPhrase)) 19 | { 20 | ReasonPhrase = reasonPhrase; 21 | } 22 | 23 | public MrasException(string message) 24 | : base(message) 25 | { 26 | ReasonPhrase = ReasonPhrase.RequestMalformed; 27 | } 28 | 29 | public MrasException(ReasonPhrase reasonPhrase, Exception innerException) 30 | : base(Common.ToString(reasonPhrase), innerException) 31 | { 32 | ReasonPhrase = reasonPhrase; 33 | } 34 | 35 | public MrasException(Exception innerException) 36 | : base(Common.ToString(ReasonPhrase.RequestMalformed), innerException) 37 | { 38 | ReasonPhrase = ReasonPhrase.RequestMalformed; 39 | } 40 | 41 | public MrasException(string message, Exception innerException) 42 | : base(message, innerException) 43 | { 44 | ReasonPhrase = ReasonPhrase.RequestMalformed; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Server/Mras/Password.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Security.Cryptography; 3 | 4 | namespace Mras 5 | { 6 | public class Password 7 | { 8 | public static byte[] GetBytes(byte[] key2, byte[] username) 9 | { 10 | using (HMACSHA1 sha1 = new HMACSHA1(key2)) 11 | { 12 | sha1.ComputeHash(username); 13 | return sha1.Hash; 14 | } 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Server/Mras/TokenBlob.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Mras 4 | { 5 | public class TokenBlob1 6 | { 7 | public TokenBlob1() 8 | { 9 | MajorVersion = 1; 10 | MinorVersion = 0; 11 | Size = 0x0020; 12 | ClientID = new byte[20]; 13 | } 14 | 15 | public byte MajorVersion; 16 | public byte MinorVersion; 17 | public UInt16 Size; 18 | public UInt32 ExpiryTimeLow; 19 | public UInt32 ExpiryTimeHigh; 20 | public byte[] ClientID; 21 | 22 | public virtual byte[] GetBytes(int extraLength) 23 | { 24 | byte[] bytes = new byte[Size + extraLength]; 25 | int offset = 0; 26 | 27 | bytes[offset++] = MajorVersion; 28 | bytes[offset++] = MinorVersion; 29 | AddBytes(bytes, ref offset, Bigendian.GetBigendianBytes(Size)); 30 | AddBytes(bytes, ref offset, Bigendian.GetBigendianBytes(ExpiryTimeLow)); 31 | AddBytes(bytes, ref offset, Bigendian.GetBigendianBytes(ExpiryTimeHigh)); 32 | AddBytes(bytes, ref offset, ClientID); 33 | 34 | return bytes; 35 | } 36 | 37 | protected static void AddBytes(byte[] dst, ref int offset, byte[] src) 38 | { 39 | Array.Copy(src, 0, dst, offset, src.Length); 40 | offset += src.Length; 41 | } 42 | } 43 | 44 | public class TokenBlob2 45 | : TokenBlob1 46 | { 47 | public UInt32 Flags; 48 | 49 | public TokenBlob2() 50 | : base() 51 | { 52 | MajorVersion = 2; 53 | MinorVersion = 0; 54 | Size = 0x0024; 55 | } 56 | 57 | public override byte[] GetBytes(int extraLength) 58 | { 59 | byte[] bytes = base.GetBytes(extraLength); 60 | int offset = Size - sizeof(UInt32); 61 | 62 | AddBytes(bytes, ref offset, Bigendian.GetBigendianBytes(Flags)); 63 | 64 | return bytes; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Server/Mras/TurnServerInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Mras 4 | { 5 | public class TurnServerInfo 6 | { 7 | public string Fqdn { get; set; } 8 | public ushort UdpPort { get; set; } 9 | public ushort TcpPort { get; set; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Server/Mras/Username.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Security.Cryptography; 3 | 4 | namespace Mras 5 | { 6 | public class Username 7 | { 8 | public static byte[] GetBytes(byte[] key1, TokenBlob1 blob1) 9 | { 10 | using (HMACSHA1 sha1 = new HMACSHA1(key1)) 11 | { 12 | byte[] username = blob1.GetBytes(sha1.HashSize / 8); 13 | 14 | sha1.ComputeHash(username, 0, blob1.Size); 15 | 16 | Array.Copy(sha1.Hash, 0, username, blob1.Size, sha1.HashSize / 8); 17 | 18 | return username; 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Server/Mras/XmlContent/CredentialsRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml.Schema; 3 | using System.Xml; 4 | 5 | namespace Mras.XmlContent 6 | { 7 | #region Schemas 8 | // 9 | // 10 | // 11 | // 12 | // 13 | // 14 | // 15 | // 16 | // 17 | 18 | // 19 | // 20 | // 21 | // 22 | // 23 | // 24 | // 25 | #endregion 26 | 27 | public class CredentialsRequest 28 | { 29 | public string Identity { get; private set; } 30 | public Location? Location { get; private set; } 31 | public uint Duration { get; set; } 32 | public string CredentialsRequestID { get; private set; } 33 | 34 | public static bool CanParse(XmlReader reader) 35 | { 36 | return reader.IsStartElement(@"credentialsRequest"); 37 | } 38 | 39 | public static CredentialsRequest Parse(XmlReader reader) 40 | { 41 | CredentialsRequest credentialsRequest = new CredentialsRequest(); 42 | 43 | reader.MoveToContent(); 44 | credentialsRequest.CredentialsRequestID = reader.GetAttribute(@"credentialsRequestID"); 45 | 46 | reader.Read(); 47 | reader.MoveToContent(); 48 | credentialsRequest.Identity = 49 | reader.ReadElementContentAsString(@"identity", @"http://schemas.microsoft.com/2006/09/sip/mrasp"); 50 | 51 | if (reader.IsStartElement(@"location")) 52 | credentialsRequest.Location = Common.ParseLocation(reader.ReadElementContentAsString()); 53 | 54 | if (reader.IsStartElement(@"duration")) 55 | credentialsRequest.Duration = (uint)reader.ReadElementContentAsInt(); 56 | 57 | reader.MoveToContent(); 58 | reader.ReadEndElement(); 59 | 60 | return credentialsRequest; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Server/Mras/XmlContent/MediaRelay.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Xml.Schema; 3 | using System.Xml; 4 | 5 | namespace Mras.XmlContent 6 | { 7 | #region Schemas 8 | // 9 | // 10 | // 11 | // 12 | // 13 | // 14 | // 15 | // 16 | // 17 | // 18 | // 19 | // 20 | #endregion 21 | 22 | public class MediaRelay 23 | { 24 | public Location Location { get; set; } 25 | public string HostName { get; set; } 26 | public string DirectIpAddress { get; set; } 27 | public ushort UdpPort { get; set; } 28 | public ushort TcpPort { get; set; } 29 | 30 | public void Generate(XmlWriter writer) 31 | { 32 | writer.WriteStartElement(@"mediaRelay"); 33 | 34 | writer.WriteElementString(@"location", Common.ToString(Location)); 35 | 36 | if (string.IsNullOrEmpty(HostName) == false) 37 | writer.WriteElementString(@"hostName", HostName); 38 | else 39 | writer.WriteElementString(@"directIPAddress", DirectIpAddress); 40 | 41 | writer.WriteElementString(@"udpPort", UdpPort.ToString()); 42 | writer.WriteElementString(@"tcpPort", TcpPort.ToString()); 43 | 44 | writer.WriteEndElement(); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Server/Mras/XmlContent/Response.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Xml.Schema; 4 | using System.Xml; 5 | 6 | namespace Mras.XmlContent 7 | { 8 | public class Response 9 | : EnhancedPresence.OutContentBase 10 | { 11 | public Request Request { get; set; } 12 | public Version ServerVersion { get; set; } 13 | public ReasonPhrase ReasonPhrase { get; set; } 14 | public IEnumerable CredentialsResponses { get; set; } 15 | 16 | public override void Generate(XmlWriter writer) 17 | { 18 | writer.WriteRaw(""); 19 | writer.WriteStartElement(@"response", @"http://schemas.microsoft.com/2006/09/sip/mrasp"); 20 | 21 | if (Request != null) 22 | { 23 | writer.WriteAttributeString(@"requestID", Request.RequestId); 24 | writer.WriteAttributeString(@"version", Request.Version); 25 | } 26 | 27 | writer.WriteAttributeString(@"serverVersion", ServerVersion); 28 | 29 | if (Request != null) 30 | { 31 | writer.WriteAttributeString(@"to", Request.To); 32 | writer.WriteAttributeString(@"from", Request.From); 33 | } 34 | 35 | writer.WriteAttributeString(@"reasonPhrase", Common.ToString(ReasonPhrase)); 36 | 37 | if (CredentialsResponses != null) 38 | foreach (var credentialsResponse in CredentialsResponses) 39 | credentialsResponse.Generate(writer); 40 | 41 | writer.WriteEndElement(); 42 | } 43 | 44 | public override string OutContentType 45 | { 46 | get { return @"application"; } 47 | } 48 | 49 | public override string OutContentSubtype 50 | { 51 | get { return @"msrtc-media-relay-auth+xml"; } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Server/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | using System.Resources; 4 | 5 | [assembly: AssemblyTitle("OfficeSIP Server")] 6 | [assembly: AssemblyDescription("OfficeSIP Server Service")] 7 | [assembly: AssemblyCompany("OfficeSIP Communications")] 8 | [assembly: AssemblyProduct("OfficeSIP Server")] 9 | [assembly: AssemblyCopyright("Copyright © OfficeSIP Communications 2006-2012")] 10 | [assembly: ComVisibleAttribute(false)] 11 | [assembly: NeutralResourcesLanguageAttribute("")] 12 | 13 | [assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Test")] -------------------------------------------------------------------------------- /Server/Properties/AssemblyInfoVersion.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | 3 | [assembly: AssemblyVersion( "3.5.*" )] 4 | -------------------------------------------------------------------------------- /Server/Properties/OfficeSIP Server.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Server/Properties/OfficeSIP Server.ico -------------------------------------------------------------------------------- /Server/Restapi/Bnf/api.bat: -------------------------------------------------------------------------------- 1 | BnfToDfa.exe api.bnf api.mrk API 2 | DfaToCSharp.exe api.xml Server.Restapi RestapiUriParser 3 | 4 | move Server.Restapi.dfa ..\ 5 | move RestapiUriParser.cs ..\ -------------------------------------------------------------------------------- /Server/Restapi/Bnf/api.bnf: -------------------------------------------------------------------------------- 1 |  2 | API = "/api" (ACCOUNTS / OPTIONS / VERSION / ROLE) [ "?" PARAM *( "&" PARAM ) ] 3 | 4 | VERSION = "/version" 5 | 6 | OPTIONS = "/options" 7 | 8 | ROLE = "/role" 9 | 10 | ACCOUNTS = "/accounts" [ "/" DOMAIN-NAME [ USERZ ]] 11 | DOMAIN-NAME = 1*64 (LOALPHA / DIGIT / safe) 12 | 13 | USERZ = "/userz" [ "/" USERS-ID [ "/" USERNAME ] ] 14 | USERS-ID = 1*4 LOALPHA 15 | USERNAME = 1*32 (LOALPHA / DIGIT / safe) 16 | 17 | PARAM = METHOD-PARAM / TIMESTAMP-PARAM / SIGNATURE-PARAM / AUTHNAME-PARAM / STARTINDEX-PARAM / COUNT-PARAM 18 | METHOD-PARAM = "method=" ( "PUT" / "DELETE" ) 19 | TIMESTAMP-PARAM = "time=" 1*16 DIGIT 20 | AUTHNAME-PARAM = "user=" USERNAME 21 | SIGNATURE-PARAM = "sig=" 32 HEX 22 | STARTINDEX-PARAM = "start=" 1*8 DIGIT 23 | COUNT-PARAM = "count=" 1*8 DIGIT 24 | 25 | DIGIT = %x30-39 26 | LOALPHA = %x61-7A 27 | UPALPHA = %x41-5A 28 | ALPHA = UPALPHA / LOALPHA 29 | HEX = "A" / "B" / "C" / "D" / "E" / "F" 30 | / "a" / "b" / "c" / "d" / "e" / "f" / DIGIT 31 | escape = "%" HEX HEX 32 | safe = "-" / "_" / "." 33 | -------------------------------------------------------------------------------- /Server/Restapi/Bnf/api.mrk: -------------------------------------------------------------------------------- 1 |  2 | API.OPTIONS./options -> Const = BaseAction, Options; 3 | 4 | API.ACCOUNTS./accounts -> Const = BaseAction, Accounts; 5 | API.ACCOUNTS.DOMAIN-NAME -> Range = DomainName; 6 | 7 | API.VERSION./version -> Const = BaseAction, Version; 8 | 9 | API.ROLE./role -> Const = BaseAction, Role; 10 | 11 | API.ACCOUNTS.USERZ./userz -> Const = AccountAction, Userz; 12 | API.ACCOUNTS.USERZ.USERS-ID -> Range = UsersId; 13 | API.ACCOUNTS.USERZ.USERNAME -> Range = Username; 14 | 15 | API.PARAM.METHOD-PARAM.PUT -> Const = Method; 16 | API.PARAM.METHOD-PARAM.DELETE -> Const = Method; 17 | API.PARAM.TIMESTAMP-PARAM.DIGIT -> Decimal = Timestamp, long; 18 | API.PARAM.SIGNATURE-PARAM.HEX -> Range = Signature; 19 | API.PARAM.AUTHNAME-PARAM.USERNAME -> Range = Authname; 20 | API.PARAM.STARTINDEX-PARAM.DIGIT -> Decimal = StartIndex; 21 | API.PARAM.COUNT-PARAM.DIGIT -> Decimal = Count; 22 | 23 | 24 | //API.ACCOUNTS.AD-USERS./ad-users -> Const = AccountAction, AdUsers; 25 | //API.ACCOUNTS.CVS-USERS./csv-users -> Const = AccountAction, CsvUsers; 26 | 27 | 28 | //API.ACCOUNTS./accounts -> Const = BaseAction, Accounts; 29 | //API.ACCOUNTS.HEX -> Hex = AccountId; 30 | 31 | //API.VERSION./version -> Const = BaseAction, Version; 32 | 33 | //API.ROLE./role -> Const = BaseAction, Role; 34 | 35 | //API.ADMINS./admins -> Const = BaseAction, Admins; 36 | //API.ADMINS.USERNAME -> Range = Admin; 37 | 38 | //API.ADMINS./accounts -> Const = AdminAction, Accounts; 39 | 40 | //API.ACCOUNTS.OPTIONS./options -> Const = AccountAction, Options; 41 | //API.ACCOUNTS.AD-USERS./ad-users -> Const = AccountAction, AdUsers; 42 | //API.ACCOUNTS.CVS-USERS./csv-users -> Const = AccountAction, CsvUsers; 43 | 44 | //API.ACCOUNTS.CVS-USERS.USERNAME -> Range = Username; 45 | //API.ACCOUNTS.AD-USERS.USERNAME -> Range = Username; 46 | 47 | //API.PARAM.METHOD-PARAM.PUT -> Const = Method; 48 | //API.PARAM.METHOD-PARAM.DELETE -> Const = Method; 49 | //API.PARAM.TIMESTAMP-PARAM.DIGIT -> Decimal = Timestamp, long; 50 | //API.PARAM.SIGNATURE-PARAM.HEX -> Range = Signature; 51 | //API.PARAM.AUTHNAME-PARAM.USERNAME -> Range = Authname; 52 | //API.PARAM.STARTINDEX-PARAM.DIGIT -> Decimal = StartIndex; 53 | //API.PARAM.COUNT-PARAM.DIGIT -> Decimal = Count; 54 | -------------------------------------------------------------------------------- /Server/Restapi/JsonContractResolver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Newtonsoft.Json; 4 | using Newtonsoft.Json.Serialization; 5 | using Sip.Server.Users; 6 | using Sip.Server.Accounts; 7 | 8 | namespace Server.Restapi 9 | { 10 | public class JsonContractResolver : CamelCasePropertyNamesContractResolver 11 | { 12 | protected override IList CreateProperties(Type type, MemberSerialization memberSerialization) 13 | { 14 | var properties = base.CreateProperties(type, memberSerialization); 15 | 16 | //if (type == typeof(Account) || type.BaseType == typeof(BaseUser)) 17 | { 18 | for (int i = properties.Count - 1; i >= 0; i--) 19 | { 20 | if (properties[i].PropertyName == "password") 21 | properties.RemoveAt(i); 22 | } 23 | } 24 | 25 | return properties; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Server/Restapi/Server.Restapi.dfa: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Server/Restapi/Server.Restapi.dfa -------------------------------------------------------------------------------- /Server/Rtp/DtmfEventMessage.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Rtp.Payload 5 | { 6 | class DtmfEventMessage 7 | { 8 | // 0 1 2 3 9 | // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 10 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 11 | // | event |E|R| volume | duration | 12 | // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 13 | 14 | public const int Length = 4; 15 | 16 | public byte Event { get; set; } 17 | public bool End { get; set; } 18 | public int Volume { get; set; } 19 | public int Duration { get; set; } 20 | 21 | public static DtmfEventMessage[] Parse(byte[] bytes, int startIndex, int length) 22 | { 23 | if ((length - startIndex) % Length != 0) 24 | throw new ParseException(@"DtmfEventMessage: Invalid message length"); 25 | int count = (length - startIndex) / Length; 26 | 27 | var messages = new DtmfEventMessage[count]; 28 | 29 | for (int i = 0; i < count; i++) 30 | { 31 | messages[i] = new DtmfEventMessage(); 32 | messages[i].Parse2(bytes, startIndex, length); 33 | 34 | startIndex += Length; 35 | } 36 | 37 | return messages; 38 | } 39 | 40 | protected void Parse2(byte[] bytes, int startIndex, int length) 41 | { 42 | Event = bytes[startIndex++]; 43 | 44 | End = (bytes[startIndex] & 0x80) != 0; 45 | Volume = bytes[startIndex] & 0x3f; 46 | startIndex++; 47 | 48 | Duration = bytes.BigendianToUInt16(ref startIndex); 49 | } 50 | 51 | public void GetBytes(byte[] bytes, int startIndex) 52 | { 53 | throw new NotImplementedException(); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Server/Rtp/JitterBuffer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Rtp 5 | { 6 | class JitterBuffer 7 | { 8 | private List messages; 9 | private int dequeuedSequenceNumber; 10 | private CalculateNtpTimestampDelegate calculateNtpTimestampDelegate; 11 | 12 | public delegate UInt64 CalculateNtpTimestampDelegate(RtpMessage message, int rate); 13 | 14 | public JitterBuffer(CalculateNtpTimestampDelegate calculateNtpTimestampDelegate1) 15 | { 16 | messages = new List(); 17 | dequeuedSequenceNumber = -1; 18 | calculateNtpTimestampDelegate = calculateNtpTimestampDelegate1; 19 | } 20 | 21 | public int Count 22 | { 23 | get 24 | { 25 | return messages.Count; 26 | } 27 | } 28 | 29 | public int Rate 30 | { 31 | get; 32 | set; 33 | } 34 | 35 | public void Insert(RtpMessage message) 36 | { 37 | if (message.SequenceNumber > dequeuedSequenceNumber) 38 | { 39 | int index = messages.FindIndex( 40 | (oldMessage) => { return message.SequenceNumber <= oldMessage.SequenceNumber; }); 41 | 42 | if (index < 0) 43 | { 44 | messages.Add(message); 45 | } 46 | else 47 | { 48 | if (messages[index].SequenceNumber != message.SequenceNumber) 49 | messages.Insert(index, message); 50 | } 51 | } 52 | } 53 | 54 | public RtpMessage DequeueAvailable() 55 | { 56 | return DequeueAvailable(UInt64.MaxValue); 57 | } 58 | 59 | public bool DequeueAvailable(UInt64 maxNtpTimestamp, out RtpMessage message) 60 | { 61 | message = DequeueAvailable(maxNtpTimestamp); 62 | 63 | return message != null; 64 | } 65 | 66 | public RtpMessage DequeueAvailable(UInt64 maxNtpTimestamp) 67 | { 68 | if (messages.Count > 0) 69 | { 70 | var message = messages[0]; 71 | 72 | if (calculateNtpTimestampDelegate != null) 73 | message.NtpTimestamp = calculateNtpTimestampDelegate(message, Rate); 74 | 75 | if (message.NtpTimestamp <= maxNtpTimestamp) 76 | { 77 | messages.RemoveAt(0); 78 | dequeuedSequenceNumber = message.SequenceNumber; 79 | 80 | return message; 81 | } 82 | } 83 | 84 | return null; 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Server/Rtp/ParseException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Rtp 4 | { 5 | class ParseException 6 | : Exception 7 | { 8 | public ParseException(string message) 9 | : base(message) 10 | { 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Server/Rtp/RtpReceiver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.NtpTimestamp; 4 | 5 | namespace Rtp 6 | { 7 | class RtpReceiver 8 | { 9 | private List ssrcs = new List(); 10 | private int[] payloadTypes; 11 | private int[] payloadRates; 12 | 13 | public RtpReceiver(int[] payloadTypes1, int[] payloadRates1) 14 | { 15 | ssrcs = new List(); 16 | payloadTypes = payloadTypes1; 17 | payloadRates = payloadRates1; 18 | } 19 | 20 | public IEnumerable Ssrcs 21 | { 22 | get 23 | { 24 | foreach (var ssrc in ssrcs) 25 | yield return ssrc; 26 | } 27 | } 28 | 29 | public Ssrc FindSsrc(UInt32 ssrcId) 30 | { 31 | foreach (var ssrc in ssrcs) 32 | if (ssrc.SsrcId == ssrcId) 33 | return ssrc; 34 | 35 | return null; 36 | } 37 | 38 | protected Ssrc AddSsrc(UInt32 ssrcId, UInt64 ntpTimestamp, UInt32 rtpTimestamp) 39 | { 40 | var ssrc = new Ssrc(payloadTypes, payloadRates) 41 | { 42 | SsrcId = ssrcId, 43 | }; 44 | ssrc.SetBaseTimestamp(ntpTimestamp, rtpTimestamp); 45 | 46 | ssrcs.Add(ssrc); 47 | 48 | return ssrc; 49 | } 50 | 51 | public void InsertMessage(RtpMessage message) 52 | { 53 | var ssrc = FindSsrc(message.Ssrc); 54 | if (ssrc == null) 55 | ssrc = AddSsrc(message.Ssrc, 0x000fffffffffffff, message.Timestamp); 56 | 57 | ssrc.InsertMessage(message); 58 | } 59 | 60 | public void ProcessMessages(IEnumerable messages) 61 | { 62 | foreach (var message in messages) 63 | { 64 | if (message.MessageType == RtcpMessageType.SenderReport) 65 | { 66 | var ssrc = FindSsrc(message.SenderReport.Ssrc); 67 | 68 | if (ssrc == null) 69 | ssrc = AddSsrc(message.SenderReport.Ssrc, message.SenderReport.NtpTimestamp, message.SenderReport.RtpTimestamp); 70 | else 71 | ssrc.SetBaseTimestamp(message.SenderReport.NtpTimestamp, message.SenderReport.RtpTimestamp); 72 | } 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Server/Rtp/Ssrc.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.NtpTimestamp; 4 | 5 | namespace Rtp 6 | { 7 | class Ssrc 8 | { 9 | private UInt64 baseNtpTimestamp; 10 | private UInt32 baseRtpTimestamp; 11 | private Int32 baseTickCount; 12 | 13 | public Ssrc(int[] payloadTypes, int[] payloadRates) 14 | { 15 | JitterBuffers = new JitterBuffer[128]; 16 | 17 | for (int i = 0; i < payloadTypes.Length; i++) 18 | JitterBuffers[payloadTypes[i]] = new JitterBuffer(GetNtpTimestamp) 19 | { 20 | Rate = payloadRates[i], 21 | }; 22 | } 23 | 24 | public UInt32 SsrcId 25 | { 26 | get; 27 | set; 28 | } 29 | 30 | public JitterBuffer[] JitterBuffers 31 | { 32 | get; 33 | private set; 34 | } 35 | 36 | public void SetBaseTimestamp(UInt64 ntp, UInt32 rtp) 37 | { 38 | baseNtpTimestamp = ntp; 39 | baseRtpTimestamp = rtp; 40 | baseTickCount = Environment.TickCount; 41 | } 42 | 43 | public UInt64 GetCurrentNtpTimestamp(int millisecondsOffset) 44 | { 45 | int milliseconds = Environment.TickCount - baseTickCount + millisecondsOffset; 46 | 47 | return (milliseconds > 0) ? 48 | baseNtpTimestamp + milliseconds.MillisecondsToNtpTimestamp() : 49 | baseNtpTimestamp - (-milliseconds).MillisecondsToNtpTimestamp(); 50 | } 51 | 52 | public UInt64 GetNtpTimestamp(RtpMessage message) 53 | { 54 | return GetNtpTimestamp(message, JitterBuffers[message.PayloadType].Rate); 55 | } 56 | 57 | public UInt64 GetNtpTimestamp(RtpMessage message, int rate) 58 | { 59 | if (rate != 0) 60 | { 61 | UInt32 delta1 = message.Timestamp - baseRtpTimestamp; 62 | UInt32 delta2 = baseRtpTimestamp - message.Timestamp; 63 | 64 | if (delta1 <= delta2) 65 | return baseNtpTimestamp + 66 | ((UInt64)delta1 << 32) / (UInt64)rate; 67 | else 68 | return baseNtpTimestamp - 69 | ((UInt64)delta2 << 32) / (UInt64)rate; 70 | } 71 | 72 | return 0; 73 | } 74 | 75 | public void InsertMessage(RtpMessage message) 76 | { 77 | if (JitterBuffers[message.PayloadType] != null) 78 | JitterBuffers[message.PayloadType].Insert(message); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /Server/Sdp/Helpers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Sip.Sdp 4 | { 5 | class Helpers 6 | { 7 | public static ArraySegment CutCandidates(ArraySegment content) 8 | { 9 | var str = System.Text.Encoding.UTF8.GetString(content.Array, content.Offset, content.Count); 10 | 11 | for (; ; ) 12 | { 13 | int begin = str.IndexOf("a=candidate:"); 14 | if (begin < 0) 15 | break; 16 | int end = str.IndexOf("\r\n", begin); 17 | if (end < 0) 18 | break; 19 | 20 | str = str.Remove(begin, end - begin + 2); 21 | } 22 | 23 | return new ArraySegment(System.Text.Encoding.UTF8.GetBytes(str)); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Server/Service.cs: -------------------------------------------------------------------------------- 1 | using System.ServiceProcess; 2 | using System.Threading; 3 | 4 | namespace Sip.Server 5 | { 6 | class Service : ServiceBase 7 | { 8 | public const string Name = "OfficeSIP Server"; 9 | private Server server; 10 | 11 | public Service() 12 | { 13 | this.ServiceName = Name; 14 | } 15 | 16 | public void Emulate() 17 | { 18 | server = new Server(); 19 | Thread.Sleep(Timeout.Infinite); 20 | server.Dispose(); 21 | server = null; 22 | } 23 | 24 | protected override void OnStart(string[] args) 25 | { 26 | RequestAdditionalTime(2 * 60 * 1000); 27 | server = new Server(); 28 | } 29 | protected override void OnStop() 30 | { 31 | RequestAdditionalTime(30 * 1000); 32 | OnShutdown(); 33 | } 34 | protected override void OnShutdown() 35 | { 36 | server.Dispose(); 37 | server = null; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Server/Simple/Publication.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading; 3 | using System.Collections.Generic; 4 | using ThreadSafe = System.Collections.Generic.ThreadSafe; 5 | 6 | namespace Sip.Simple 7 | { 8 | sealed class Publication 9 | { 10 | private readonly ThreadSafe.List subscriptions; 11 | private readonly PresenceDocument document; 12 | 13 | public Publication(string aor) 14 | { 15 | document = new PresenceDocument(aor); 16 | subscriptions = new ThreadSafe.List( 17 | new List()); 18 | } 19 | 20 | public ThreadSafe.List Subscriptions 21 | { 22 | get { return subscriptions; } 23 | } 24 | 25 | public PresenceDocument Document 26 | { 27 | get { return document; } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Server/Simple/Subscription.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Sip.Simple 4 | { 5 | struct Subscription 6 | : IEquatable 7 | { 8 | private int expiresTickCount; 9 | 10 | public Subscription(string id, int expires) 11 | { 12 | Id = id; 13 | expiresTickCount = unchecked(Environment.TickCount + expires * 1000); 14 | } 15 | 16 | public readonly string Id; 17 | 18 | public int Expires 19 | { 20 | get 21 | { 22 | int expires = (expiresTickCount - Environment.TickCount) / 1000; 23 | return (expires >= 0) ? expires : 0; 24 | } 25 | } 26 | 27 | public bool Equals(Subscription other) 28 | { 29 | return Id.Equals(other.Id); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Server/Tools/Bigendian.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace System 4 | { 5 | static class Bigendian 6 | { 7 | public static UInt16 BigendianToUInt16(this byte[] bytes, int startIndex) 8 | { 9 | UInt16 result = 0; 10 | 11 | result |= bytes[startIndex]; 12 | result <<= 8; 13 | result |= bytes[startIndex + 1]; 14 | 15 | return result; 16 | } 17 | 18 | public static UInt32 BigendianToUInt32(this byte[] bytes, int startIndex) 19 | { 20 | UInt32 result = 0; 21 | 22 | result |= bytes[startIndex]; 23 | result <<= 8; 24 | result |= bytes[startIndex + 1]; 25 | result <<= 8; 26 | result |= bytes[startIndex + 2]; 27 | result <<= 8; 28 | result |= bytes[startIndex + 3]; 29 | 30 | return result; 31 | } 32 | 33 | public static UInt32 BigendianToUInt24(this byte[] bytes, int startIndex) 34 | { 35 | UInt32 result = 0; 36 | 37 | result |= bytes[startIndex]; 38 | result <<= 8; 39 | result |= bytes[startIndex + 1]; 40 | result <<= 8; 41 | result |= bytes[startIndex + 2]; 42 | 43 | return result; 44 | } 45 | 46 | public static UInt16 BigendianToUInt16(this byte[] bytes, ref int startIndex) 47 | { 48 | UInt16 result = BigendianToUInt16(bytes, startIndex); 49 | startIndex += sizeof(UInt16); 50 | return result; 51 | } 52 | 53 | public static UInt32 BigendianToUInt32(this byte[] bytes, ref int startIndex) 54 | { 55 | UInt32 result = BigendianToUInt32(bytes, startIndex); 56 | startIndex += sizeof(UInt32); 57 | return result; 58 | } 59 | 60 | public static UInt32 BigendianToUInt24(this byte[] bytes, ref int startIndex) 61 | { 62 | UInt32 result = BigendianToUInt24(bytes, startIndex); 63 | startIndex += sizeof(UInt32) - sizeof(Byte); 64 | return result; 65 | } 66 | 67 | private static byte[] Correct(byte[] data) 68 | { 69 | if (BitConverter.IsLittleEndian) 70 | Array.Reverse(data); 71 | return data; 72 | } 73 | 74 | public static byte[] GetBigendianBytes(this UInt32 value) 75 | { 76 | return Correct(BitConverter.GetBytes(value)); 77 | } 78 | 79 | public static byte[] GetBigendianBytes(this UInt16 value) 80 | { 81 | return Correct(BitConverter.GetBytes(value)); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Server/Tools/BitTwiddling.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace System 4 | { 5 | /// 6 | /// http://graphics.stanford.edu/~seander/bithacks.html 7 | /// 8 | class BitTwiddling 9 | { 10 | private static readonly int[] multiplyDeBruijnBitPosition = new int[32] { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 }; 11 | 12 | /// 13 | /// Find the log base 2 of an N-bit integer in O(lg(N)) operations with multiply and lookup 14 | /// 15 | public static int GetLog2(int value) 16 | { 17 | value |= value >> 1; 18 | value |= value >> 2; 19 | value |= value >> 4; 20 | value |= value >> 8; 21 | value |= value >> 16; 22 | 23 | return multiplyDeBruijnBitPosition[unchecked(((uint)value * 0x07C4ACDDU) >> 27)]; 24 | } 25 | 26 | public static long Pack(int hiInt, int loInt) 27 | { 28 | unchecked 29 | { 30 | ulong packed; 31 | 32 | packed = (ulong)(uint)hiInt; 33 | packed <<= 32; 34 | packed |= (ulong)(uint)loInt; 35 | 36 | return (long)packed; 37 | } 38 | } 39 | 40 | public static void Unpack(long value, out int hiInt, out int loInt) 41 | { 42 | unchecked 43 | { 44 | loInt = (int)value; 45 | 46 | value >>= 32; 47 | hiInt = (int)value; 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Server/Tools/ByteArray.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Base.Message; 3 | using Sip.Message; 4 | 5 | namespace Sip.Tools 6 | { 7 | public static class ByteArray 8 | { 9 | public static int CopyFrom(this byte[] bytes, ByteArrayPart part, int offset) 10 | { 11 | int length = part.Length; 12 | 13 | if (length > 0) 14 | Buffer.BlockCopy(part.Bytes, part.Begin, bytes, offset, length); 15 | 16 | return offset + length; 17 | } 18 | 19 | public static int CopyFrom(this byte[] bytes, int value, int offset) 20 | { 21 | bytes[offset++] = (byte)(value >> 24); 22 | bytes[offset++] = (byte)(value >> 16); 23 | bytes[offset++] = (byte)(value >> 08); 24 | bytes[offset++] = (byte)(value >> 00); 25 | 26 | return offset; 27 | } 28 | 29 | public static bool IsEqualValue(this byte[] x, byte[] y) 30 | { 31 | if (x.Length != y.Length) 32 | return false; 33 | 34 | for (int i = 0; i < x.Length; i++) 35 | if (x[i] != y[i]) 36 | return false; 37 | 38 | return true; 39 | } 40 | 41 | public static int GetValueHashCode(this byte[] bytes) 42 | { 43 | int value = 0; 44 | int maxOffset = bytes.Length - 1; 45 | 46 | if (maxOffset >= 0) 47 | { 48 | for (int i = 0; i <= 3; i++) 49 | { 50 | value <<= 8; 51 | value |= bytes[maxOffset * i / 3]; 52 | } 53 | } 54 | 55 | return value; 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Server/Tools/HashAlgorithmHelpers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Sip.Message; 3 | using Base.Message; 4 | 5 | namespace System.Security.Cryptography 6 | { 7 | public static class HashAlgorithmHelpers 8 | { 9 | public static void TransformBlock(this ICryptoTransform hash, ByteArrayPart part) 10 | { 11 | hash.TransformBlock(part.Bytes, part.Offset, part.Length, null, 0); 12 | } 13 | 14 | public static void TransformBlock(this ICryptoTransform hash, byte[] bytes) 15 | { 16 | hash.TransformBlock(bytes, 0, bytes.Length, null, 0); 17 | } 18 | 19 | public static void TransformFinalBlock(this ICryptoTransform hash, ByteArrayPart part) 20 | { 21 | hash.TransformFinalBlock(part.Bytes, part.Offset, part.Length); 22 | } 23 | 24 | public static void TransformFinalBlock(this ICryptoTransform hash, byte[] bytes) 25 | { 26 | hash.TransformFinalBlock(bytes, 0, bytes.Length); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Server/Tools/IpEndPointExt.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using Sip.Message; 4 | using SocketServers; 5 | 6 | static class IpEndPointExt 7 | { 8 | public static bool IsTransportUnreliable(this ServerEndPoint endPoint) 9 | { 10 | return endPoint.Protocol == ServerProtocol.Udp; 11 | } 12 | 13 | public static ServerProtocol ToServerProtocol(this Transports transport) 14 | { 15 | switch (transport) 16 | { 17 | case Transports.Udp: 18 | return ServerProtocol.Udp; 19 | case Transports.Tcp: 20 | case Transports.Ws: 21 | return ServerProtocol.Tcp; 22 | case Transports.Tls: 23 | case Transports.Wss: 24 | return ServerProtocol.Tls; 25 | default: 26 | throw new NotImplementedException("Can not convert transport " + transport.ToString() + " to protocol."); 27 | } 28 | 29 | throw new InvalidCastException(); 30 | } 31 | 32 | public static Transports ToTransport(this ServerProtocol protocol) 33 | { 34 | switch (protocol) 35 | { 36 | case ServerProtocol.Udp: 37 | return Transports.Udp; 38 | case ServerProtocol.Tcp: 39 | return Transports.Tcp; 40 | case ServerProtocol.Tls: 41 | return Transports.Tls; 42 | } 43 | 44 | throw new InvalidCastException(); 45 | } 46 | 47 | public static void CopyFrom(this IPEndPoint to, IPEndPoint from) 48 | { 49 | to.Address = from.Address; 50 | to.Port = from.Port; 51 | } 52 | 53 | public static IPEndPoint MakeCopy(this IPEndPoint from) 54 | { 55 | return new IPEndPoint(from.Address, from.Port); 56 | } 57 | 58 | public static bool IsEqual(this IPEndPoint ip1, IPEndPoint ip2) 59 | { 60 | return 61 | ip1.AddressFamily == ip2.AddressFamily && 62 | ip1.Port == ip2.Port && 63 | ip1.Address.Equals(ip2.Address); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Server/Tools/NtpTimestamp.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace System.NtpTimestamp 4 | { 5 | static class NtpTimestamp 6 | { 7 | public const UInt64 TicksPerSecond = 10000000; 8 | public readonly static DateTime NtpZeroDateTime = new DateTime(1900, 1, 1); 9 | 10 | public static UInt64 ToNtpTimestamp(this DateTime dateTime) 11 | { 12 | UInt64 ticks = (UInt64)(dateTime - NtpZeroDateTime).Ticks; 13 | 14 | UInt64 seconds = ticks / TicksPerSecond; 15 | UInt64 fractions = ((ticks % TicksPerSecond) << 32) / TicksPerSecond; 16 | 17 | return (seconds << 32) | fractions; 18 | } 19 | 20 | public static DateTime NtpTimestampToUtcDateTime(this UInt64 timestamp) 21 | { 22 | UInt64 seconds = timestamp >> 32; 23 | UInt64 fractions = timestamp & 0xffffffffL; 24 | 25 | UInt64 ticks = seconds * TicksPerSecond + ((fractions * TicksPerSecond) >> 32); 26 | 27 | return NtpZeroDateTime.AddTicks((Int64)ticks); 28 | } 29 | 30 | public static UInt64 MillisecondsToNtpTimestamp(this Int32 milliseconds) 31 | { 32 | #if DEBUG 33 | if (milliseconds < 0) 34 | throw new Exception(); 35 | #endif 36 | 37 | UInt64 seconds = (UInt64)milliseconds / 1000; 38 | UInt64 fractions = (((UInt64)milliseconds % 1000) << 32) / 1000; 39 | 40 | return (seconds << 32) | fractions; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Server/Tools/TupleStruct.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Sip.Server 4 | { 5 | public struct TupleStruct 6 | : IEquatable> 7 | { 8 | private readonly T1 First; 9 | private readonly T2 Second; 10 | 11 | public TupleStruct(T1 f, T2 s) 12 | { 13 | First = f; 14 | Second = s; 15 | } 16 | 17 | public bool Equals(TupleStruct other) 18 | { 19 | return First.Equals(other.First) && Second.Equals(other.Second); 20 | } 21 | 22 | public override bool Equals(object obj) 23 | { 24 | if (obj is TupleStruct) 25 | return this.Equals((TupleStruct)obj); 26 | else 27 | return false; 28 | } 29 | 30 | public override int GetHashCode() 31 | { 32 | return First.GetHashCode() ^ Second.GetHashCode(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Server/Transaction/GeneralVerifier.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Sip.Message; 3 | using Base.Message; 4 | 5 | namespace Sip.Server 6 | { 7 | class GeneralVerifier 8 | { 9 | public enum Errors 10 | { 11 | None, 12 | MandatoryHeaderAbsent, 13 | HeaderDuplication, 14 | SipVersionNotSupported, 15 | ToTagAbsent, 16 | } 17 | 18 | public struct Result 19 | { 20 | private static readonly ByteArrayPart[] errorTexts; 21 | 22 | static Result() 23 | { 24 | errorTexts = new ByteArrayPart[] 25 | { 26 | new ByteArrayPart("No errors"), 27 | new ByteArrayPart("Mandatory header is absent or invalid"), 28 | new ByteArrayPart("Header duplication"), 29 | new ByteArrayPart("SIP version not supported"), 30 | new ByteArrayPart("To tag is absent"), 31 | }; 32 | 33 | var values = Enum.GetValues(typeof(Errors)); 34 | if (errorTexts.Length != values.Length) 35 | throw new InvalidProgramException(@"GeneralVerifier::Result static constructor"); 36 | } 37 | 38 | public Errors Error; 39 | public HeaderNames HeaderName; 40 | 41 | public ByteArrayPart Message 42 | { 43 | get 44 | { 45 | return errorTexts[(int)Error]; 46 | } 47 | } 48 | } 49 | 50 | public Result Validate(IncomingMessage message) 51 | { 52 | if (message.Reader.SipVersion != 20) 53 | return new Result() { Error = Errors.SipVersionNotSupported, }; 54 | 55 | var absent = message.Reader.ValidateMandatoryHeaders(); 56 | if (absent != HeaderNames.None) 57 | return new Result() { Error = Errors.MandatoryHeaderAbsent, HeaderName = absent, }; 58 | 59 | // callcentric does not send to tag in the NOTIFY 60 | //if (message.Reader.From.Tag.IsNotEmpty == false) 61 | // return new Result() { Error = Errors.ToTagAbsent, }; 62 | 63 | //var duplicate = message.Reader.ValidateHeadersDuplication(); 64 | //if (duplicate != HeaderNames.None) 65 | // return new Result() { Error = Errors.HeaderDuplication, HeaderName = duplicate, }; 66 | 67 | return new Result(); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /Server/Transaction/IncomingMessageEx.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.Net.Sockets; 4 | using Sip.Message; 5 | using SocketServers; 6 | 7 | namespace Sip.Server 8 | { 9 | public struct IncomingMessageEx 10 | { 11 | public IncomingMessageEx(IncomingMessage source, int transactionId) 12 | { 13 | TransactionId = transactionId; 14 | 15 | ConnectionAddresses = source.ConnectionAddresses; 16 | 17 | Reader = source.Reader; 18 | 19 | Headers = source.Header; 20 | Content = source.Content; 21 | } 22 | 23 | public readonly int TransactionId; 24 | 25 | public readonly ConnectionAddresses ConnectionAddresses; 26 | 27 | public readonly SipMessageReader Reader; 28 | public readonly ArraySegment Headers; 29 | public readonly ArraySegment Content; 30 | 31 | public BufferHandle DetachBuffers() 32 | { 33 | return TransportLayer.DetachBuffers(); 34 | } 35 | 36 | #region Accessors to ConnectionAddresses fields 37 | 38 | public Transports Transport 39 | { 40 | get { return ConnectionAddresses.Transport; } 41 | } 42 | 43 | public IPEndPoint LocalEndPoint 44 | { 45 | get { return ConnectionAddresses.LocalEndPoint; } 46 | } 47 | 48 | public IPEndPoint RemoteEndPoint 49 | { 50 | get { return ConnectionAddresses.RemoteEndPoint; } 51 | } 52 | 53 | public int ConnectionId 54 | { 55 | get { return ConnectionAddresses.ConnectionId; } 56 | } 57 | 58 | public bool IsTransportUnreliable 59 | { 60 | get { return ConnectionAddresses.Transport == Transports.Udp; } 61 | } 62 | 63 | #endregion 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /Server/Transaction/ProducedRequest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using Sip.Message; 4 | using SocketServers; 5 | 6 | namespace Sip.Server 7 | { 8 | sealed class ProducedRequest 9 | { 10 | public int Index { get; set; } 11 | public Action IncomingResponse { get; set; } 12 | public Action ProduceAck { get; set; } 13 | public Action TransportError { get; set; } 14 | public BaseTransactionUser TransactionUser { get; private set; } 15 | 16 | public ProducedRequest(BaseTransactionUser transactionUser) 17 | { 18 | TransactionUser = transactionUser; 19 | IncomingResponse = None; 20 | TransportError = None; 21 | ProduceAck = None; 22 | } 23 | 24 | public void OnIncomingResponse(IncomingMessageEx message) 25 | { 26 | IncomingResponse(message); 27 | } 28 | 29 | //public int GetTransactionId(Methods method) 30 | //{ 31 | // return TransactionUser.GetTransactionId(method); 32 | //} 33 | 34 | public void SendRequest(ConnectionAddresses connectionAddresses, SipMessageWriter writer, int transactionId, int userData) 35 | { 36 | TransactionUser.SendRequest(Index, connectionAddresses, transactionId, writer, userData); 37 | } 38 | 39 | public void SendRequest(ConnectionAddresses connectionAddresses, SipMessageWriter writer, int transactionId) 40 | { 41 | TransactionUser.SendRequest(Index, connectionAddresses, transactionId, writer, 0); 42 | } 43 | 44 | public void SendRequest(Transports transport, IPEndPoint localEndPoint, IPEndPoint remoteEndPoint, int connectionId, SipMessageWriter writer, int transactionId) 45 | { 46 | TransactionUser.SendRequest(Index, 47 | new ConnectionAddresses(transport, localEndPoint, remoteEndPoint, connectionId), transactionId, writer, 0); 48 | } 49 | 50 | private static void None(IncomingMessageEx message) { } 51 | private static void None(int transactionId, int userData) { } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Server/TransactionUsers/ErrorTU.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Sip.Message; 4 | 5 | namespace Sip.Server 6 | { 7 | class ErrorTU 8 | : BaseTransactionUser 9 | { 10 | public override IEnumerable GetAcceptedRequests() 11 | { 12 | foreach (Methods method in Enum.GetValues(typeof(Methods))) 13 | if (method != Methods.None) 14 | yield return new AcceptedRequest(this) 15 | { 16 | Method = method, 17 | IsAcceptedRequest = (reader) => true, 18 | IncomingRequest = ProccessRequest, 19 | AuthorizationMode = AuthorizationMode.Disabled, 20 | }; 21 | } 22 | 23 | private void ProccessRequest(AcceptedRequest tu, IncomingMessageEx request) 24 | { 25 | var writer = GetWriter(); 26 | 27 | writer.WriteStatusLine(StatusCodes.NotImplemented); 28 | writer.CopyViaToFromCallIdRecordRouteCSeq(request.Reader, StatusCodes.NotImplemented); 29 | writer.WriteContentLength(0); 30 | writer.WriteCRLF(); 31 | 32 | tu.SendResponse(request, writer); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Server/TransactionUsers/MrasTU.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Threading; 4 | using System.Collections.Generic; 5 | using Sip.Message; 6 | using Base.Message; 7 | using Sip.Server.Accounts; 8 | using SocketServers; 9 | using Mras; 10 | 11 | namespace Sip.Server 12 | { 13 | sealed class MrasTU 14 | : BaseTransactionUser 15 | { 16 | private readonly ByteArrayPart type; 17 | private readonly ByteArrayPart subtype; 18 | private readonly byte[] userPrefix; 19 | private readonly Mras1 mras; 20 | 21 | public MrasTU(Mras1 mras) 22 | { 23 | this.type = new ByteArrayPart("application"); 24 | this.subtype = new ByteArrayPart("msrtc-media-relay-auth+xml"); 25 | this.userPrefix = Encoding.UTF8.GetBytes("MRASLoc."); 26 | 27 | this.mras = mras; 28 | } 29 | 30 | public override IEnumerable GetAcceptedRequests() 31 | { 32 | yield return new AcceptedRequest(this) 33 | { 34 | Method = Methods.Servicem, 35 | IsAcceptedRequest = (reader) => IsAccepted(reader), 36 | IncomingRequest = ProccessService, 37 | }; 38 | } 39 | 40 | public bool IsAccepted(SipMessageReader reader) 41 | { 42 | return 43 | reader.ContentType.Type.Equals(type) && 44 | reader.ContentType.Subtype.Equals(subtype) && 45 | reader.To.AddrSpec.User.StartsWith(userPrefix); 46 | } 47 | 48 | private void ProccessService(AcceptedRequest tu, IncomingMessageEx request) 49 | { 50 | var writer = GetWriter(); 51 | 52 | try 53 | { 54 | var outContent = mras.ProcessRequest(request.Content); 55 | 56 | writer.WriteStatusLine(StatusCodes.OK); 57 | writer.CopyViaToFromCallIdRecordRouteCSeq(request.Reader, StatusCodes.OK); 58 | writer.WriteContentType(type, subtype); 59 | writer.WriteCustomHeaders(); 60 | writer.WriteContentLength(); 61 | writer.WriteCRLF(); 62 | 63 | writer.Write(outContent.GenerateToByteArray()); 64 | writer.RewriteContentLength(); 65 | } 66 | catch (MrasException) 67 | { 68 | writer.WriteResponse(request.Reader, StatusCodes.BadRequest); 69 | } 70 | 71 | tu.SendResponse(request, writer); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Server/TransactionUsers/OptionsTU.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Sip; 4 | using Sip.Simple; 5 | using Sip.Message; 6 | using SocketServers; 7 | 8 | namespace Sip.Server 9 | { 10 | class OptionsTU 11 | : BaseTransactionUser 12 | { 13 | public static readonly Methods[] AllowMethods = new Methods[] { Methods.Registerm, Methods.Invitem, 14 | Methods.Ackm, Methods.Cancelm, Methods.Byem, Methods.Optionsm, Methods.Subscribem, 15 | Methods.Notifym, Methods.Publishm, Methods.Servicem, }; 16 | 17 | 18 | public override IEnumerable GetAcceptedRequests() 19 | { 20 | yield return new AcceptedRequest(this) 21 | { 22 | Method = Methods.Optionsm, 23 | IsAcceptedRequest = (reader) => true, 24 | AuthorizationMode = AuthorizationMode.Disabled, 25 | IncomingRequest = ProccessOptions, 26 | }; 27 | } 28 | 29 | private void ProccessOptions(AcceptedRequest tu, IncomingMessageEx request) 30 | { 31 | var writer = GetWriter(); 32 | 33 | writer.WriteStatusLine(StatusCodes.OK); 34 | writer.CopyViaToFromCallIdRecordRouteCSeq(request.Reader, StatusCodes.OK); // statusCode есть во writer'е!!!!!! 35 | writer.WriteAllow(AllowMethods); 36 | writer.WriteCRLF(); 37 | 38 | tu.SendResponse(request, writer); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Server/TransactionUsers/ProxyServerTU/BaseProxie.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Sip.Message; 3 | 4 | namespace Sip.Server 5 | { 6 | class BaseProxie 7 | { 8 | public BaseProxie(int transactionId) 9 | { 10 | TransactionId = transactionId; 11 | } 12 | 13 | public int TransactionId { get; private set; } 14 | public bool IsFinalReceived { get; set; } 15 | public bool IsCancelSent { get; set; } 16 | public int TimerC { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Server/TransactionUsers/ProxyServerTU/IProxie.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Sip.Message; 3 | 4 | namespace Sip.Server 5 | { 6 | interface IProxie 7 | { 8 | int TransactionId { get; } 9 | ConnectionAddresses ToConnectionAddresses { get; } 10 | bool IsFinalReceived { get; set; } 11 | bool IsCancelSent { get; set; } 12 | int TimerC { get; set; } 13 | 14 | void GenerateForwardedRequest(SipMessageWriter writer, SipMessageReader reader, ArraySegment content, ConnectionAddresses ca, int serverTransactionId); 15 | void GenerateForwardedResponse(SipMessageWriter writer, SipMessageReader reader, ArraySegment content, ConnectionAddresses ca); 16 | void GenerateCancel(SipMessageWriter writer, SipMessageReader message); 17 | void GenerateAck(SipMessageWriter writer, SipMessageReader message); 18 | 19 | bool CanFork(SipMessageReader response); 20 | IProxie Fork(int transactionId); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Server/TransactionUsers/ProxyServerTU/ProxieFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Sip.Message; 3 | using Base.Message; 4 | 5 | namespace Sip.Server 6 | { 7 | static class ProxieFactory 8 | { 9 | public static IProxie Create(int transactionId, LocationService.Binding binding) 10 | { 11 | return new LocalProxie(binding, transactionId); 12 | } 13 | 14 | public static IProxie Create(int transactionId, Trunk trunk) 15 | { 16 | return new LocalTrunkProxie(transactionId, trunk); 17 | } 18 | 19 | public static IProxie Create(int transactionId, Trunk trunk, ByteArrayPart toTag) 20 | { 21 | int tag; 22 | Dialog dialog1 = null; 23 | if (HexEncoding.TryParseHex8(toTag, out tag)) 24 | dialog1 = trunk.GetDialog1(tag); 25 | 26 | return (dialog1 == null) ? null : new TrunkDialogProxie(transactionId, trunk, tag, dialog1); 27 | } 28 | 29 | public static IProxie Create(int transactionId, Trunk trunk, LocationService.Binding binding) 30 | { 31 | return new TrunkLocalProxie(transactionId, trunk, binding); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Server/TransactionUsers/ProxyServerTU/RequestProxyFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | using Sip.Message; 5 | 6 | namespace Sip.Server 7 | { 8 | partial class ProxyServerTU 9 | { 10 | struct RequestProxyFactory 11 | { 12 | private readonly ProxyServerTU parent; 13 | private readonly IncomingMessageEx request; 14 | 15 | private RequestProxy requestProxy; 16 | 17 | public RequestProxyFactory(ProxyServerTU parent, IncomingMessageEx request) 18 | { 19 | this.parent = parent; 20 | this.request = request; 21 | 22 | this.requestProxy = null; 23 | } 24 | 25 | public void Forward(IProxie proxie) 26 | { 27 | if (proxie != null) 28 | { 29 | CreateLockedRequestProxy(); 30 | parent.ForwardRequest(proxie, requestProxy, request.Reader); 31 | } 32 | } 33 | 34 | public bool HasValue 35 | { 36 | get { return requestProxy != null; } 37 | } 38 | 39 | public RequestProxy Value 40 | { 41 | get { return requestProxy; } 42 | } 43 | 44 | public void SetAllRequestsSent() 45 | { 46 | if (requestProxy != null) 47 | requestProxy.SetAllRequestsSent(); 48 | } 49 | 50 | public void Release() 51 | { 52 | if (requestProxy != null) 53 | Monitor.Exit(requestProxy); 54 | } 55 | 56 | private void CreateLockedRequestProxy() 57 | { 58 | if (requestProxy == null) 59 | { 60 | requestProxy = new RequestProxy(request); 61 | Monitor.Enter(requestProxy); 62 | 63 | if (request.Reader.Method != Methods.Ackm) 64 | parent.requestProxyes.Add(requestProxy.ServerTransactionId, requestProxy); 65 | 66 | if (request.Reader.Method == Methods.Invitem) 67 | { 68 | var writer = parent.GetWriter(); 69 | writer.WriteResponse(request.Reader, StatusCodes.Trying); 70 | parent.SendResponse(request, writer); 71 | } 72 | } 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Server/Transport/AjaxWebsocketWriter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using Http.Message; 4 | 5 | namespace Sip.Server 6 | { 7 | static class AjaxWebsocketWriter 8 | { 9 | private static byte[] accessControlAllowHeaders = Encoding.UTF8.GetBytes("Authorization"); 10 | private static byte[] accessControlExposeHeaders = Encoding.UTF8.GetBytes("WWW-Authenticate"); 11 | 12 | public static void WriteNotFinishedResponse(this HttpMessageWriter writer, StatusCodes statusCode, ContentType contentType) 13 | { 14 | writer.WriteStatusLine(statusCode); 15 | writer.WriteAccessControlHeaders(); 16 | if (contentType != ContentType.None) 17 | writer.WriteContentType(contentType); 18 | else 19 | writer.WriteContentLength(0); 20 | } 21 | 22 | public static void WriteResponse(this HttpMessageWriter writer, StatusCodes statusCodes, ContentType contentType, byte[] content) 23 | { 24 | writer.WriteStatusLine(statusCodes); 25 | writer.WriteAccessControlHeaders(); 26 | writer.WriteContentType(contentType); 27 | writer.WriteContentLength(content.Length); 28 | writer.WriteCRLF(); 29 | writer.Write(content); 30 | } 31 | 32 | public static void WriteEmptyResponse(this HttpMessageWriter writer, StatusCodes statusCode) 33 | { 34 | writer.WriteStatusLine(statusCode); 35 | writer.WriteAccessControlHeaders(); 36 | writer.WriteContentLength(0); 37 | writer.WriteCRLF(); 38 | } 39 | 40 | public static void WriteAccessControlHeaders(this HttpMessageWriter writer) 41 | { 42 | writer.WriteAccessControlAllowOrigin(true); 43 | writer.WriteAccessControlAllowCredentials(true); 44 | writer.WriteAccessControlAllowHeaders(accessControlAllowHeaders); 45 | writer.WriteAccessControlExposeHeaders(accessControlExposeHeaders); 46 | writer.WriteAccessControlAllowMethods(Methods.Get, Methods.Post, Methods.Options); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Server/Transport/BufferHandle.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using SocketServers; 3 | 4 | namespace Sip.Server 5 | { 6 | public struct BufferHandle 7 | { 8 | private ArraySegment segment1; 9 | private ArraySegment segment2; 10 | 11 | public BufferHandle(ArraySegment segment1, ArraySegment segment2) 12 | { 13 | this.segment1 = segment1; 14 | this.segment2 = segment2; 15 | } 16 | 17 | public void Free() 18 | { 19 | BufferManager.Free(ref segment1); 20 | BufferManager.Free(ref segment2); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Server/Transport/OutgoingMessage.cs: -------------------------------------------------------------------------------- 1 | //using System; 2 | //using System.Net; 3 | //using System.Net.Sockets; 4 | //using Sip.Message; 5 | //using SocketServers; 6 | 7 | //namespace Sip.Server 8 | //{ 9 | // class OutgoingMessage 10 | // { 11 | // public IncomingMessageEx(IncomingMessage source, int transactionId) 12 | // { 13 | // TransactionId = transactionId; 14 | 15 | // ConnectionAddresses = source.ConnectionAddresses; 16 | 17 | // Reader = source.Reader; 18 | 19 | // Headers = source.Headers; 20 | // Content = source.Content; 21 | // } 22 | 23 | // public readonly int TransactionId; 24 | 25 | // public readonly ConnectionAddresses ConnectionAddresses; 26 | 27 | // public readonly SipMessageReader Reader; 28 | // public readonly ArraySegment Headers; 29 | // public readonly ArraySegment Content; 30 | // } 31 | //} 32 | -------------------------------------------------------------------------------- /Server/Trunk/ITrunkManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Sip.Message; 4 | using Base.Message; 5 | 6 | namespace Sip.Server 7 | { 8 | interface ITrunkManager 9 | { 10 | event Action TrunkAdded; 11 | event Action TrunkRemoved; 12 | 13 | //Trunk GetTrunk(ByteArrayPart host); 14 | Trunk GetTrunkByDomain(ByteArrayPart host); 15 | Trunk GetTrunkById(int id); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Server/Users/AdUser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.DirectoryServices; 4 | using Sip.Server.Tools; 5 | 6 | namespace Sip.Server.Users 7 | { 8 | class AdUser 9 | : BaseUser 10 | { 11 | private readonly static string[] properties = new string[] 12 | { 13 | @"sAMAccountName", 14 | @"memberOf", 15 | @"displayName", 16 | @"mail", 17 | @"telephoneNumber", 18 | @"facsimileTelephoneNumber", 19 | @"streetAddress", 20 | @"l", 21 | @"st", 22 | @"countryCode", 23 | @"postalCode", 24 | @"wWWHomePage", 25 | @"title", 26 | @"company", 27 | @"physicalDeliveryOfficeName" 28 | }; 29 | 30 | public AdUser() 31 | { 32 | } 33 | 34 | public AdUser(SearchResult user) 35 | { 36 | Name = GetAsString(user, @"sAMAccountName").ToLower(); 37 | DisplayName = GetAsString(user, @"displayName"); 38 | Email = GetAsString(user, @"mail"); 39 | Telephone = GetAsString(user, @"telephoneNumber"); 40 | Fax = GetAsString(user, @"facsimileTelephoneNumber"); 41 | StreetAddress = GetAsString(user, @"streetAddress"); 42 | City = GetAsString(user, @"l"); 43 | State = GetAsString(user, @"st"); 44 | CountryCode = ISO3166.ToA2(GetAsInt(user, @"countryCode"), null); 45 | PostalCode = GetAsString(user, @"postalCode"); 46 | WwwHomepage = GetAsString(user, @"wWWHomePage"); 47 | Title = GetAsString(user, @"title"); 48 | Company = GetAsString(user, @"company"); 49 | PhysicalDeliveryOfficeName = GetAsString(user, @"physicalDeliveryOfficeName"); 50 | } 51 | 52 | public static string[] Properties 53 | { 54 | get { return properties; } 55 | } 56 | 57 | private string GetAsString(SearchResult result, string name) 58 | { 59 | var s = String.Empty; 60 | 61 | try 62 | { 63 | s = result.Properties[name][0] as string; 64 | } 65 | catch 66 | { 67 | } 68 | 69 | return s; 70 | } 71 | 72 | 73 | private int GetAsInt(SearchResult result, string name) 74 | { 75 | int i = 0; 76 | 77 | try 78 | { 79 | i = (int)result.Properties[name][0]; 80 | } 81 | catch 82 | { 83 | } 84 | 85 | return i; 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Server/Users/IUser.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Sip.Server.Users 4 | { 5 | public interface IUser 6 | { 7 | string Name { get; } 8 | 9 | string DisplayName { get; set; } 10 | string Email { get; set; } 11 | 12 | string Password { get; set; } 13 | 14 | string Telephone { get; set; } 15 | string Fax { get; set; } 16 | 17 | string City { get; set; } 18 | string State { get; set; } 19 | string StreetAddress { get; set; } 20 | string CountryCode { get; set; } 21 | string PostalCode { get; set; } 22 | string WwwHomepage { get; set; } 23 | string Title { get; set; } 24 | string Company { get; set; } 25 | string PhysicalDeliveryOfficeName { get; set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Server/Users/IUsers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Sip.Server.Users 5 | { 6 | public delegate void IUsersEventHandler1(int accountId, IUsers source, IUser user); 7 | public delegate void IUsersEventHandler2(int accountId, IUsers source); 8 | 9 | public interface IUsers 10 | : IDisposable 11 | { 12 | event IUsersEventHandler2 Reset; 13 | event IUsersEventHandler1 Added; 14 | event IUsersEventHandler1 Updated; 15 | event IUsersEventHandler1 Removed; 16 | 17 | string Id { get; } 18 | string SourceName { get; } 19 | bool HasPasswords { get; } 20 | 21 | bool IsReadOnly { get; } 22 | 23 | void Add(int accountId, IUser user); 24 | void Update(int accountId, IUser user); 25 | void Remove(int accountId, string name); 26 | 27 | int GetCount(int accountId); 28 | 29 | IList GetUsers(int accountId, int startIndex, int count); 30 | 31 | IUser GetByName(int accountId, string name); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Server/Users/IUserz.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Sip.Server.Users 4 | { 5 | public interface IUserz 6 | { 7 | event IUsersEventHandler2 Reset; 8 | event IUsersEventHandler1 Added; 9 | event IUsersEventHandler1 Updated; 10 | event IUsersEventHandler1 Removed; 11 | 12 | IUsers this[int index] { get; } 13 | int Count { get; } 14 | 15 | int GetIndex(string id); 16 | IUsers Get(string id); 17 | 18 | IUsers[] ToArray(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Server/Users/UsersException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Sip.Server.Users 4 | { 5 | enum ErrorCodes 6 | { 7 | UserExist, 8 | UsernameEmpty, 9 | } 10 | 11 | public class UsersException 12 | : Exception 13 | { 14 | internal UsersException(ErrorCodes code) 15 | : base(GetMessage(code)) 16 | { 17 | 18 | } 19 | 20 | internal static string GetMessage(ErrorCodes code) 21 | { 22 | switch (code) 23 | { 24 | case ErrorCodes.UserExist: 25 | return @"User with specified username already exist"; 26 | case ErrorCodes.UsernameEmpty: 27 | return @"Empty username is not allowed"; 28 | } 29 | 30 | return null; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Server/WcfService/IWcfService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Net; 3 | using System.ServiceModel; 4 | using System.Collections.Generic; 5 | using System.Runtime.Serialization; 6 | using Sip.Server.Users; 7 | 8 | namespace Sip.Server.WcfService 9 | { 10 | [ServiceContract(Namespace = "http://officesip.com/server.control", CallbackContract = typeof(IWcfServiceCallback))] 11 | public interface IWcfService 12 | { 13 | [OperationContract] 14 | WcfConfiguration GetConfigurations(); 15 | 16 | [OperationContract] 17 | void SetConfigurations(WcfConfiguration configurations); 18 | 19 | 20 | 21 | [OperationContract] 22 | int GetUsersCount(string id); 23 | 24 | [OperationContract] 25 | IList GetUsers(string id, int startIndex, int count, out int overallCount); 26 | 27 | 28 | 29 | [OperationContract] 30 | void AddUser(string usersId, WcfUser user, string password); 31 | 32 | [OperationContract] 33 | void UpdateUser(string usersId, WcfUser user); 34 | 35 | [OperationContract] 36 | void RemoveUser(string usersId, string name); 37 | 38 | [OperationContract] 39 | void SetUserPassword(string usersId, string name, string password); 40 | 41 | 42 | 43 | [OperationContract] 44 | IEnumerable GetVoipProviders(); 45 | 46 | [OperationContract] 47 | void AddVoipProvider(WcfVoipProvider provider); 48 | 49 | [OperationContract] 50 | void RemoveVoipProvider(string username, string hostname); 51 | 52 | 53 | 54 | [OperationContract] 55 | void Ping(); 56 | 57 | [OperationContract] 58 | Version GetVersion(); 59 | 60 | 61 | [OperationContract] 62 | string GetDefaultXmlConfiguration(); 63 | 64 | [OperationContract] 65 | string GetXmlConfiguration(); 66 | 67 | [OperationContract] 68 | string[] SetXmlConfiguration(string xml); 69 | 70 | [OperationContract] 71 | string[] ValidateXmlConfiguration(string xml); 72 | 73 | 74 | 75 | [OperationContract] 76 | WcfTurnConfiguration GetTurnConfigurations(); 77 | 78 | [OperationContract] 79 | void SetTurnConfigurations(WcfTurnConfiguration configurations); 80 | 81 | [OperationContract] 82 | void SetAdministratorPassword(string newPassword); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Server/WcfService/IWcfServiceCallback.cs: -------------------------------------------------------------------------------- 1 | using System.ServiceModel; 2 | using System.Runtime.Serialization; 3 | using System.Collections.Generic; 4 | using System.Net; 5 | using Sip.Server.Users; 6 | 7 | namespace Sip.Server.WcfService 8 | { 9 | interface IWcfServiceCallback 10 | { 11 | [OperationContract(IsOneWay = true)] 12 | void AvailabilityChanged(string name, int availability); 13 | 14 | [OperationContract(IsOneWay = true)] 15 | void NewClient(); 16 | 17 | [OperationContract(IsOneWay = true)] 18 | void UsersReset(string usersId); 19 | 20 | [OperationContract(IsOneWay = true)] 21 | void UserAddedOrUpdated(string usersId, WcfUser user); 22 | 23 | [OperationContract(IsOneWay = true)] 24 | void UserRemoved(string usersId, string name); 25 | 26 | [OperationContract(IsOneWay = true)] 27 | void VoipProviderUpdated(WcfVoipProvider info); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Server/WcfService/WcfConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System.Net; 2 | using System.Runtime.Serialization; 3 | using System.Collections.Generic; 4 | using Sip.Server.Users; 5 | 6 | namespace Sip.Server.WcfService 7 | { 8 | [DataContract(Name = "Configurations", Namespace = "http://officesip.com/server.control")] 9 | public class WcfConfiguration 10 | { 11 | [DataMember] 12 | public string DomainName { set; get; } 13 | 14 | 15 | 16 | [DataMember] 17 | public bool IsAuthorizationEnabled { set; get; } 18 | 19 | 20 | 21 | 22 | [DataMember] 23 | public bool IsActiveDirectoryUsersEnabled { set; get; } 24 | 25 | [DataMember] 26 | public string ActiveDirectoryUsersGroup { set; get; } 27 | 28 | 29 | 30 | [DataMember] 31 | public bool IsTracingEnabled { set; get; } 32 | 33 | [DataMember] 34 | public string TracingFileName { set; get; } 35 | 36 | 37 | 38 | [DataMember] 39 | public IEnumerable Users { get; set; } 40 | 41 | 42 | //public IPEndPoint PortForwardingPublicIPEndPoint 43 | //public IPEndPoint PortForwardingPrivateIPEndPoint 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Server/WcfService/WcfTurnConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using System.Collections.Generic; 3 | 4 | namespace Sip.Server.WcfService 5 | { 6 | [DataContract(Name = "TURNConfigurations", Namespace = "http://officesip.com/server.control")] 7 | public class WcfTurnConfiguration 8 | { 9 | [DataMember] 10 | public byte[] Key1 { get; set; } 11 | [DataMember] 12 | public byte[] Key2 { get; set; } 13 | [DataMember] 14 | public string FQDN { get; set; } 15 | [DataMember] 16 | public int UDPPort { get; set; } 17 | [DataMember] 18 | public int TCPPort { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Server/WcfService/WcfUser.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using Sip.Server.Users; 3 | 4 | namespace Sip.Server.WcfService 5 | { 6 | [DataContract(Name = "User", Namespace = "http://officesip.com/server.control")] 7 | public class WcfUser 8 | { 9 | public WcfUser(IUser user) 10 | { 11 | Name = user.Name; 12 | DisplayName = user.DisplayName; 13 | Email = user.Email; 14 | } 15 | 16 | [DataMember] 17 | public string Name { set; get; } 18 | [DataMember] 19 | public string DisplayName { set; get; } 20 | [DataMember] 21 | public string Email { set; get; } 22 | [DataMember] 23 | public int Availability { set; get; } 24 | 25 | public IUser ToIUser(string password) 26 | { 27 | return new BaseUser() 28 | { 29 | Name = Name, 30 | DisplayName = DisplayName, 31 | Email = Email, 32 | Password = password, 33 | }; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Server/WcfService/WcfUsers.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.Serialization; 2 | using Sip.Server.Users; 3 | 4 | namespace Sip.Server.WcfService 5 | { 6 | [DataContract(Name = "Users", Namespace = "http://officesip.com/server.control")] 7 | public class WcfUsers 8 | { 9 | public WcfUsers(IUsers users) 10 | { 11 | Id = users.Id; 12 | SourceName = users.SourceName; 13 | IsReadOnly = users.IsReadOnly; 14 | } 15 | 16 | [DataMember] 17 | public string Id { get; private set; } 18 | [DataMember] 19 | public string SourceName { get; private set; } 20 | [DataMember] 21 | public bool IsReadOnly { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Server/Www/assets/bootstrap/bootstrap-transition.js: -------------------------------------------------------------------------------- 1 | /* =================================================== 2 | * bootstrap-transition.js v2.2.2 3 | * http://twitter.github.com/bootstrap/javascript.html#transitions 4 | * =================================================== 5 | * Copyright 2012 Twitter, Inc. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * ========================================================== */ 19 | 20 | 21 | !function ($) { 22 | 23 | "use strict"; // jshint ;_; 24 | 25 | 26 | /* CSS TRANSITION SUPPORT (http://www.modernizr.com/) 27 | * ======================================================= */ 28 | 29 | $(function () { 30 | 31 | $.support.transition = (function () { 32 | 33 | var transitionEnd = (function () { 34 | 35 | var el = document.createElement('bootstrap') 36 | , transEndEventNames = { 37 | 'WebkitTransition' : 'webkitTransitionEnd' 38 | , 'MozTransition' : 'transitionend' 39 | , 'OTransition' : 'oTransitionEnd otransitionend' 40 | , 'transition' : 'transitionend' 41 | } 42 | , name 43 | 44 | for (name in transEndEventNames){ 45 | if (el.style[name] !== undefined) { 46 | return transEndEventNames[name] 47 | } 48 | } 49 | 50 | }()) 51 | 52 | return transitionEnd && { 53 | end: transitionEnd 54 | } 55 | 56 | })() 57 | 58 | }) 59 | 60 | }(window.jQuery); -------------------------------------------------------------------------------- /Server/Www/assets/bootstrap/img/glyphicons-halflings-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Server/Www/assets/bootstrap/img/glyphicons-halflings-white.png -------------------------------------------------------------------------------- /Server/Www/assets/bootstrap/img/glyphicons-halflings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Server/Www/assets/bootstrap/img/glyphicons-halflings.png -------------------------------------------------------------------------------- /Server/Www/assets/codemirror/simple-hint.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-completions { 2 | position: absolute; 3 | z-index: 10; 4 | overflow: hidden; 5 | -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2); 6 | -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2); 7 | box-shadow: 2px 3px 5px rgba(0,0,0,.2); 8 | } 9 | .CodeMirror-completions select { 10 | background: #fafafa; 11 | outline: none; 12 | border: none; 13 | padding: 0; 14 | margin: 0; 15 | font-family: monospace; 16 | } 17 | -------------------------------------------------------------------------------- /Server/Www/index.css: -------------------------------------------------------------------------------- 1 |  2 | .x-menu { 3 | padding: 8px 0; 4 | } 5 | 6 | .CodeMirror { 7 | border-top: 1px solid #eee; 8 | border-bottom: 1px solid #eee; 9 | border-right: 1px solid #eee; 10 | height: 32em; 11 | } 12 | 13 | /* bootstrap docs.css */ 14 | .jumbotron { 15 | position: relative; 16 | } 17 | .jumbotron h1 { 18 | margin-bottom: 9px; 19 | font-size: 81px; 20 | font-weight: bold; 21 | letter-spacing: -1px; 22 | line-height: 1; 23 | } 24 | .jumbotron p { 25 | margin-bottom: 18px; 26 | font-weight: 300; 27 | } 28 | .jumbotron .btn-large { 29 | font-size: 20px; 30 | font-weight: normal; 31 | padding: 14px 24px; 32 | margin-right: 10px; 33 | -webkit-border-radius: 6px; 34 | -moz-border-radius: 6px; 35 | border-radius: 6px; 36 | } 37 | .jumbotron .btn-large small { 38 | font-size: 14px; 39 | } 40 | 41 | /* Masthead (docs home) */ 42 | .masthead { 43 | padding-top: 36px; 44 | margin-bottom: 72px; 45 | } 46 | .masthead h1, 47 | .masthead p { 48 | text-align: center; 49 | } 50 | .masthead h1 { 51 | margin-bottom: 18px; 52 | } 53 | .masthead p { 54 | margin-left: 5%; 55 | margin-right: 5%; 56 | font-size: 30px; 57 | line-height: 36px; 58 | } 59 | 60 | /* ----------------- */ -------------------------------------------------------------------------------- /Server/Www/xmlEditorHints.js: -------------------------------------------------------------------------------- 1 |  2 | CodeMirror.xmlHints['<'] = [ 3 | 'sipServer' 4 | ]; 5 | 6 | CodeMirror.xmlHints['<'] = [ 7 | 'portForwardings', 8 | 'turnServers', 9 | 'voipProviders' 10 | ]; 11 | 12 | CodeMirror.xmlHints['<'] = 13 | CodeMirror.xmlHints['<'] = 14 | CodeMirror.xmlHints['<'] = [ 15 | 'add', 16 | 'clear', 17 | 'remove' 18 | ]; 19 | 20 | CodeMirror.xmlHints['/g; 5 | 6 | var removeComments = function (xml) { 7 | return xml.replace(reComment, '{C097EBC1-2006-4203-A96F-37F7075DC344}'); 8 | } 9 | 10 | var restoreComments = function (xml, originalXml) { 11 | 12 | var comments = originalXml.match(reComment); 13 | 14 | if (comments != null) { 15 | for (var i = 0; i < comments.length; i++) { 16 | xml = xml.replace(/{C097EBC1-2006-4203-A96F-37F7075DC344}/, comments[i]); 17 | } 18 | } 19 | return xml; 20 | } 21 | 22 | this.changeAttribute = function (originalXml, element, attribute, newValue) { 23 | 24 | var xml = removeComments(originalXml); 25 | 26 | var attrAndValue = attribute + '="' + newValue + '"'; 27 | 28 | var reAttr = new RegExp(attribute + '=".*?"', 'g'); 29 | 30 | var newXml = ''; 31 | if (xml.match(reAttr) != null) { 32 | newXml = xml.replace(reAttr, attrAndValue); 33 | } 34 | else { 35 | var index = xml.indexOf(element); 36 | if (index >= 0) { 37 | index += element.length; 38 | newXml = xml.slice(0, index) + '\n\t' + attrAndValue + xml.slice(index) 39 | } 40 | } 41 | 42 | return restoreComments(newXml, originalXml) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Server/Xcap/PidfManipulationHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Sip.Simple; 3 | using Base.Message; 4 | using Http.Message; 5 | 6 | namespace Server.Xcap 7 | { 8 | class PidfManipulationHandler 9 | : BasePidfManipulationHandler 10 | { 11 | private readonly SimpleModule simpleModule; 12 | 13 | public PidfManipulationHandler(SimpleModule simpleModule) 14 | { 15 | this.simpleModule = simpleModule; 16 | } 17 | 18 | public override HttpMessageWriter ProcessGetItem(ByteArrayPart username, ByteArrayPart domain) 19 | { 20 | var document = simpleModule.GetDocument(username.ToString() + "@" + domain.ToString()); 21 | 22 | if (document == null) 23 | { 24 | return base.CreateResponse(StatusCodes.NotFound); 25 | } 26 | else 27 | { 28 | var response = base.CreateNotFinishedResponse(StatusCodes.OK, ContentType.ApplicationPidfXml); 29 | 30 | document.WriteLenghtAndContent(response); 31 | 32 | return response; 33 | } 34 | } 35 | 36 | public override HttpMessageWriter ProcessPutItem(ByteArrayPart username, ByteArrayPart domain, HttpMessageReader reader, ArraySegment content) 37 | { 38 | var statusCode = StatusCodes.OK; 39 | 40 | int sipIfMatch = simpleModule.InvalidEtag; 41 | if (reader.Count.IfMatches > 0) 42 | { 43 | if (HexEncoding.TryParseHex8(reader.IfMatches[0].Bytes, reader.IfMatches[0].Begin, out sipIfMatch) == false) 44 | statusCode = StatusCodes.PreconditionFailed; 45 | } 46 | 47 | if (statusCode == StatusCodes.OK) 48 | { 49 | if (simpleModule.Publish(username.ToString() + "@" + domain.ToString(), ref sipIfMatch, 60, content) == false) 50 | statusCode = StatusCodes.BadRequest; 51 | } 52 | 53 | HttpMessageWriter response; 54 | if (statusCode != StatusCodes.OK) 55 | { 56 | response = CreateResponse(statusCode); 57 | } 58 | else 59 | { 60 | response = CreateNotFinishedResponse(statusCode, ContentType.None); 61 | 62 | response.WriteEtag(sipIfMatch); 63 | response.WriteCRLF(); 64 | } 65 | 66 | return response; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Server/Xcap/ResourceListsHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Sip.Server.Users; 4 | using Sip.Server.Accounts; 5 | using Base.Message; 6 | 7 | namespace Server.Xcap 8 | { 9 | class ResourceListsHandler 10 | : BaseResourceListsHandler 11 | { 12 | private readonly IUserz userz; 13 | private readonly IAccounts accounts; 14 | 15 | public ResourceListsHandler(IAccounts accounts, IUserz userz) 16 | { 17 | this.accounts = accounts; 18 | this.userz = userz; 19 | } 20 | 21 | protected override IEnumerable GetEntries(ByteArrayPart username, ByteArrayPart domain) 22 | { 23 | var account = accounts.GetAccount(domain); 24 | 25 | if (account != null) 26 | { 27 | for (int i = 0; i < userz.Count; i++) 28 | { 29 | int count = userz[i].GetCount(account.Id); 30 | var users = userz[i].GetUsers(account.Id, 0, count); 31 | 32 | for (int j = 0; j < users.Count; j++) 33 | { 34 | var user = users[j]; 35 | 36 | yield return new Entry("sip:" + user.Name + "@" + account.DomainName, user.DisplayName); 37 | } 38 | } 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Server/app.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /Server/dll/CsvReader.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Server/dll/CsvReader.dll -------------------------------------------------------------------------------- /Server/dll/CsvReader_src.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Server/dll/CsvReader_src.zip -------------------------------------------------------------------------------- /Server/dll/DataVirtualization.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Server/dll/DataVirtualization.dll -------------------------------------------------------------------------------- /Server/dll/DataVirtualization.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Server/dll/DataVirtualization.zip -------------------------------------------------------------------------------- /Server/dll/DnDns.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Server/dll/DnDns.dll -------------------------------------------------------------------------------- /Server/dll/Http.Message.dfa: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Server/dll/Http.Message.dfa -------------------------------------------------------------------------------- /Server/dll/Http.Message.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Server/dll/Http.Message.dll -------------------------------------------------------------------------------- /Server/dll/ICSharpCode.AvalonEdit.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Server/dll/ICSharpCode.AvalonEdit.dll -------------------------------------------------------------------------------- /Server/dll/Json45r7.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Server/dll/Json45r7.zip -------------------------------------------------------------------------------- /Server/dll/Newtonsoft.Json.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Server/dll/Newtonsoft.Json.dll -------------------------------------------------------------------------------- /Server/dll/Sip.Message.dfa: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Server/dll/Sip.Message.dfa -------------------------------------------------------------------------------- /Server/dll/Sip.Message.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Server/dll/Sip.Message.dll -------------------------------------------------------------------------------- /Server/dll/SocketServers.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Server/dll/SocketServers.dll -------------------------------------------------------------------------------- /Setup/WwwFiles.bat: -------------------------------------------------------------------------------- 1 | "C:\Program Files (x86)\WiX Toolset v3.6\bin\heat.exe" dir "..\Server\Www" -var wix.WwwPath -suid -cg WwwFiles -gg -out WwwFiles.wxs -------------------------------------------------------------------------------- /Setup/bannrbmp.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Setup/bannrbmp.bmp -------------------------------------------------------------------------------- /Setup/dlgbmp.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vf1/sipserver/f8f4a389b4779709304f017c21a360bb8bcc8ae5/Setup/dlgbmp.bmp -------------------------------------------------------------------------------- /Tests/LoadTables.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text; 3 | using System.Collections.Generic; 4 | using NUnit.Framework; 5 | using Sip.Server; 6 | using Sip.Message; 7 | using Http.Message; 8 | using SocketServers; 9 | 10 | namespace Test 11 | { 12 | [SetUpFixture] 13 | public class LoadTables 14 | { 15 | [SetUp] 16 | public void SetUp() 17 | { 18 | { 19 | var dfa = new SipMessageReader(); 20 | dfa.LoadTables(@"..\..\..\Server\dll\Sip.Message.dfa"); 21 | dfa.SetDefaultValue(); 22 | dfa.Parse(new byte[] { 0 }, 0, 1); 23 | } 24 | { 25 | HttpMessageReader.LoadTables(@"..\..\..\Server\dll\"); 26 | 27 | var dfa = new HttpMessageReader(); 28 | dfa.SetDefaultValue(); 29 | dfa.Parse(new byte[] { 0 }, 0, 1); 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("TestRtp")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("TestRtp")] 13 | [assembly: AssemblyCopyright("Copyright © 2009")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM componenets. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("92da22f7-832d-4c4b-b295-e434950e7ac3")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /Tests/ProxyServerTU/ConnectionAddressTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Net; 4 | using System.Text; 5 | using System.Threading; 6 | using System.Collections.Generic; 7 | using NUnit.Framework; 8 | using Sip.Tools; 9 | using Sip.Server; 10 | using Sip.Message; 11 | using Base.Message; 12 | using SocketServers; 13 | 14 | namespace Test 15 | { 16 | //[TestFixture] 17 | //class ConnectionAddressTest 18 | //{ 19 | // [Test] 20 | // public void it_should_parse_this_connection_address() 21 | // { 22 | // int transactionId; 23 | // var addresses = ConnectionAddresses.Parse(new ByteArrayPart("020000000313c404d014f60aef2b041e14f60a01000002"), out transactionId); 24 | 25 | // Assert.AreEqual(0x01000002, transactionId); 26 | // Assert.IsTrue(addresses.HasValue); 27 | // Assert.AreEqual("10.246.20.30:61227", addresses.Value.RemoteEndPoint.ToString()); 28 | // Assert.AreEqual("10.246.20.208:5060", addresses.Value.LocalEndPoint.ToString()); 29 | // Assert.AreEqual(Transports.Tcp, addresses.Value.Transport); 30 | // } 31 | //} 32 | } 33 | -------------------------------------------------------------------------------- /Tests/Rtp/DtmfEventMessageTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Rtp; 3 | using Rtp.Payload; 4 | using NUnit.Framework; 5 | 6 | namespace TestRtp 7 | { 8 | [TestFixture] 9 | public class DtmfEventMessageTest 10 | { 11 | [Test] 12 | public void ParseTest1() 13 | { 14 | byte[] bytes1 = new byte[] { 0xff, 0x01, 0x8A, 0x03, 0xC0, }; 15 | 16 | var messages1 = DtmfEventMessage.Parse(bytes1, 1, bytes1.Length); 17 | 18 | Assert.AreEqual(1, messages1.Length); 19 | Assert.AreEqual(1, messages1[0].Event, "Dtmf.Event"); 20 | Assert.AreEqual(true, messages1[0].End, "Dtmf.End"); 21 | Assert.AreEqual(0x0a, messages1[0].Volume, "Dtmf.Volume"); 22 | Assert.AreEqual(0x03c0, messages1[0].Duration, "Dtmf.Duration"); 23 | } 24 | 25 | [Test] 26 | public void ParseTest2() 27 | { 28 | byte[] bytes = new byte[] { 0xff, 0x01, 0x8A, 0x03, 0xC0, 0x02, 0x0B, 0x04, 0xC1, }; 29 | 30 | var messages = DtmfEventMessage.Parse(bytes, 1, bytes.Length); 31 | 32 | Assert.AreEqual(2, messages.Length, "messages.Length"); 33 | 34 | Assert.AreEqual(1, messages[0].Event, "Dtmf.Event"); 35 | Assert.AreEqual(true, messages[0].End, "Dtmf.End"); 36 | Assert.AreEqual(0x0a, messages[0].Volume, "Dtmf.Volume"); 37 | Assert.AreEqual(0x03c0, messages[0].Duration, "Dtmf.Duration"); 38 | 39 | Assert.AreEqual(2, messages[1].Event, "Dtmf.Event"); 40 | Assert.AreEqual(false, messages[1].End, "Dtmf.End"); 41 | Assert.AreEqual(0x0b, messages[1].Volume, "Dtmf.Volume"); 42 | Assert.AreEqual(0x04c1, messages[1].Duration, "Dtmf.Duration"); 43 | } 44 | 45 | [Test] 46 | [ExpectedException(typeof(NotImplementedException))] 47 | public void GetBytesTest() 48 | { 49 | DtmfEventMessage target = new DtmfEventMessage(); // TODO: Initialize to an appropriate value 50 | byte[] bytes = null; // TODO: Initialize to an appropriate value 51 | int startIndex = 0; // TODO: Initialize to an appropriate value 52 | target.GetBytes(bytes, startIndex); 53 | Assert.Inconclusive("A method that does not return a value cannot be verified."); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Tests/Rtp/JitterBufferTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Rtp; 3 | using NUnit.Framework; 4 | 5 | namespace TestRtp 6 | { 7 | [TestFixture] 8 | public class JitterBufferTest 9 | { 10 | RtpMessage message1 = new RtpMessage() { SequenceNumber = 1, }; 11 | RtpMessage message2 = new RtpMessage() { SequenceNumber = 2, }; 12 | RtpMessage message3 = new RtpMessage() { SequenceNumber = 3, }; 13 | 14 | [Test] 15 | public void JitterBufferTest1() 16 | { 17 | JitterBuffer buffer = new JitterBuffer(null); 18 | 19 | buffer.Insert(message1); 20 | buffer.Insert(message1); 21 | buffer.Insert(message2); 22 | buffer.Insert(message2); 23 | buffer.Insert(message3); 24 | buffer.Insert(message3); 25 | 26 | Assert.AreEqual(3, buffer.Count); 27 | Assert.AreEqual((UInt16)1, buffer.DequeueAvailable().SequenceNumber); 28 | Assert.AreEqual((UInt16)2, buffer.DequeueAvailable().SequenceNumber); 29 | Assert.AreEqual((UInt16)3, buffer.DequeueAvailable().SequenceNumber); 30 | Assert.IsNull(buffer.DequeueAvailable()); 31 | } 32 | 33 | [Test] 34 | public void JitterBufferTest2() 35 | { 36 | JitterBuffer buffer = new JitterBuffer(null); 37 | 38 | buffer.Insert(message3); 39 | buffer.Insert(message3); 40 | buffer.Insert(message1); 41 | buffer.Insert(message1); 42 | buffer.Insert(message2); 43 | buffer.Insert(message2); 44 | 45 | Assert.AreEqual(3, buffer.Count); 46 | Assert.AreEqual((UInt16)1, buffer.DequeueAvailable().SequenceNumber); 47 | Assert.AreEqual((UInt16)2, buffer.DequeueAvailable().SequenceNumber); 48 | Assert.AreEqual((UInt16)3, buffer.DequeueAvailable().SequenceNumber); 49 | Assert.IsNull(buffer.DequeueAvailable()); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Tests/Rtp/NtpTimestampTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.NtpTimestamp; 3 | using NUnit.Framework; 4 | 5 | namespace TestRtp 6 | { 7 | [TestFixture] 8 | public class NtpTimestampTest 9 | { 10 | [Test] 11 | public void NtpTimestampTest1() 12 | { 13 | UInt64 timestamp1 = 0xCEA3F33E5D0D5A5BL; 14 | 15 | DateTime actual1 = NtpTimestamp.NtpTimestampToUtcDateTime(timestamp1); 16 | DateTime expected1 = new DateTime(0x08cc3026efdea9a1L); // {10.11.2009 14:12:14.3634849} 17 | 18 | Assert.AreEqual(expected1, actual1); 19 | 20 | 21 | UInt64 timestamp2 = actual1.ToNtpTimestamp(); 22 | 23 | Assert.AreEqual(0xcea3f33e5d0d58ae, timestamp2); 24 | 25 | 26 | UInt64 timestamp3 = (new DateTime(1900, 1, 1)).ToNtpTimestamp(); 27 | UInt64 actual3 = 0; 28 | 29 | Assert.AreEqual(actual3, timestamp3); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Tests/Rtp/SsrcTest.cs: -------------------------------------------------------------------------------- 1 | using Rtp; 2 | using System; 3 | using NUnit.Framework; 4 | 5 | namespace TestRtp 6 | { 7 | [TestFixture] 8 | public class SsrcTest 9 | { 10 | [Test] 11 | public void GetNtpTimestampTest() 12 | { 13 | Ssrc ssrc = new Ssrc(new int[] { 0 }, new int[] { 1 }); 14 | 15 | ssrc.SetBaseTimestamp(0x0000001000000000UL, 0xfffffff0); 16 | 17 | // message's rtp timestamp >= base rtp timestamp 18 | Assert.AreEqual(0x0000001000000000UL, ssrc.GetNtpTimestamp(new RtpMessage() { Timestamp = 0xfffffff0, }, 1)); 19 | Assert.AreEqual(0x0000001100000000UL, ssrc.GetNtpTimestamp(new RtpMessage() { Timestamp = 0xfffffff1, }, 1)); 20 | Assert.AreEqual(0x0000001f00000000UL, ssrc.GetNtpTimestamp(new RtpMessage() { Timestamp = 0xffffffff, }, 1)); 21 | Assert.AreEqual(0x0000002000000000UL, ssrc.GetNtpTimestamp(new RtpMessage() { Timestamp = 0x00000000, }, 1)); 22 | Assert.AreEqual(0x0000002100000000UL, ssrc.GetNtpTimestamp(new RtpMessage() { Timestamp = 0x00000001, }, 1)); 23 | 24 | // message's rtp timestamp < base rtp timestamp 25 | Assert.AreEqual(0x0000000f00000000UL, ssrc.GetNtpTimestamp(new RtpMessage() { Timestamp = 0xffffffef, }, 1)); 26 | Assert.AreEqual(0x0000000000000000UL, ssrc.GetNtpTimestamp(new RtpMessage() { Timestamp = 0xffffffe0, }, 1)); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Tests/ServiceSoap/DirectorySearchRequestTest.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | using System.Xml; 3 | using ServiceSoap.XmlContent; 4 | using NUnit.Framework; 5 | 6 | namespace ServiceSoap 7 | { 8 | [TestFixture] 9 | public class DirectorySearchRequestTest 10 | { 11 | [Test] 12 | public void ParseTest() 13 | { 14 | string xml1 = "100"; 15 | string xml2 = "100"; 16 | 17 | var request1 = DirectorySearchRequest.Parse(CreateXmlReader(xml1)); 18 | 19 | Assert.AreEqual(100, request1.MaxResults); 20 | Assert.AreEqual(3, request1.SearchTerms.Count); 21 | Assert.AreEqual("n", request1.SearchTerms["givenName"]); 22 | Assert.AreEqual("e", request1.SearchTerms["givenEmail"]); 23 | Assert.AreEqual("<>&", request1.SearchTerms["ltgtamp"]); 24 | 25 | var request2 = DirectorySearchRequest.Parse(CreateXmlReader(xml2)); 26 | 27 | Assert.AreEqual(100, request2.MaxResults); 28 | Assert.AreEqual(0, request2.SearchTerms.Count); 29 | } 30 | 31 | public XmlReader CreateXmlReader(string xml) 32 | { 33 | using (MemoryStream stream = new MemoryStream()) 34 | using (StreamWriter writer = new StreamWriter(stream)) 35 | { 36 | writer.Write(xml); 37 | writer.Flush(); 38 | stream.Seek(0, SeekOrigin.Begin); 39 | 40 | return XmlReader.Create(stream); 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Tests/ServiceSoap/Helpers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ServiceSoap 4 | { 5 | static class Helpers 6 | { 7 | public static int GetEqualLength(this string s1, string s2) 8 | { 9 | int i; 10 | for (i = 0; i < s1.Length && i < s2.Length; i++) 11 | { 12 | if (s1[i] != s2[i]) 13 | break; 14 | } 15 | return i; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Tests/Transaction/BaseServerTransactionTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using NUnit.Framework; 6 | using Sip.Server; 7 | using Sip.Message; 8 | using SocketServers; 9 | 10 | namespace Test.Transaction1 11 | { 12 | abstract class BaseServerTransactionTest 13 | : BaseTransactionTest 14 | where T : IServerTransaction, new() 15 | { 16 | protected void EmulateTuEvent(Transaction.States fromState, int startStatus, int endStatus, Transaction.States toState) 17 | { 18 | EmulateTuEvent(true, fromState, startStatus, endStatus, toState); 19 | EmulateTuEvent(false, fromState, startStatus, endStatus, toState); 20 | } 21 | 22 | protected void EmulateTuEvent(bool isTransportUnreliable, Transaction.States fromState, int startStatus, int endStatus, Transaction.States toState) 23 | { 24 | var e = GetServerEventArgs(isTransportUnreliable); 25 | 26 | for (int i = startStatus; i <= endStatus; i++) 27 | { 28 | var transaction = GetTransaction(fromState, isTransportUnreliable); 29 | transaction.ProccessTransactionUser(i, e); 30 | 31 | Assert.AreEqual(toState, transaction.State); 32 | } 33 | } 34 | 35 | } 36 | } 37 | --------------------------------------------------------------------------------