private QualityIndicator ConvertToNamedQuality(VATRPCall call) { var rating = (float)LinphoneAPI.linphone_call_get_current_quality(call.NativeCallPtr); if (rating >= 4.0) { return(QualityIndicator.Good); } if (rating >= 3.0) { return(QualityIndicator.Medium); } if (rating >= 2.0) { return(QualityIndicator.Poor); } if (rating >= 1.0) { return(QualityIndicator.VeryPoor); } if (rating >= 0) { return(QualityIndicator.ToBad); } return(QualityIndicator.Unknown); }
internal int ValidateAddress(string input) { if (string.IsNullOrWhiteSpace(input)) { return(1); } string un, host; int port; if (!VATRPCall.ParseSipAddress(input, out un, out host, out port)) { return(2); } if (!ValidateUsername(un)) { return(3); } if (!ValidateHost(host)) { return(4); } if (port < 0 || port > 65535) { return(5); } return(0); }
internal bool CheckReceiverContact() { //**************************************************************************************** // Check Chat message receiver contact. it should not be null. //***************************************************************************************** var receiver = string.Empty; if (ReceiverAddress != null) { receiver = ReceiverAddress.Trim(); } if (ChatViewContact != null && receiver == ChatViewContact.Contact.RegistrationName) { return(true); } VATRPContact contact = _chatsManager.FindContact(new ContactID(receiver, IntPtr.Zero)); if (contact == null) { string un, host, dn; int port; if (!VATRPCall.ParseSipAddress(receiver, out un, out host, out port)) { un = ""; } if (!un.NotBlank()) { return(false); } if (string.IsNullOrEmpty(host)) { host = App.CurrentAccount.ProxyHostname; } var contactAddress = string.Format("{0}@{1}", un, host); var contactID = new ContactID(contactAddress, IntPtr.Zero); contact = new VATRPContact(contactID) { DisplayName = un, Fullname = un, SipUsername = un, RegistrationName = contactAddress }; _contactsManager.AddContact(contact, ""); } SetActiveChatContact(contact, IntPtr.Zero); if (ReceiverAddress != contact.RegistrationName) { ReceiverAddress = contact.RegistrationName; } return(true); }
private void LoadProviders() { var providersList = ServiceManager.Instance.ProviderService.GetProviderListFullInfo(); providersList.Sort((a, b) => String.Compare(a.Label, b.Label, StringComparison.Ordinal)); string un, domain; int port; VATRPCall.ParseSipAddress(_contactSipUsername, out un, out domain, out port); ProviderViewModel selectedProvider = null; foreach (var s in providersList) { if (s.Label == "_nologo") { continue; } var providerModel = new ProviderViewModel(s); Providers.Add(providerModel); if (s.Address == domain && domain.NotBlank()) { selectedProvider = providerModel; } if (App.CurrentAccount != null && s.Address == App.CurrentAccount.ProxyHostname) { _currentProvider = providerModel; } } var nlp = ServiceManager.Instance.ProviderService.FindProviderLooseSearch("_nologo"); if (nlp != null) { _nologoProvider = new ProviderViewModel(nlp); } if (selectedProvider == null) { if (_currentProvider == null) { _currentProvider = _nologoProvider; } _contactInitialSipHost = string.Empty; } if (_isAddMode) { SelectedProvider = selectedProvider ?? _currentProvider; } else { if (selectedProvider == null) { _contactInitialSipHost = domain; } SelectedProvider = selectedProvider ?? _nologoProvider; } }
private void LogCallData(VATRPCall call) //cjm-aug17 { if (App.CurrentAccount.EnableTechCallLog) { if (call != null && CurrentState != call.CallState) { if (CurrentState == VATRPCallState.None) { _LOG.Info("=========================================================================\n" + " Call Started \n" + "========================================================================="); } DateTime time = DateTime.Now; string formattedTime = time.ToString(); CurrentState = call.CallState; string data = String.Empty; data = "Date : {0}\n" + "Call State : {1}\n" + "Audio Codec : {2}\n" + "Video Codec : {3}\n" + "SIP Port : {4}\n" + "RTP Port : {5}\n" + "Receiving FPS : {6}\n" + "Sending FPS : {7}\n" + "Download Bandwidth : {8}\n" + "Upload Bandwidth : {9}\n" + "ICE Setup : {10}\n" + "Media Encryption : {11}\n" + "Call Quality : {12}\n" + "Receiving Video Resolution : {13}\n" + "Sending Video Resolution : {14}\n" + "AVPF Enabled : {15}\n" + "Video Packet Loss Sending : {16}\n" + "Video Packet Loss Receiving : {17}\n" + "Audio Packet Loss Sending : {18}\n" + "Audio Packet Loss Receiving : {19}\n" + "Video Packet Late : {20}\n" + "Audio Packet Late : {21}\n" + "Video Interarrival Jitter Sending : {22}\n" + "Video Interarrival Jitter Receiving : {23}\n" + "Audio Interarrival Jitter Sending : {24}\n" + "Audio Interarrival Jitter Receiving : {25}\n"; _LOG.Info(String.Format(data, formattedTime, CurrentState, AudioCodec, VideoCodec, SipPort, RtpPort, ReceivingFPS, SendingFPS, DownloadBandwidth, UploadBandwidth, IceSetup, MediaEncryption, CallQuality, ReceivingVideoResolution, SendingVideoResolution, AVPFEnabled, VideoPacketLossSending, VideoPacketLossReceiving, AudioPacketLossSending, AudioPacketLossReceiving, VideoPacketLate, AudioPacketLate, VideoInterarrivalJitterSending, VideoInterarrivalJitterReceiving, AudioInterarrivalJitterSending, AudioInterarrivalJitterReceiving)); } } }
internal void OnCallStatisticsChanged(VATRPCall call) { //**************************************************************************************************************************************** // When anything related to call is changed like mute mic etc. Then this method will called. Or a message is sent from chat. //**************************************************************************************************************************************** if (ServiceManager.Instance.Dispatcher.Thread != Thread.CurrentThread) { ServiceManager.Instance.Dispatcher.BeginInvoke((Action)(() => this.OnCallStatisticsChanged(call))); return; } //Console.WriteLine("OnCallStatisticsChanged"); UpdateCallInfo(call); }
/// <summary> /// Method to import contacts from local machine. Prompts /// user to select a contacts file from the computer. Then /// it parses the file & stores the contacts. /// </summary> /// <returns>void</returns> private void ExecuteLocalImport() { var openDlg = new OpenFileDialog() { CheckFileExists = true, CheckPathExists = true, Filter = "xCard Files (*.xml, *.xml)|*.xml;*xml", FilterIndex = 0, ShowReadOnly = false, }; if (openDlg.ShowDialog() != true) { return; } if (ServiceManager.Instance.LinphoneService.VCardSupported) { // System.Windows.Forms.MessageBox.Show("ExecuteImportCommand Path" + openDlg.FileName); var recordsImported = ServiceManager.Instance.ContactService.ImportVCards(openDlg.FileName); } else { var cardReader = new vCardReader(openDlg.FileName); string un, host; int port; foreach (var card in cardReader.vCards) { var remoteParty = card.Title.TrimSipPrefix(); var contact = ServiceManager.Instance.ContactService.FindContact(new ContactID(remoteParty, IntPtr.Zero)); if (contact != null && contact.Fullname == card.FormattedName) { continue; } VATRPCall.ParseSipAddress(remoteParty, out un, out host, out port); if ((App.CurrentAccount != null && App.CurrentAccount.ProxyHostname != host) || App.CurrentAccount == null) { un = remoteParty; } ServiceManager.Instance.ContactService.AddLinphoneContact(card.FormattedName, un, remoteParty); } } }
internal CallViewModel FindCallViewModel(VATRPCall call) { if (call == null) { return(null); } lock (CallsViewModelList) { foreach (var callVM in CallsViewModelList) { if (callVM.Equals(call)) { return(callVM); } } } return(null); }
public InfoEventArgs(VATRPCall call) : base(call) { }
protected InfoEventBaseArgs(VATRPCall call) { ActiveCall = call; }
internal void UpdateCallInfo(VATRPCall call) { //********************************************************************************************************************************* // When anything related to call is changed or when call is running then this method is called. //********************************************************************************************************************************* if (call == null || call.CallState != VATRPCallState.StreamsRunning) { LogCallData(call); // cjm-aug17 ResetCallInfoView(); return; } ServiceManager.Instance.LinphoneService.LockCalls(); ServiceManager.Instance.LinphoneService.GetCallAudioStats(call.NativeCallPtr, ref _audioStats); ServiceManager.Instance.LinphoneService.GetCallVideoStats(call.NativeCallPtr, ref _videoStats); IntPtr curparams = ServiceManager.Instance.LinphoneService.GetCallParams(call.NativeCallPtr); if (curparams != IntPtr.Zero) { int sipPort, rtpPort; ServiceManager.Instance.LinphoneService.GetUsedPorts(out sipPort, out rtpPort); SipPort = sipPort; RtpPort = rtpPort; bool has_video = LinphoneAPI.linphone_call_params_video_enabled(curparams) == 1; MSVideoSizeDef size_received = LinphoneAPI.linphone_call_params_get_received_video_size(curparams); MSVideoSizeDef size_sent = LinphoneAPI.linphone_call_params_get_sent_video_size(curparams); IntPtr rtp_profile = LinphoneAPI.linphone_call_params_get_rtp_profile(curparams); if (rtp_profile != IntPtr.Zero) { RtpProfile = Marshal.PtrToStringAnsi(rtp_profile); } AudioCodec = ServiceManager.Instance.LinphoneService.GetUsedAudioCodec(curparams); int avpf_mode = ServiceManager.Instance.LinphoneService.GetAVPFMode(); if (avpf_mode == 0) { AVPFEnabled = false; } else if (avpf_mode == 1) { AVPFEnabled = true; } var videoCodecName = ServiceManager.Instance.LinphoneService.GetUsedVideoCodec(curparams); //Console.WriteLine("videoCodecName " + videoCodecName); if (has_video && !string.IsNullOrWhiteSpace(videoCodecName)) { VideoCodec = videoCodecName; UploadBandwidth = string.Format("{0:0.##} kbit/s a {1:0.##} kbit/s v {2:0.##} kbit/s", _audioStats.upload_bandwidth + _videoStats.upload_bandwidth, _audioStats.upload_bandwidth, _videoStats.upload_bandwidth); DownloadBandwidth = string.Format("{0:0.##} kbit/s a {1:0.##} kbit/s v {2:0.##} kbit/s", _audioStats.download_bandwidth + _videoStats.download_bandwidth, _audioStats.download_bandwidth, _videoStats.download_bandwidth); ReceivingFPS = ServiceManager.Instance.LinphoneService.GetFrameRate(curparams, false); SendingFPS = ServiceManager.Instance.LinphoneService.GetFrameRate(curparams, true); // System.Diagnostics.Debug.WriteLine(ReceivingFPS.ToString(), SendingFPS.ToString()); var vs = ServiceManager.Instance.LinphoneService.GetVideoSize(curparams, false); ReceivingVideoResolution = string.Format("{0}({1}x{2})", "", vs.width, vs.height); vs = ServiceManager.Instance.LinphoneService.GetVideoSize(curparams, true); SendingVideoResolution = string.Format("{0}({1}x{2})", "", vs.width, vs.height); } else { VideoCodec = "Not used"; ReceivingFPS = 0; SendingFPS = 0; UploadBandwidth = string.Format("a {0:0.##} kbit/s", _audioStats.upload_bandwidth); DownloadBandwidth = string.Format("a {0:0.##} kbit/s", _audioStats.download_bandwidth); ReceivingVideoResolution = "N/A"; SendingVideoResolution = "N/A"; } switch ((LinphoneIceState)_audioStats.ice_state) { case LinphoneIceState.LinphoneIceStateNotActivated: IceSetup = "Not Activated"; break; case LinphoneIceState.LinphoneIceStateFailed: IceSetup = "Failed"; break; case LinphoneIceState.LinphoneIceStateInProgress: IceSetup = "In Progress"; break; case LinphoneIceState.LinphoneIceStateHostConnection: IceSetup = "Connected directly"; break; case LinphoneIceState.LinphoneIceStateReflexiveConnection: IceSetup = "Connected through NAT"; break; case LinphoneIceState.LinphoneIceStateRelayConnection: IceSetup = "Connected through a relay"; break; } switch (ServiceManager.Instance.LinphoneService.GetMediaEncryption(curparams)) { case LinphoneMediaEncryption.LinphoneMediaEncryptionNone: MediaEncryption = "None"; break; case LinphoneMediaEncryption.LinphoneMediaEncryptionSRTP: MediaEncryption = "SRTP"; break; case LinphoneMediaEncryption.LinphoneMediaEncryptionZRTP: MediaEncryption = "ZRTP"; break; case LinphoneMediaEncryption.LinphoneMediaEncryptionDTLS: MediaEncryption = "DTLS"; break; } var curQuality = ConvertToNamedQuality(call); if (CallQuality != curQuality) { CallQuality = curQuality; if (CallQualityChangedEvent != null) { CallQualityChangedEvent(curQuality); } } AudioPacketLossSending = "Sending " + _audioStats.sender_loss_rate; AudioPacketLossReceiving = "Receiving " + _audioStats.receiver_loss_rate; AudioPacketLate = _audioStats.total_late_packets.ToString(); AudioInterarrivalJitterSending = "Sending " + _audioStats.sender_interarrival_jitter; AudioInterarrivalJitterReceiving = "Receiving " + _audioStats.receiver_interarrival_jitter; VideoPacketLossSending = "Sending " + _videoStats.sender_loss_rate; VideoPacketLossReceiving = "Receiving " + _audioStats.receiver_loss_rate; VideoPacketLate = _videoStats.total_late_packets.ToString(); VideoInterarrivalJitterSending = "Sending " + _audioStats.sender_interarrival_jitter; VideoInterarrivalJitterReceiving = "Receiving " + _audioStats.receiver_interarrival_jitter; } ServiceManager.Instance.LinphoneService.UnlockCalls(); LogCallData(call); // cjm-aug17 }
public CameraMuteEventArgs(VATRPCall call, bool muted) : base(call) { IsMuted = muted; }
private VATRPCallEvent ParseLinphoneCallLog(IntPtr callLogPtr) { LinphoneCallDir direction = LinphoneAPI.linphone_call_log_get_dir(callLogPtr); IntPtr tmpPtr = LinphoneAPI.linphone_call_log_get_remote_address(callLogPtr); if (tmpPtr == IntPtr.Zero) { return(null); } // 4/11 MITRE-fjr Throws Exception, Added Catch try { tmpPtr = LinphoneAPI.linphone_address_as_string(tmpPtr); // 4/11 try ?? LinphoneAddress _linphoneAddress = LinphoneAPI.linphone_address_as_string(tmpPtr); if (tmpPtr == IntPtr.Zero) { return(null); } } catch (Exception ex) { Console.Write(ex.InnerException); return(null); } var remoteParty = Marshal.PtrToStringAnsi(tmpPtr); LinphoneAPI.ortp_free(tmpPtr); string dn = "", un = "", host = ""; int port = 0; VATRPCall.ParseSipAddressEx(remoteParty, out dn, out un, out host, out port); if (string.IsNullOrEmpty(un)) { return(null); } remoteParty = port == 0 ? string.Format("sip:{0}@{1}", un, host) : string.Format("sip:{0}@{1}:{2}", un, host, port); var callevent = new VATRPCallEvent("", remoteParty) { DisplayName = dn, Username = un }; tmpPtr = LinphoneAPI.linphone_call_log_get_call_id(callLogPtr); if (tmpPtr != IntPtr.Zero) { callevent.CallGuid = Marshal.PtrToStringAnsi(tmpPtr); } callevent.StartTime = new DateTime(1970, 1, 1).AddSeconds(LinphoneAPI.linphone_call_log_get_start_date(callLogPtr)); callevent.EndTime = callevent.StartTime.AddSeconds( Convert.ToInt32(LinphoneAPI.linphone_call_log_get_duration(callLogPtr))); switch (LinphoneAPI.linphone_call_log_get_status(callLogPtr)) { case LinphoneCallStatus.LinphoneCallSuccess: { callevent.Status = direction == LinphoneCallDir.LinphoneCallIncoming ? VATRPHistoryEvent.StatusType.Incoming : VATRPHistoryEvent.StatusType.Outgoing; } break; case LinphoneCallStatus.LinphoneCallAborted: callevent.Status = VATRPHistoryEvent.StatusType.Failed; break; case LinphoneCallStatus.LinphoneCallDeclined: callevent.Status = VATRPHistoryEvent.StatusType.Rejected; break; case LinphoneCallStatus.LinphoneCallMissed: callevent.Status = VATRPHistoryEvent.StatusType.Missed; break; } return(callevent); }
/// <summary> /// Configures the client for placing phone calls and validates user input. /// </summary> /// <remarks> /// Remote URI Format: sip:[email protected] /// </remarks> /// <param name="remoteUri"> The SIP URI the call is being placed to.</param> /// <returns>True if the call was placed successfully.</returns> internal static bool MakeVideoCall(string remoteUri) { string dialPadPhonePattern = @"^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\/]?(\d+))?$"; string pattern = @"[ \-\s\t\n\r\(\)\*\#\+\.]*"; string replacement = ""; Regex rgx = new Regex(pattern); Regex dialPadPhoneCheckRgx = new Regex(dialPadPhonePattern); //string result = rgx.Replace(remoteUri, replacement); Match match = dialPadPhoneCheckRgx.Match(remoteUri); if (match.Success) { string result = rgx.Replace(remoteUri, replacement); // Perserving the leading 1 if there is one: // /* * if (result.Length > 10 && result[0] == '1') * result = result.Remove(0, 1);*/ remoteUri = result; } //******************************** Maake Video Call ********************************************************************************************** // This method is called when user tap on call button on dial pad. or When user select the Contact from Contact list (All/Favorites) // It will called only when there is a valid number entered for a call (After validation) //************************************************************************************************************************************************* ILinphoneService _linphoneService = ServiceManager.Instance.LinphoneService; if (!_linphoneService.CanMakeVideoCall()) { MessageBox.Show("Video call not supported yet.", "VATRP", MessageBoxButton.OK, MessageBoxImage.Warning); return(false); } if (MainWindow.RegistrationState != LinphoneRegistrationState.LinphoneRegistrationOk) { MessageBox.Show("Not Registered. Please register first", "VATRP", MessageBoxButton.OK, MessageBoxImage.Error); return(false); } // VATRP-2506, 2496: check to see if there is currently a call in progress. IF there is a call in progress, prevent // an outgoing call. int callCount = ServiceManager.Instance.LinphoneService.GetActiveCallsCount; // It checks if user already connected a call. if yes then it returns false. if (callCount > 0) { return(false); // i think this can be a quiet failure - the user is already in a call. } bool muteMicrophone = false; bool muteSpeaker = false; bool enableVideo = true; bool enableAudio = true; if (App.CurrentAccount != null) { muteMicrophone = App.CurrentAccount.MuteMicrophone; muteSpeaker = App.CurrentAccount.MuteSpeaker; enableVideo = App.CurrentAccount.VideoAutomaticallyStart; enableAudio = App.CurrentAccount.AudioAutomaticallyStart; } var target = string.Empty; string un, host; int port; VATRPCall.ParseSipAddress(remoteUri, out un, out host, out port); if (!host.NotBlank()) { // set proxy to selected provider // find selected provider host var provider = ServiceManager.Instance.ProviderService.FindProviderLooseSearch( ServiceManager.Instance.ConfigurationService.Get(Configuration.ConfSection.GENERAL, Configuration.ConfEntry.CURRENT_PROVIDER, "")); //Use dial-around provider if selected if (!string.IsNullOrEmpty(App.CurrentAccount?.DialAroundProviderAddress)) { target = string.Format("sip:{0}@{1}", un, App.CurrentAccount.DialAroundProviderAddress); } else if (provider != null) { target = string.Format("sip:{0}@{1}", un, provider.Address); } else if (App.CurrentAccount != null) { target = string.Format("sip:{0}@{1}", un, App.CurrentAccount.ProxyHostname); } } else { if (!string.IsNullOrEmpty(App.CurrentAccount?.DialAroundProviderAddress)) { target = string.Format("sip:{0}@{1}", un, App.CurrentAccount.DialAroundProviderAddress); } else { target = string.Format("sip:{0}@{1}:{2}", un, host, port); } } if (!App.CurrentAccount.DisableUserPhoneTag) { // https://www.twilio.com/docs/glossary/what-e164 // https://en.wikipedia.org/wiki/E.164 Regex rE164 = new Regex(@"^(\+|00)?[1-9]\d{4,14}$"); bool isE164 = rE164.IsMatch(un); if (isE164) { target += ";user=phone"; } else { target += ";user=dialstring"; } } var privacyMask = VATRP.Core.Enums.LinphonePrivacy.LinphonePrivacyDefault; if (App.CurrentAccount.EnablePrivacy) { privacyMask = VATRP.Core.Enums.LinphonePrivacy.LinphonePrivacySession; } // update video policy settings prior to making a call _linphoneService.MakeCall(target, /* destination */ true, /* videoOn */ ServiceManager.Instance.ConfigurationService.Get(Configuration.ConfSection.GENERAL, Configuration.ConfEntry.USE_RTT, true), /* rttEnabled */ muteMicrophone, /* muteMicrophone */ muteSpeaker, /* muteSpeaker */ enableVideo, /* enableVideo */ enableAudio, App.CurrentAccount.GeolocationURI, /* geolocation */ privacyMask); /* privacyMask */ return(true); }
internal void UpdateContactAddress(bool changeProvider) { string un, host; int port; if (VATRPCall.ParseSipAddress(_contactSipUsername, out un, out host, out port)) { if (changeProvider) { if (_selectedProvider != null) { if (_selectedProvider == _nologoProvider) { ContactSipUsername = port == 0 ? String.Format("{0}@{1}", un, _contactInitialSipHost) : String.Format("{0}@{1}:{2}", un, _contactInitialSipHost, port); } else { ContactSipUsername = port == 0 ? String.Format("{0}@{1}", un, _selectedProvider.Provider.Address) : String.Format("{0}@{1}:{2}", un, _selectedProvider.Provider.Address, port); } } else { ContactSipUsername = port == 0 ? String.Format("{0}@{1}", un, _contactInitialSipHost) : String.Format("{0}@{1}:{2}", un, _contactInitialSipHost, port); } } else { if (_selectedProvider != null) { if (host != _selectedProvider.Provider.Address && string.IsNullOrEmpty(host)) { ContactSipUsername = port == 0 ? String.Format("{0}@{1}", un, _selectedProvider.Provider.Address) : String.Format("{0}@{1}:{2}", un, _selectedProvider.Provider.Address, port); } } else { ContactSipUsername = port == 0 ? String.Format("{0}@{1}", un, host) : String.Format("{0}@{1}:{2}", un, host, port); } } } }