/// <summary>
        /// Adds or updates matching bindings.
        /// </summary>
        /// <param name="flow">SIP data flow what updates this binding. This value is null if binding was not added through network or
        /// flow has disposed.</param>
        /// <param name="callID">Call-ID header field value.</param>
        /// <param name="cseqNo">CSeq header field sequence number value.</param>
        /// <param name="contacts">Contacts to add or update.</param>
        /// <exception cref="ArgumentNullException">Is raised when <b>callID</b> or <b>contacts</b> is null reference.</exception>
        public void AddOrUpdateBindings(SIP_Flow flow,string callID,int cseqNo,SIP_t_ContactParam[] contacts)
        {
            if(callID == null){
                throw new ArgumentNullException("callID");
            }
            if(cseqNo < 0){
                throw new ArgumentException("Argument 'cseqNo' value must be >= 0.");
            }
            if(contacts == null){
                throw new ArgumentNullException("contacts");
            }

            lock(m_pLock){
                foreach(SIP_t_ContactParam contact in contacts){
                    SIP_RegistrationBinding binding = GetBinding(contact.Address.Uri);
                    // Add binding.
                    if(binding == null){
                        binding = new SIP_RegistrationBinding(this,contact.Address.Uri);
                        m_pBindings.Add(binding);
                    }

                    // Update binding.
                    binding.Update(
                        flow,
                        contact.Expires == -1 ? 3600 : contact.Expires,
                        contact.QValue == -1 ? 1.0 : contact.QValue,
                        callID,
                        cseqNo
                    );
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// Refreshes specified registration info.
        /// </summary>
        public void Refresh()
        {
            /* GetSipRegistration "<virtualServerID>" "<addressOfRecord>"
                  Responses:
                    +OK <sizeOfData>
                    <data>
                    
                    -ERR <errorText>
            */

            lock(m_pOwner.VirtualServer.Server.LockSynchronizer){
                m_pOwner.VirtualServer.Server.TcpClient.TcpStream.WriteLine("GetSipRegistration " + 
                    TextUtils.QuoteString(m_pOwner.VirtualServer.VirtualServerID) + " " +
                    TextUtils.QuoteString(m_AddressOfRecord)
                );

                string response = m_pOwner.VirtualServer.Server.ReadLine();
                if(!response.ToUpper().StartsWith("+OK")){
                    throw new Exception(response);
                }

                int sizeOfData = Convert.ToInt32(response.Split(new char[]{' '},2)[1]);
                MemoryStream ms = new MemoryStream();
                m_pOwner.VirtualServer.Server.TcpClient.TcpStream.ReadFixedCount(ms,sizeOfData);
                
                // Decompress dataset
                DataSet ds = Utils.DecompressDataSet(ms);
             
                if(ds.Tables.Contains("Contacts")){
                    List<SipRegistrationContact> contacts = new List<SipRegistrationContact>();
                    foreach(DataRow dr in ds.Tables["Contacts"].Rows){
                        SIP_t_ContactParam c = new SIP_t_ContactParam();
                        c.Parse(new LumiSoft.Net.StringReader(dr["Value"].ToString()));
                        contacts.Add(new SipRegistrationContact(c.Address.Uri.Value,c.Expires,c.QValue));
                    }
                    m_pContacts = contacts.ToArray();
                }
                else{
                    m_pContacts = new SipRegistrationContact[0];
                }
            }
        }
        /// <summary>
        /// Gets server events and binds them to this.
        /// </summary>
        private void Bind()
        {
            /* GetSipRegistrations "<virtualServerID>"
                  Responses:
                    +OK <sizeOfData>
                    <data>

                    -ERR <errorText>
            */

            lock(m_pOwner.Server.LockSynchronizer){
                m_pOwner.Server.Socket.WriteLine("GetSipRegistrations " +
                    TextUtils.QuoteString(m_pOwner.VirtualServerID)
                );

                string response = m_pOwner.Server.Socket.ReadLine();
                if(!response.ToUpper().StartsWith("+OK")){
                    throw new Exception(response);
                }

                int sizeOfData = Convert.ToInt32(response.Split(new char[]{' '},2)[1]);
                MemoryStream ms = new MemoryStream();
                m_pOwner.Server.Socket.ReadSpecifiedLength(sizeOfData,ms);

                // Decompress dataset
                DataSet ds = Utils.DecompressDataSet(ms);

                if(ds.Tables.Contains("SipRegistrations")){
                    foreach(DataRow dr in ds.Tables["SipRegistrations"].Rows){
                        //--- Parse contact -------------------------------------------------------------//
                        List<SipRegistrationContact> contacts = new List<SipRegistrationContact>();
                        foreach(string contact in dr["Contacts"].ToString().Split('\t')){
                            if(!string.IsNullOrEmpty(contact)){
                                SIP_t_ContactParam c = new SIP_t_ContactParam();
                                c.Parse(new LumiSoft.Net.StringReader(contact));
                                contacts.Add(new SipRegistrationContact(c.Address.Uri,c.Expires,c.QValue));
                            }
                        }
                        //--------------------------------------------------------------------------------//

                        m_pRegistrations.Add(new SipRegistration(
                            this,
                            dr["UserName"].ToString(),
                            dr["AddressOfRecord"].ToString(),
                            contacts.ToArray()
                        ));
                    }
                }
            }
        }
        /// <summary>
        /// Converts <b>ContactUri</b> to valid Contact header value.
        /// </summary>
        /// <returns>Returns contact header value.</returns>
        public string ToContactValue()
        {
            SIP_t_ContactParam retVal = new SIP_t_ContactParam();
            retVal.Parse(new StringReader(m_ContactURI.ToString()));
            retVal.Expires = m_Expires;

            return retVal.ToStringValue();
        }
        /// <summary>
        /// Add or updates specified SIP registration info.
        /// </summary>
        /// <param name="aor">Registration address of record.</param>
        /// <param name="contacts">Registration address of record contacts to update.</param>
        /// <param name="flow">SIP proxy local data flow what accpeted this contact registration.</param>
        public void SetRegistration(string aor,SIP_t_ContactParam[] contacts,SIP_Flow flow)
        {
            lock(m_pRegistrations){
                SIP_Registration registration = m_pRegistrations[aor];
                if(registration == null){
                    registration = new SIP_Registration("system",aor);
                    m_pRegistrations.Add(registration);
                    OnAorRegistered(registration);
                }

                registration.AddOrUpdateBindings(flow,"",1,contacts);
            }
        }
 /// <summary>
 /// Add or updates specified SIP registration info.
 /// </summary>
 /// <param name="aor">Registration address of record.</param>
 /// <param name="contacts">Registration address of record contacts to update.</param>
 public void SetRegistration(string aor,SIP_t_ContactParam[] contacts)
 {
     SetRegistration(aor,contacts,null);
 }
Exemple #7
0
        /// <summary>
        /// Redirects incoming call to speified contact(s).
        /// </summary>
        /// <param name="contacts">Redirection targets.</param>
        /// <exception cref="ObjectDisposedException">Is raised when this object is disposed and and this method is accessed.</exception>
        /// <exception cref="InvalidOperationException">Is raised when call is not in valid state and this method is called.</exception>
        /// <exception cref="ArgumentNullException">Is raised when <b>contacts</b> is null.</exception>
        /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception>
        public void Redirect(SIP_t_ContactParam[] contacts)
        {
            lock(m_pLock){
                if(this.State == SIP_UA_CallState.Disposed){                
                    throw new ObjectDisposedException(this.GetType().Name);
                }
                if(this.State != SIP_UA_CallState.WaitingToAccept){
                    throw new InvalidOperationException("Call is not in valid state.");
                }
                if(contacts == null){
                    throw new ArgumentNullException("contacts");
                }
                if(contacts.Length == 0){
                    throw new ArgumentException("Arguments 'contacts' must contain at least 1 value.");
                }

                // TODO:
                //m_pUA.Stack.CreateResponse(SIP_ResponseCodes.,m_pInitialInviteTransaction);

                throw new NotImplementedException();
            }
        }
        /// <summary>
        /// Updates registration contacts.
        /// </summary>
        /// <param name="contacts">SIP contacts to add/update.</param>
        /// <param name="expires">This is register request header field Expires: value and used only if contact doesn't have expires parameter.</param>
        /// <param name="minExpires">SIP server minimum expire time in seconds.</param>
        /// <param name="localEP">SIP proxy local end point info what accpeted this contact registration.</param>
        public void UpdateContacts(SIP_t_ContactParam[] contacts,int expires,int minExpires,SIP_EndPointInfo localEP)
        {
            lock(m_pContacts){
                foreach(SIP_t_ContactParam contact in contacts){
                    // Handle special value STAR Contact:, this means that we need to remove all contacts.
                    if(contact.IsStarContact){
                        m_pContacts.Clear();
                        return;
                    }

                    SIP_RegistrationContact currentContact = GetContact(contact.Address.Uri);

                    // Get contact expire time.
                    int contactExpires = contact.Expires;
                    if(contactExpires == -1){
                        contactExpires = expires;
                    }
                    if(contactExpires == -1){
                        contactExpires = minExpires;
                    }

                    // Remove specified contact
                    if(contactExpires == 0){
                        if(currentContact != null){
                            m_pContacts.Remove(currentContact);
                        }
                    }
                    // Add
                    else if(currentContact == null){
                        m_pContacts.Add(new SIP_RegistrationContact(contact,contactExpires,localEP));
                    }
                    // Update
                    else{
                        currentContact.UpdateContact(contact,contactExpires,localEP);
                    }
                }
            }
        }
        private void SetSipRegistration(string argsText)
        {
            /* SetSipRegistration "<virtualServerID>" "<addressOfRecord>" "<contacts>"
                  Responses:
                    +OK                    
                    -ERR <errorText>
            */

            try{
                string[] args = TextUtils.SplitQuotedString(argsText,' ',true);
                if(args.Length != 3){
                    WriteLine("-ERR Invalid arguments. Syntax: SetSipRegistration \"<virtualServerID>\" \"<addressOfRecord>\" \"<contacts>\"");
                    return;
                }
                
                foreach(VirtualServer virtualServer in this.Server.MailServer.VirtualServers){
                    if(virtualServer.ID.ToLower() == args[0].ToLower()){
                        List<SIP_t_ContactParam> contacts = new List<SIP_t_ContactParam>();
                        foreach(string contact in args[2].Split('\t')){
                            if(contact.Length > 0){
                                SIP_t_ContactParam c = new SIP_t_ContactParam();
                                c.Parse(new LumiSoft.Net.StringReader(contact));
                                contacts.Add(c);
                            }
                        }
                        
                        virtualServer.SipServer.Registrar.SetRegistration(args[1],contacts.ToArray());
                        
                        WriteLine("+OK");
                        return;
                    }                    
                }

                WriteLine("-ERR Specified virtual server with ID '" + argsText + "' doesn't exist !");                
            }
            catch(Exception x){
                WriteLine("-ERR " + x.Message);
            }
        }
 /// <summary>
 /// Default constructor.
 /// </summary>
 /// <param name="contact">SIP contact.</param>
 /// <param name="expires">Time in seconds when contact expires.</param>
 /// <param name="localEP">SIP proxy local end point info what accpeted this contact registration.</param>
 public SIP_RegistrationContact(SIP_t_ContactParam contact,int expires,SIP_EndPointInfo localEP)
 {
     UpdateContact(contact,expires,localEP);
 }
 /// <summary>
 /// Updates contact info.
 /// </summary>
 /// <param name="contact">SIP contact.</param>
 /// <param name="expires">Time in seconds when contact expires.</param>
 /// <param name="localEP">SIP proxy local end point info what accpeted this contact registration.</param>
 public void UpdateContact(SIP_t_ContactParam contact,int expires,SIP_EndPointInfo localEP)
 {
     m_pContact       = contact;
     m_Expire         = expires;
     m_pLocalEndPoint = localEP;
     m_LastUpdate     = DateTime.Now;
 }
        /// <summary>
        /// Returns this.Contact as string value, but expires parameter is replaced with remaining time value.
        /// </summary>
        /// <returns></returns>
        public string ToStringValue()
        {
            SIP_t_ContactParam retVal = new SIP_t_ContactParam();
            retVal.Parse(new StringReader(m_pContact.ToStringValue()));
            retVal.Expires = this.Expires;

            return retVal.ToStringValue();
        }