private Customer AuthoriseRequest() { try { string authId = GetAuthId(); //logger.Debug("Authorising request for sessionid=" + authId + "."); if (authId != null) { CustomerSession customerSession = CRMSessionManager.Authenticate(authId); if (customerSession == null) { logger.Warn("SIPProvisioningWebService AuthoriseRequest failed for " + authId + "."); throw new UnauthorizedAccessException(); } else { Customer customer = CRMCustomerPersistor.Get(c => c.CustomerUsername == customerSession.CustomerUsername); return(customer); } } else { logger.Warn("SIPProvisioningWebService AuthoriseRequest failed no authid header."); throw new UnauthorizedAccessException(); } } catch (UnauthorizedAccessException) { throw; } catch (Exception excp) { logger.Error("Exception AuthoriseRequest. " + excp.Message); throw new Exception("There was an exception authorising the request."); } }
private SIPRegistrarBinding GetNextExpiredBinding(DateTimeOffset expiryTime) { using (var trans = new TransactionScope()) { SIPRegistrarBinding binding = m_bindingsPersistor.Get(b => b.ExpiryTime < expiryTime); if (binding != null) { if (binding.ExpiryTime < DateTimeOffset.UtcNow.AddSeconds(BINDING_EXPIRY_GRACE_PERIOD * -1)) { m_bindingsPersistor.Delete(binding); } else { logger.Warn("A binding returned from the database as expired wasn't. " + binding.SIPAccountName + " and " + binding.MangledContactURI + ", last register " + binding.LastUpdate.ToString("HH:mm:ss") + ", expiry " + binding.Expiry + ", expiry time " + binding.ExpiryTime.ToString("HH:mm:ss") + ", checkedtime " + expiryTime.ToString("HH:mm:ss") + ", now " + DateTimeOffset.UtcNow.ToString("HH:mm:ss") + "."); binding = null; } } trans.Complete(); return(binding); } }
public CustomerSession Authenticate(string sessionId) { try { CustomerSession customerSession = m_customerSessionPersistor.Get(s => s.SessionID == sessionId && !s.Expired); //CustomerSession customerSession = m_customerSessionPersistor.Get(s => s.Id == sessionId); if (customerSession != null) { int sessionLengthMinutes = (int)DateTimeOffset.UtcNow.Subtract(customerSession.Inserted).TotalMinutes; //logger.Debug("CustomerSession Inserted=" + customerSession.Inserted.ToString("o") + ", session length=" + sessionLengthMinutes + "mins."); if (sessionLengthMinutes > customerSession.TimeLimitMinutes || sessionLengthMinutes > CustomerSession.MAX_SESSION_LIFETIME_MINUTES) { customerSession.Expired = true; m_customerSessionPersistor.Update(customerSession); return(null); } else { //logger.Debug("Authentication token valid for " + sessionId + "."); return(customerSession); } } else { logger.Warn("Authentication token invalid for " + sessionId + "."); return(null); } } catch (Exception excp) { logger.Error("Exception Authenticate CustomerSessionManager. " + excp.Message); throw; } }
public List <SIPProviderBinding> GetSIPProviderBindings(string whereExpression, int offset, int count) { Customer customer = AuthoriseRequest(); string authoriseExpression = GetAuthorisedWhereExpression(customer, whereExpression); if (authoriseExpression.IsNullOrBlank()) { return(SIPProviderBindingsPersistor.Get(null, "providername asc", offset, count)); } else { return(SIPProviderBindingsPersistor.Get(DynamicExpression.ParseLambda <SIPProviderBinding, bool>(authoriseExpression), "providername asc", offset, count)); } }
public CustomerSession Authenticate(string username, string password, string ipAddress) { try { if (username.IsNullOrBlank() || password.IsNullOrBlank()) { logger.Debug("Login failed, either username or password was not specified."); return(null); } else { logger.Debug("CustomerSessionManager authenticate requested for username " + username + " from " + ipAddress + "."); // Don't do the password check via the database as different ones have different string case matching. Customer customer = m_customerPersistor.Get(c => c.CustomerUsername == username); if (customer != null && PasswordHash.Hash(password, customer.Salt) == customer.CustomerPassword) { if (!customer.EmailAddressConfirmed) { throw new ApplicationException("Your email address has not yet been confirmed."); } else if (customer.Suspended) { throw new ApplicationException("Your account is suspended."); } else { logger.Debug("Login successful for " + username + "."); string sessionId = Crypto.GetRandomByteString(SESSION_ID_STRING_LENGTH / 2); CustomerSession customerSession = new CustomerSession(Guid.NewGuid(), sessionId, customer.CustomerUsername, ipAddress); m_customerSessionPersistor.Add(customerSession); return(customerSession); } } else { logger.Debug("Login failed for " + username + "."); return(null); } } } catch (Exception excp) { logger.Error("Exception Authenticate CustomerSessionManager. " + excp.Message); throw; } }
public List <SIPProvider> GetSIPProviders(string whereExpression, int offset, int count) { Customer customer = AuthoriseRequest(); string authoriseExpression = GetAuthorisedWhereExpression(customer, whereExpression); if (authoriseExpression.IsNullOrBlank()) { return(SIPProviderPersistor.Get(null, "providername", offset, count)); } else { //logger.Debug("SIPProvisioningWebService GetSIPProviders for " + customerSession.Customer.CustomerUsername + " and where: " + authoriseExpression + "."); return(SIPProviderPersistor.Get(DynamicExpression.ParseLambda <SIPProvider, bool>(authoriseExpression), "providername", offset, count)); } }
public void Read() { SipAccountDataStorage = SIPAssetPersistorFactory <SIPAccount> .CreateSIPAssetPersistor(m_storageType, m_connStr, m_XMLFilename); SipAccountDataStorage.Added += Account_Added; _sipAccountsCache = SipAccountDataStorage.Get(); }
public void Read() { SIPAssetPersistor <SIPAccount> account = SIPAssetPersistorFactory <SIPAccount> .CreateSIPAssetPersistor(m_storageType, m_connStr, m_XMLFilename); _sipAccount = account; _accounts = account.Get(); }
private void LoadSIPDomains() { try { List <SIPDomain> sipDomains = m_sipDomainPersistor.Get(null, null, 0, Int32.MaxValue); //if (sipDomains == null || sipDomains.Count == 0) //{ // throw new ApplicationException("No SIP domains could be loaded from the persistence store. There needs to be at least one domain."); //} //else //{ m_domains.Clear(); foreach (SIPDomain sipDomain in sipDomains) { AddDomain(sipDomain); } //} } catch (Exception excp) { logger.Error("Exception LoadSIPDomains. " + excp.Message); throw; } }
public void SIPProviderUpdated(SIPProvider sipProvider) { try { Logger.Logger.Debug("SIPProviderBindingSynchroniser SIPProviderUpdated for " + sipProvider.Owner + " and " + sipProvider.ProviderName + "."); SIPProviderBinding existingBinding = m_bindingPersistor.Get(b => b.ProviderId == sipProvider.Id); if (sipProvider.RegisterEnabled) { if (existingBinding == null) { SIPProviderBinding newBinding = new SIPProviderBinding(sipProvider); m_bindingPersistor.Add(newBinding); } else { existingBinding.SetProviderFields(sipProvider); existingBinding.NextRegistrationTime = DateTime.UtcNow; m_bindingPersistor.Update(existingBinding); } } else { if (existingBinding != null) { if (existingBinding.IsRegistered) { // Let the registration agent know the existing binding should be expired. existingBinding.BindingExpiry = 0; existingBinding.NextRegistrationTime = DateTime.UtcNow; m_bindingPersistor.Update(existingBinding); } else { m_bindingPersistor.Delete(existingBinding); } } } } catch (Exception excp) { Logger.Logger.Error("Exception SIPProviderBindingSynchroniser SIPProviderUpdated. ->" + excp.Message); } }
protected Customer AuthoriseRequest() { try { string authId = ServiceAuthToken.GetAuthId(); //logger.Debug("Authorising request for sessionid=" + authId + "."); if (!authId.IsNullOrBlank()) { CustomerSession customerSession = CRMSessionManager.Authenticate(authId); if (customerSession == null) { logger.Warn("SIPSorceryAuthenticatedService AuthoriseRequest failed for " + authId + "."); throw new UnauthorizedAccessException(); } else { Customer customer = CRMCustomerPersistor.Get(c => c.CustomerUsername == customerSession.CustomerUsername); return(customer); } } else { string apiKey = ServiceAuthToken.GetAPIKey(); if (!apiKey.IsNullOrBlank()) { Customer customer = CRMCustomerPersistor.Get(c => c.APIKey == apiKey); return(customer); } else { logger.Warn("SIPSorceryAuthenticatedService AuthoriseRequest failed no authid header."); throw new UnauthorizedAccessException(); } } } catch (UnauthorizedAccessException) { throw; } catch (Exception excp) { logger.Error("Exception AuthoriseRequest. " + excp.Message); throw new Exception("There was an exception authorising the request."); } }
protected void Page_Load(object sender, EventArgs e) { try { logger.Debug("CustomerEmailConfirmation request from " + this.Context.Request.UserHostAddress + " for " + this.Request.QueryString["id"] + "."); string id = this.Request.QueryString["id"]; if (!id.IsNullOrBlank()) { Guid customerId = new Guid(id); m_crmPersistor = SIPAssetPersistorFactory <Customer> .CreateSIPAssetPersistor(m_crmStorageType, m_crmStorageConnStr, null); Customer customer = m_crmPersistor.Get(customerId); if (customer != null) { if (!customer.EmailAddressConfirmed) { customer.CreatedFromIPAddress = this.Context.Request.UserHostAddress; customer.EmailAddressConfirmed = true; if (IsValidCustomer(m_validationRules, customer)) { m_crmPersistor.Update(customer); m_confirmed = true; m_confirmMessage.Text = "Thank you, your account has now been activated."; } else { customer.Suspended = true; m_crmPersistor.Update(customer); m_confirmed = false; m_confirmMessage.Text = "Your account has been confirmed but not approved. You will receive an email within 48 hours if it is approved."; } } else { m_confirmed = false; m_confirmMessage.Text = "Your account has already been confirmed."; } } else { m_confirmMessage.Text = "No matching customer record could be found. Please check that you entered the confirmation URL correctly."; } } else { m_confirmMessage.Text = "Your account could not be confirmed. Please check that you entered the confirmation URL correctly."; } } catch (Exception excp) { logger.Error("Exception CustomerEmailConfirmation. " + excp.Message); m_confirmMessage.Text = "There was an error confirming your account. Please check that you entered the confirmation URL correctly."; } }
public List <SIPDialogueAsset> GetCalls(string whereExpression, int offset, int count) { try { Customer customer = AuthoriseRequest(); string authorisedExpression = GetAuthorisedWhereExpression(customer, whereExpression); //logger.Debug("SIPProvisioningWebService GetCalls for " + customerSession.Customer.CustomerUsername + " and where: " + authoriseExpression + "."); if (authorisedExpression.IsNullOrBlank()) { return(SIPDialoguePersistor.Get(null, null, offset, count)); } else { return(SIPDialoguePersistor.Get(DynamicExpression.ParseLambda <SIPDialogueAsset, bool>(authorisedExpression), null, offset, count)); } } catch (Exception excp) { logger.Error("Exception GetCalls. " + excp.Message); throw; } }
protected void Page_Load(object sender, EventArgs e) { try { logger.Debug("CustomerEmailConfirmation request from " + this.Context.Request.UserHostAddress + " for " + this.Request.QueryString["id"] + "."); string id = this.Request.QueryString["id"]; if (!id.IsNullOrBlank()) { Guid customerId = new Guid(id); m_crmPersistor = SIPAssetPersistorFactory<Customer>.CreateSIPAssetPersistor(m_crmStorageType, m_crmStorageConnStr, null); Customer customer = m_crmPersistor.Get(customerId); if (customer != null) { if (!customer.EmailAddressConfirmed) { customer.CreatedFromIPAddress = this.Context.Request.UserHostAddress; customer.EmailAddressConfirmed = true; if (IsValidCustomer(m_validationRules, customer)) { m_crmPersistor.Update(customer); m_confirmed = true; m_confirmMessage.Text = "Thank you, your account has now been activated."; } else { customer.Suspended = true; m_crmPersistor.Update(customer); m_confirmed = false; m_confirmMessage.Text = "Your account has been confirmed but not approved. You will receive an email within 48 hours if it is approved."; } } else { m_confirmed = false; m_confirmMessage.Text = "Your account has already been confirmed."; } } else { m_confirmMessage.Text = "No matching customer record could be found. Please check that you entered the confirmation URL correctly."; } } else { m_confirmMessage.Text = "Your account could not be confirmed. Please check that you entered the confirmation URL correctly."; } } catch (Exception excp) { logger.Error("Exception CustomerEmailConfirmation. " + excp.Message); m_confirmMessage.Text = "There was an error confirming your account. Please check that you entered the confirmation URL correctly."; } }
public List <SIPRegistrarBinding> GetRegistrarRecords(string owner, int offset, int count) { try { if (owner != null && owner.Trim().Length > 0) { return(SIPRegistrarBindingPersistor.Get(b => b.Owner == owner, "lastupdate", offset, count)); } else { logger.Warn("GetRegistrarRecords was called with an empty owner."); return(null); } } catch (Exception excp) { logger.Error("Exception GetRegistrarRecords. " + excp.Message); throw excp; } }
private void LoadSIPDomains() { try { var sipDomainList = m_sipDomainPersistor.Get(null, null, 0, Int32.MaxValue); if (sipDomainList == null || sipDomainList.Count == 0) { throw new ApplicationException("No SIP domains could be loaded from the persistence store. There needs to be at least one domain."); } else { m_domains.Clear(); sipDomainList.ForEach(sipDomain => AddDomain(sipDomain)); } } catch (Exception excp) { logger.Error("Exception LoadSIPDomains. " + excp.Message); throw; } }
/// <summary> /// 加载设备信息 /// </summary> public void Read() { SIPAssetPersistor <NvrItem> nvrItem = SIPAssetPersistorFactory <NvrItem> .CreateSIPAssetPersistor(m_storageType, m_connStr, m_XMLFilename); SIPAssetPersistor <ChannelItem> nvrChannel = SIPAssetPersistorFactory <ChannelItem> .CreateSIPAssetPersistor(m_storageType, m_connStr, m_XMLFilename); NvrItems = nvrItem; ChannelItems = nvrChannel; _nvrItems = nvrItem.Get(); var nvrChannelItems = nvrChannel.Get(); foreach (var item in _nvrItems) { foreach (var channel in nvrChannelItems) { if (item.NvrID == channel.NvrID) { item.Add(channel); } } } }
private void Subscribe(SIPTransaction subscribeTransaction) { try { SIPRequest sipRequest = subscribeTransaction.TransactionRequest; string fromUser = sipRequest.Header.From.FromURI.User; string fromHost = sipRequest.Header.From.FromURI.Host; string canonicalDomain = GetCanonicalDomain_External(fromHost, true); if (canonicalDomain == null) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Warn, "Subscribe request for " + fromHost + " rejected as no matching domain found.", null)); SIPResponse noDomainResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, "Domain not serviced"); subscribeTransaction.SendFinalResponse(noDomainResponse); return; } SIPAccount sipAccount = m_sipAssetPersistor.Get(s => s.SIPUsername == fromUser && s.SIPDomain == canonicalDomain); SIPRequestAuthenticationResult authenticationResult = SIPRequestAuthenticator_External(subscribeTransaction.LocalSIPEndPoint, subscribeTransaction.RemoteEndPoint, sipRequest, sipAccount, FireProxyLogEvent); if (!authenticationResult.Authenticated) { // 401 Response with a fresh nonce needs to be sent. SIPResponse authReqdResponse = SIPTransport.GetResponse(sipRequest, authenticationResult.ErrorResponse, null); authReqdResponse.Header.AuthenticationHeader = authenticationResult.AuthenticationRequiredHeader; subscribeTransaction.SendFinalResponse(authReqdResponse); if (authenticationResult.ErrorResponse == SIPResponseStatusCodesEnum.Forbidden) { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Warn, "Forbidden " + fromUser + "@" + canonicalDomain + " does not exist, " + sipRequest.Header.ProxyReceivedFrom.ToString() + ", " + sipRequest.Header.UserAgent + ".", null)); } else { FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAuth, "Authentication required for " + fromUser + "@" + canonicalDomain + " from " + subscribeTransaction.RemoteEndPoint + ".", sipAccount.Owner)); } return; } else { if (sipRequest.Header.To.ToTag != null) { // Request is to renew an existing subscription. SIPResponseStatusCodesEnum errorResponse = SIPResponseStatusCodesEnum.None; string errorResponseReason = null; string sessionID = m_subscriptionsManager.RenewSubscription(sipRequest, out errorResponse, out errorResponseReason); if (errorResponse != SIPResponseStatusCodesEnum.None) { // A subscription renewal attempt failed SIPResponse renewalErrorResponse = SIPTransport.GetResponse(sipRequest, errorResponse, errorResponseReason); subscribeTransaction.SendFinalResponse(renewalErrorResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeFailed, "Subscription renewal failed for event type " + sipRequest.Header.Event + " " + sipRequest.URI.ToString() + ", " + errorResponse + " " + errorResponseReason + ".", sipAccount.Owner)); } else if (sipRequest.Header.Expires == 0) { // Existing subscription was closed. SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); subscribeTransaction.SendFinalResponse(okResponse); } else { // Existing subscription was found. SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); subscribeTransaction.SendFinalResponse(okResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeRenew, "Subscription renewal for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + " and expiry " + sipRequest.Header.Expires + ".", sipAccount.Owner)); m_subscriptionsManager.SendFullStateNotify(sessionID); } } else { // Authenticated but the this is a new subscription request and authorisation to subscribe to the requested resource also needs to be checked. SIPURI canonicalResourceURI = sipRequest.URI.CopyOf(); string resourceCanonicalDomain = GetCanonicalDomain_External(canonicalResourceURI.Host, true); canonicalResourceURI.Host = resourceCanonicalDomain; SIPAccount resourceSIPAccount = null; if (resourceCanonicalDomain == null) { SIPResponse notFoundResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotFound, "Domain " + resourceCanonicalDomain + " not serviced"); subscribeTransaction.SendFinalResponse(notFoundResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeFailed, "Subscription failed for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + ", domain not serviced.", sipAccount.Owner)); return; } if (canonicalResourceURI.User != m_wildcardUser) { resourceSIPAccount = m_sipAssetPersistor.Get(s => s.SIPUsername == canonicalResourceURI.User && s.SIPDomain == canonicalResourceURI.Host); if (resourceSIPAccount == null) { SIPResponse notFoundResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.NotFound, "Requested resource does not exist"); subscribeTransaction.SendFinalResponse(notFoundResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeFailed, "Subscription failed for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + ", SIP account does not exist.", sipAccount.Owner)); return; } } // Check the owner permissions on the requesting and subscribed resources. bool authorised = false; string adminID = null; if (canonicalResourceURI.User == m_wildcardUser || sipAccount.Owner == resourceSIPAccount.Owner) { authorised = true; FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAuth, "Subscription to " + canonicalResourceURI.ToString() + " authorised due to common owner.", sipAccount.Owner)); } else { // Lookup the customer record for the requestor and check the administrative level on it. Customer requestingCustomer = GetCustomer_External(c => c.CustomerUsername == sipAccount.Owner); adminID = requestingCustomer.AdminId; if (!resourceSIPAccount.AdminMemberId.IsNullOrBlank() && requestingCustomer.AdminId == resourceSIPAccount.AdminMemberId) { authorised = true; FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAuth, "Subscription to " + canonicalResourceURI.ToString() + " authorised due to requestor admin permissions for domain " + resourceSIPAccount.AdminMemberId + ".", sipAccount.Owner)); } else if (requestingCustomer.AdminId == m_topLevelAdminID) { authorised = true; FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAuth, "Subscription to " + canonicalResourceURI.ToString() + " authorised due to requestor having top level admin permissions.", sipAccount.Owner)); } } if (authorised) { // Request is to create a new subscription. SIPResponseStatusCodesEnum errorResponse = SIPResponseStatusCodesEnum.None; string errorResponseReason = null; string toTag = CallProperties.CreateNewTag(); string sessionID = m_subscriptionsManager.SubscribeClient(sipAccount.Owner, adminID, sipRequest, toTag, canonicalResourceURI, out errorResponse, out errorResponseReason); if (errorResponse != SIPResponseStatusCodesEnum.None) { SIPResponse subscribeErrorResponse = SIPTransport.GetResponse(sipRequest, errorResponse, errorResponseReason); subscribeTransaction.SendFinalResponse(subscribeErrorResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAccept, "Subscription failed for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + ", " + errorResponse + " " + errorResponseReason + ".", sipAccount.Owner)); } else { SIPResponse okResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Ok, null); okResponse.Header.To.ToTag = toTag; okResponse.Header.Expires = sipRequest.Header.Expires; okResponse.Header.Contact = new List <SIPContactHeader>() { new SIPContactHeader(null, new SIPURI(SIPSchemesEnum.sip, subscribeTransaction.LocalSIPEndPoint)) }; subscribeTransaction.SendFinalResponse(okResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAccept, "Subscription accepted for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + " and expiry " + sipRequest.Header.Expires + ".", sipAccount.Owner)); if (sessionID != null) { m_subscriptionsManager.SendFullStateNotify(sessionID); } } } else { SIPResponse forbiddenResponse = SIPTransport.GetResponse(sipRequest, SIPResponseStatusCodesEnum.Forbidden, "Requested resource not authorised"); subscribeTransaction.SendFinalResponse(forbiddenResponse); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeFailed, "Subscription failed for " + sipRequest.URI.ToString() + ", event type " + sipRequest.Header.Event + ", requesting account " + sipAccount.Owner + " was not authorised.", sipAccount.Owner)); } } } } catch (Exception excp) { logger.Error("Exception notifiercore subscribing. " + excp.Message + "\r\n" + subscribeTransaction.TransactionRequest.ToString()); FireProxyLogEvent(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.Error, "Exception notifiercore subscribing. " + excp.Message, null)); SIPResponse errorResponse = SIPTransport.GetResponse(subscribeTransaction.TransactionRequest, SIPResponseStatusCodesEnum.InternalServerError, null); subscribeTransaction.SendFinalResponse(errorResponse); } }
/// <summary> /// Establishes a new call with the client end tied to the proxy. Since the proxy will not be sending any audio the idea is that once /// the call is up it should be re-INVITED off somewhere else pronto to avoid the callee sitting their listening to dead air. /// </summary> /// <param name="dest1">The dial string of the first call to place.</param> /// <param name="dest2">The dial string of the second call to place.</param> /// <param name="delaySeconds">Delay in seconds before placing the first call. Gives the user a chance to hangup their phone if they are calling themselves back.</param> /// <param name="ringTimeoutLeg1">The ring timeout for the first call leg, If 0 the max timeout will be used.</param> /// <param name="ringTimeoutLeg1">The ring timeout for the second call leg, If 0 the max timeout will be used.</param> /// <param name="customHeadersCallLeg1">A | delimited string that contains a list of custom SIP headers to add to the INVITE request sent for the first call leg.</param> /// /// <param name="customHeadersCallLeg2">A | delimited string that contains a list of custom SIP headers to add to the INVITE request sent for the second call leg.</param> /// <returns>The result of the call.</returns> public void Callback(string dest1, string dest2, int delaySeconds, int ringTimeoutLeg1, int ringTimeoutLeg2, string customHeadersCallLeg1, string customHeadersCallLeg2) { var ts = new CancellationTokenSource(); CancellationToken ct = ts.Token; try { if (delaySeconds > 0) { delaySeconds = (delaySeconds > MAXCALLBACK_DELAY_SECONDS) ? MAXCALLBACK_DELAY_SECONDS : delaySeconds; Log("Callback app delaying by " + delaySeconds + "s."); Thread.Sleep(delaySeconds * 1000); } Log("Callback app commencing first leg to " + dest1 + "."); SIPEndPoint defaultUDPEP = m_sipTransport.GetDefaultSIPEndPoint(SIPProtocolsEnum.udp); SIPRequest firstLegDummyInviteRequest = GetCallbackInviteRequest(defaultUDPEP.GetIPEndPoint(), null); ForkCall firstLegCall = new ForkCall(m_sipTransport, Log_External, m_callManager.QueueNewCall, null, m_username, m_adminMemberId, m_outboundProxy, m_callManager, null); m_firstLegDialogue = Dial(firstLegCall, dest1, ringTimeoutLeg1, 0, firstLegDummyInviteRequest, SIPCallDescriptor.ParseCustomHeaders(customHeadersCallLeg1)); if (m_firstLegDialogue == null) { Log("The first call leg to " + dest1 + " was unsuccessful."); return; } // Persist the dialogue to the database so any hangup can be detected. m_sipDialoguePersistor.Add(new SIPDialogueAsset(m_firstLegDialogue)); SDP firstLegSDP = SDP.ParseSDPDescription(m_firstLegDialogue.RemoteSDP); string call1SDPIPAddress = firstLegSDP.Connection.ConnectionAddress; int call1SDPPort = firstLegSDP.Media[0].Port; Log("The first call leg to " + dest1 + " was successful, audio socket=" + call1SDPIPAddress + ":" + call1SDPPort + "."); Log("Callback app commencing second leg to " + dest2 + "."); SIPRequest secondLegDummyInviteRequest = GetCallbackInviteRequest(defaultUDPEP.GetIPEndPoint(), m_firstLegDialogue.RemoteSDP); ForkCall secondLegCall = new ForkCall(m_sipTransport, Log_External, m_callManager.QueueNewCall, null, m_username, m_adminMemberId, m_outboundProxy, m_callManager, null); Task.Factory.StartNew(() => { while (true) { Thread.Sleep(CHECK_FIRST_LEG_FOR_HANGUP_PERIOD); Console.WriteLine("Checking if first call leg is still up..."); if (ct.IsCancellationRequested) { Console.WriteLine("Checking first call leg task was cancelled."); break; } else { // Check that the first call leg hasn't been hung up. var dialog = m_sipDialoguePersistor.Get(m_firstLegDialogue.Id); if (dialog == null) { Console.WriteLine("First call leg has been hungup."); // The first call leg has been hungup while waiting for the second call. Log("The first call leg was hungup while the second call leg was waiting for an answer."); secondLegCall.CancelNotRequiredCallLegs(CallCancelCause.ClientCancelled); break; } } } Console.WriteLine("Checking first call leg task finished..."); }, ct); SIPDialogue secondLegDialogue = Dial(secondLegCall, dest2, ringTimeoutLeg2, 0, secondLegDummyInviteRequest, SIPCallDescriptor.ParseCustomHeaders(customHeadersCallLeg2)); ts.Cancel(); if (secondLegDialogue == null) { Log("The second call leg to " + dest2 + " was unsuccessful."); m_firstLegDialogue.Hangup(m_sipTransport, m_outboundProxy); return; } // Check that the first call leg hasn't been hung up. var firstLegDialog = m_sipDialoguePersistor.Get(m_firstLegDialogue.Id); if (firstLegDialog == null) { // The first call leg has been hungup while waiting for the second call. Log("The first call leg was hungup while waiting for the second call leg."); secondLegDialogue.Hangup(m_sipTransport, m_outboundProxy); return; } SDP secondLegSDP = SDP.ParseSDPDescription(secondLegDialogue.RemoteSDP); string call2SDPIPAddress = secondLegSDP.Connection.ConnectionAddress; int call2SDPPort = secondLegSDP.Media[0].Port; Log("The second call leg to " + dest2 + " was successful, audio socket=" + call2SDPIPAddress + ":" + call2SDPPort + "."); // Persist the second leg dialogue and update the bridge ID on the first call leg. Guid bridgeId = Guid.NewGuid(); secondLegDialogue.BridgeId = bridgeId; m_sipDialoguePersistor.Add(new SIPDialogueAsset(secondLegDialogue)); m_sipDialoguePersistor.UpdateProperty(firstLegDialog.Id, "BridgeID", bridgeId.ToString()); //m_callManager.CreateDialogueBridge(m_firstLegDialogue, secondLegDialogue, m_username); Log("Re-inviting Callback dialogues to each other."); m_callManager.ReInvite(m_firstLegDialogue, secondLegDialogue); //m_callManager.ReInvite(secondLegDialogue, m_firstLegDialogue.RemoteSDP); SendRTPPacket(call2SDPIPAddress + ":" + call2SDPPort, call1SDPIPAddress + ":" + call1SDPPort); SendRTPPacket(call1SDPIPAddress + ":" + call1SDPPort, call2SDPIPAddress + ":" + call2SDPPort); } catch (Exception excp) { logger.Error("Exception CallbackApp. " + excp); Log("Exception in Callback. " + excp); } finally { if (!ts.IsCancellationRequested) { ts.Cancel(); } } }
/// <summary> /// Monitors the CDRs table for records that are using real-time call control and are within the limit that requires them to /// re-reserve credit. /// </summary> private void MonitorCDRs() { try { Thread.CurrentThread.Name = RTCC_THREAD_NAME; logger.Debug("RTCC Core Starting Monitor CDRs thread."); while (!m_exit) { using (var db = new SIPSorceryEntities()) { try { // Try and reserve credit on in progress calls. DateTime reservationDue = DateTime.Now.AddSeconds(m_reserveDueSeconds); var rtccReservationDue = (from rtcc in db.RTCCs1.Include("cdr") where rtcc.AccountCode != null && rtcc.SecondsReserved != null && rtcc.SecondsReserved > 0 && rtcc.ReservationError == null && rtcc.ReconciliationResult == null && rtcc.cdr.HungupTime == null && rtcc.cdr.AnsweredAt != null && rtcc.cdr.AnsweredStatus >= 200 && rtcc.cdr.AnsweredStatus <= 299 && EntityFunctions.AddSeconds(rtcc.cdr.AnsweredAt, rtcc.SecondsReserved) <= reservationDue orderby rtcc.cdr.AnsweredAt select rtcc).Take(NUMBER_CDRS_PER_ROUNDTRIP); while (rtccReservationDue.Count() > 0) { foreach (RTCC rtcc in rtccReservationDue) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.RTCC, SIPMonitorEventTypesEnum.DialPlan, "Reserving credit for call " + rtcc.cdr.Dst + ".", rtcc.cdr.Owner)); // Attempt to re-reserve the next chunk of credit for the call. m_customerAccountDataLayer.ReserveCredit(m_reservationAmountSeconds, rtcc.ID); } } } //catch (ReflectionTypeLoadException ex) //{ // StringBuilder sb = new StringBuilder(); // foreach (Exception exSub in ex.LoaderExceptions) // { // sb.AppendLine(exSub.Message); // if (exSub is FileNotFoundException) // { // FileNotFoundException exFileNotFound = exSub as FileNotFoundException; // if (!string.IsNullOrEmpty(exFileNotFound.FusionLog)) // { // sb.AppendLine("Fusion Log:"); // sb.AppendLine(exFileNotFound.FusionLog); // } // } // sb.AppendLine(); // } // string errorMessage = sb.ToString(); // logger.Error(errorMessage); //} catch (Exception monitorExcp) { logger.Error("Exception MonitorCDRs Credit Reservation. " + monitorExcp); logger.Error("InnerException MonitorCDRs Credit Reservation. " + monitorExcp.InnerException); } try { // Terminate any calls that have reached their time limit. DateTime now = DateTime.Now; var rtccTerminationDue = (from rtcc in db.RTCCs1.Include("cdr") where !rtcc.IsHangingUp && rtcc.AccountCode != null && rtcc.cdr.HungupTime == null && rtcc.cdr.AnsweredAt != null && rtcc.SecondsReserved != null && rtcc.cdr.AnsweredStatus >= 200 && rtcc.cdr.AnsweredStatus <= 299 && EntityFunctions.AddSeconds(rtcc.cdr.AnsweredAt, rtcc.SecondsReserved) <= now && !rtcc.IsHangingUp && rtcc.ReconciliationResult == null orderby rtcc.cdr.AnsweredAt select rtcc).Take(NUMBER_CDRS_PER_ROUNDTRIP); while (rtccTerminationDue.Count() > 0) { foreach (RTCC rtcc in rtccTerminationDue) { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.RTCC, SIPMonitorEventTypesEnum.DialPlan, "Terminating call due to reservation limit being reached " + rtcc.cdr.Dst + ".", rtcc.cdr.Owner)); m_customerAccountDataLayer.SetCDRIsHangingUp(rtcc.ID); var dialogue = m_sipDialoguePersistor.Get(x => x.CDRId == rtcc.CDRID, null, 0, 1).FirstOrDefault(); if (dialogue != null) { m_sipDialogueManager.CallHungup(dialogue.SIPDialogue, "RTCC time limit reached", true); } else { Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.RTCC, SIPMonitorEventTypesEnum.Warn, "A dialogue could not be found when terminating a call due to reservation limit being reached.", rtcc.cdr.Owner)); } } } } catch (Exception monitorExcp) { logger.Error("Exception RTCCCore MonitorCDRs Call Termination. " + monitorExcp.Message); } } Thread.Sleep(1000); } logger.Warn("RTCCCore MonitorCDRs thread stopping."); } catch (Exception excp) { logger.Error("Exception RTCCCore MonitorCDRs. " + excp.Message); } }
public string SubscribeClient( string owner, string adminID, SIPRequest subscribeRequest, string toTag, SIPURI canonicalResourceURI, out SIPResponseStatusCodesEnum errorResponse, out string errorReason) { try { errorResponse = SIPResponseStatusCodesEnum.None; errorReason = null; SIPURI resourceURI = subscribeRequest.URI.CopyOf(); SIPEventPackage eventPackage = SIPEventPackage.Parse(subscribeRequest.Header.Event); int expiry = subscribeRequest.Header.Expires; if (!(eventPackage == SIPEventPackage.Dialog || eventPackage == SIPEventPackage.Presence)) { throw new ApplicationException("Event package " + eventPackage.ToString() + " is not supported by the subscriptions manager."); } else { if (expiry > 0) { string subscribeError = null; string sessionID = Guid.NewGuid().ToString(); SIPDialogue subscribeDialogue = new SIPDialogue(subscribeRequest, owner, adminID, toTag); if (eventPackage == SIPEventPackage.Dialog) { string monitorFilter = "dialog " + canonicalResourceURI.ToString(); if (!subscribeRequest.Body.IsNullOrBlank()) { monitorFilter += " and " + subscribeRequest.Body; } m_publisher.Subscribe(owner, adminID, m_notificationsAddress, sessionID, SIPMonitorClientTypesEnum.Machine.ToString(), monitorFilter, expiry, null, out subscribeError); if (subscribeError != null) { throw new ApplicationException(subscribeError); } else { GetSIPDialogueDelegate getSipDialogue = (id) => { return(GetDialogue_External(id).SIPDialogue); }; GetDialoguesForOwnerDelegate getSipDialoguesForOwner = (ownr, offset, limit) => { return(GetDialogues_External(x => x.Owner == owner, "Inserted", offset, limit).Select(x => x.SIPDialogue).ToList <SIPDialogue>()); }; GetRemoteDialogueForBridgeDelegate getSIPDialogueForBridge = (bridgeID, localDialogueID) => { return(GetDialogues_External(d => d.BridgeId == bridgeID.ToString() && d.Id != localDialogueID, null, 0, 1).Select(x => x.SIPDialogue).FirstOrDefault()); }; SIPDialogEventSubscription subscription = new SIPDialogEventSubscription(MonitorLogEvent_External, sessionID, resourceURI, canonicalResourceURI, monitorFilter, subscribeDialogue, expiry, getSipDialoguesForOwner, getSIPDialogueForBridge, getSipDialogue); m_subscriptions.Add(sessionID, subscription); MonitorLogEvent_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAccept, "New dialog subscription created for " + resourceURI.ToString() + ", expiry " + expiry + "s.", owner)); } } else if (eventPackage == SIPEventPackage.Presence) { string monitorFilter = "presence " + canonicalResourceURI.ToString(); m_publisher.Subscribe(owner, adminID, m_notificationsAddress, sessionID, SIPMonitorClientTypesEnum.Machine.ToString(), monitorFilter, expiry, null, out subscribeError); if (subscribeError != null) { throw new ApplicationException(subscribeError); } else { bool switchboardAccountsOnly = subscribeRequest.Body == SIPPresenceEventSubscription.SWITCHBOARD_FILTER; SIPRegistrarBindingsCountDelegate getRegistrarBindingsCount = (sipAccountID) => { return(GetSIPRegistrarBindingsCount_External(x => x.SIPAccountId == sipAccountID)); }; GetSIPAccountsForUserDelegate getSIPAccountsForUser = (username, domain, offset, limit) => { return(m_sipAssetPersistor.Get(x => x.SIPUsername == username && x.SIPDomain == domain, "SIPUsername", offset, limit).Select(y => y.SIPAccount).ToList()); }; GetSIPAccountsForOwnerDelegate getSIPAccountsForOwner = (accountOwner, offset, limit) => { return(m_sipAssetPersistor.Get(x => x.Owner == accountOwner, "SIPUsername", offset, limit).Select(y => y.SIPAccount).ToList()); }; SIPPresenceEventSubscription subscription = new SIPPresenceEventSubscription(MonitorLogEvent_External, sessionID, resourceURI, canonicalResourceURI, monitorFilter, subscribeDialogue, expiry, getSIPAccountsForUser, getSIPAccountsForOwner, m_sipAssetPersistor.GetProperty, getRegistrarBindingsCount, switchboardAccountsOnly); m_subscriptions.Add(sessionID, subscription); MonitorLogEvent_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.Notifier, SIPMonitorEventTypesEnum.SubscribeAccept, "New presence subscription created for " + resourceURI.ToString() + ", expiry " + expiry + "s.", owner)); } } return(sessionID); } return(null); } } catch (Exception excp) { logger.Error("Exception NotifierSubscriptionsManager SubscribeClient. " + excp.Message); throw; } }
public void CreateCustomer(Customer customer) { try { if (m_inviteCodeRequired && customer.InviteCode == null) { throw new ApplicationException("Sorry new account creations currently require an invite code, please see http://sipsorcery.wordpress.com/new-accounts/."); } else if (m_newCustomersAllowedLimit != 0 && CRMCustomerPersistor.Count(null) >= m_newCustomersAllowedLimit) { // Check whether the number of customers is within the allowed limit. throw new ApplicationException("Sorry new account creations are currently disabled, please see http://sipsorcery.wordpress.com/new-accounts/."); } else { // Check whether the username is already taken. customer.CustomerUsername = customer.CustomerUsername.ToLower(); Customer existingCustomer = CRMCustomerPersistor.Get(c => c.CustomerUsername == customer.CustomerUsername); if (existingCustomer != null) { throw new ApplicationException("The requested username is already in use please try a different one."); } // Check whether the email address is already taken. customer.EmailAddress = customer.EmailAddress.ToLower(); existingCustomer = CRMCustomerPersistor.Get(c => c.EmailAddress == customer.EmailAddress); if (existingCustomer != null) { throw new ApplicationException("The email address is already associated with an account."); } string validationError = Customer.ValidateAndClean(customer); if (validationError != null) { throw new ApplicationException(validationError); } customer.MaxExecutionCount = Customer.DEFAULT_MAXIMUM_EXECUTION_COUNT; customer.APIKey = Crypto.GetRandomByteString(Customer.API_KEY_LENGTH / 2); CRMCustomerPersistor.Add(customer); logger.Debug("New customer record added for " + customer.CustomerUsername + "."); // Create a default dialplan. SIPDialPlan defaultDialPlan = new SIPDialPlan(customer.CustomerUsername, "default", null, "sys.Log(\"hello world\")\n", SIPDialPlanScriptTypesEnum.Ruby); DialPlanPersistor.Add(defaultDialPlan); logger.Debug("Default dialplan added for " + customer.CustomerUsername + "."); // Get default domain name. string defaultDomain = SIPDomainManager.GetDomain("local", true); // Create SIP account. if (SIPAccountPersistor.Get(s => s.SIPUsername == customer.CustomerUsername && s.SIPDomain == defaultDomain) == null) { SIPAccount sipAccount = new SIPAccount(customer.CustomerUsername, defaultDomain, customer.CustomerUsername, customer.CustomerPassword, "default"); SIPAccountPersistor.Add(sipAccount); logger.Debug("SIP account " + sipAccount.SIPUsername + "@" + sipAccount.SIPDomain + " added for " + sipAccount.Owner + "."); } else { int attempts = 0; while (attempts < 10) { string testUsername = customer.CustomerUsername + Crypto.GetRandomString(4); if (SIPAccountPersistor.Get(s => s.SIPUsername == testUsername && s.SIPDomain == defaultDomain) == null) { SIPAccount sipAccount = new SIPAccount(customer.CustomerUsername, defaultDomain, testUsername, customer.CustomerPassword, "default"); SIPAccountPersistor.Add(sipAccount); logger.Debug("SIP account " + sipAccount.SIPUsername + "@" + sipAccount.SIPDomain + " added for " + sipAccount.Owner + "."); break; } else { attempts++; } } } if (!m_customerConfirmLink.IsNullOrBlank()) { logger.Debug("Sending new account confirmation email to " + customer.EmailAddress + "."); SIPSorcerySMTP.SendEmail(customer.EmailAddress, NEW_ACCOUNT_EMAIL_FROM_ADDRESS, NEW_ACCOUNT_EMAIL_SUBJECT, String.Format(NEW_ACCOUNT_EMAIL_BODY, customer.FirstName, m_customerConfirmLink, customer.Id)); } else { logger.Debug("Customer confirmation email was not sent as no confirmation link has been set."); } } } catch (Exception excp) { logger.Error("Exception CreateNewCustomer. " + excp.Message); throw; } }