/// <summary> /// Default constructor. /// </summary> /// <param name="sipStack">Reference to SIP stack.</param> /// <param name="request">SIP request to what caused to create client transaction.</param> /// <param name="destination">Remote destination info.</param> /// <param name="addVia">Specified if transaction adds new Via: header. If this value is false, /// then its user responsibility to add valid Via: header to <b>request</b> argument.</param> internal SIP_ClientTransaction(SIP_Stack sipStack,SIP_Request request,SIP_Destination destination,bool addVia) { m_pSipStack = sipStack; m_pRequest = request; m_pDestination = destination; m_pResponses = new List<SIP_Response>(); // Add Via: header field. if(addVia){ m_ID = SIP_t_ViaParm.CreateBranch(); SIP_t_ViaParm via = new SIP_t_ViaParm(); via.ProtocolName = "SIP"; via.ProtocolVersion = "2.0"; via.ProtocolTransport = m_pDestination.Transport; via.SentBy = "transport_layer_will_replace_it"; via.Branch = m_ID; request.Via.AddToTop(via.ToStringValue()); } // User provided Via:. else{ // Validate Via: SIP_t_ViaParm via = request.Via.GetTopMostValue(); if(via == null){ throw new ArgumentException("Via: header is missing !"); } if(via.Branch == null){ throw new ArgumentException("Via: header 'branch' prameter is missing !"); } m_ID = via.Branch; } }
/// <summary> /// Calling constructor. /// </summary> /// <param name="stack">Reference to SIP stack.</param> /// <param name="sender">Initial INVITE sender.</param> /// <param name="session">Call RTP multimedia session.</param> /// <exception cref="ArgumentNullException">Is raised when <b>stack</b>,<b>sender</b> or <b>session</b> is null reference.</exception> internal SIP_Call(SIP_Stack stack,SIP_RequestSender sender,RTP_MultimediaSession session) { if(stack == null){ throw new ArgumentNullException("stack"); } if(sender == null){ throw new ArgumentNullException("sender"); } if(session == null){ throw new ArgumentNullException("session"); } m_pStack = stack; m_pInitialInviteSender = sender; m_pRtpMultimediaSession = session; m_pTags = new Dictionary<string,object>(); m_pInitialInviteSender.Completed += new EventHandler(delegate(object s,EventArgs e){ m_pInitialInviteSender = null; if(this.State == SIP_CallState.Terminating){ SetState(SIP_CallState.Terminated); } }); m_CallState = SIP_CallState.Calling; }
/// <summary> /// Default constructor. /// </summary> /// <param name="stack">Owner stack.</param> /// <param name="isServer">Specifies if flow is server or client flow.</param> /// <param name="localEP">Local IP end point.</param> /// <param name="remoteEP">Remote IP end point.</param> /// <param name="transport">SIP transport.</param> /// <exception cref="ArgumentNullException">Is raised when <b>stack</b>,<b>localEP</b>,<b>remoteEP</b> or <b>transport</b> is null reference.</exception> /// <exception cref="ArgumentException">Is raised whena any of the arguments has invalid value.</exception> internal SIP_Flow(SIP_Stack stack,bool isServer,IPEndPoint localEP,IPEndPoint remoteEP,string transport) { if(stack == null){ throw new ArgumentNullException("stack"); } if(localEP == null){ throw new ArgumentNullException("localEP"); } if(remoteEP == null){ throw new ArgumentNullException("remoteEP"); } if(transport == null){ throw new ArgumentNullException("transport"); } m_pStack = stack; m_IsServer = isServer; m_pLocalEP = localEP; m_pRemoteEP = remoteEP; m_Transport = transport.ToUpper(); m_CreateTime = DateTime.Now; m_LastActivity = DateTime.Now; m_ID = m_pLocalEP.ToString() + "-" + m_pRemoteEP.ToString() + "-" + m_Transport; m_pMessage = new MemoryStream(); }
/// <summary> /// Default constructor. /// </summary> public SIP_UA() { m_pStack = new SIP_Stack(); m_pStack.RequestReceived += new EventHandler<SIP_RequestReceivedEventArgs>(m_pStack_RequestReceived); m_pCalls = new List<SIP_UA_Call>(); }
/// <summary> /// Default constructor. /// </summary> /// <param name="stack">Owner SIP stack.</param> /// <param name="server">Registrar server URI. For example: sip:domain.com.</param> /// <param name="aor">Address of record. For example: [email protected].</param> /// <param name="contact">Contact URI.</param> /// <param name="expires">Gets after how many seconds reigisration expires.</param> /// <exception cref="ArgumentNullException">Is raised when <b>ua</b>,<b>server</b>,<b>transport</b>,<b>aor</b> or <b>contact</b> is null reference.</exception> /// <exception cref="ArgumentException">Is raised when any of the arguments contains invalid value.</exception> internal SIP_UA_Registration(SIP_Stack stack,SIP_Uri server,string aor,AbsoluteUri contact,int expires) { if(stack == null){ throw new ArgumentNullException("stack"); } if(server == null){ throw new ArgumentNullException("server"); } if(aor == null){ throw new ArgumentNullException("aor"); } if(aor == string.Empty){ throw new ArgumentException("Argument 'aor' value must be specified."); } if(contact == null){ throw new ArgumentNullException("contact"); } m_pStack = stack; m_pServer = server; m_AOR = aor; m_pContact = contact; m_RefreshInterval = expires; m_pContacts = new List<AbsoluteUri>(); m_pTimer = new TimerEx((m_RefreshInterval - 15) * 1000); m_pTimer.AutoReset = false; m_pTimer.Elapsed += new System.Timers.ElapsedEventHandler(m_pTimer_Elapsed); m_pTimer.Enabled = false; }
/// <summary> /// Default constructor. /// </summary> /// <param name="stack">Owner SIP stack.</param> /// <exception cref="ArgumentNullException">Is raised when <b>stack</b> is null reference.</exception> internal SIP_TransportLayer(SIP_Stack stack) { if(stack == null){ throw new ArgumentNullException("stack"); } m_pStack = stack; m_pUdpServer = new UDP_Server(); m_pUdpServer.ProcessMode = UDP_ProcessMode.Parallel; m_pUdpServer.PacketReceived += new PacketReceivedHandler(m_pUdpServer_PacketReceived); m_pUdpServer.Error += new ErrorEventHandler(m_pUdpServer_Error); m_pTcpServer = new TCP_Server<TCP_ServerSession>(); m_pTcpServer.SessionCreated += new EventHandler<TCP_ServerSessionEventArgs<TCP_ServerSession>>(m_pTcpServer_SessionCreated); m_pFlowManager = new SIP_FlowManager(this); m_pBinds = new IPBindInfo[]{}; m_pRandom = new Random(); m_pLocalIPv4 = new CircleCollection<IPAddress>(); m_pLocalIPv6 = new CircleCollection<IPAddress>(); }
/// <summary> /// Cleans up any resources being used. /// </summary> public void Dispose() { lock(m_pLock){ if(m_IsDisposed){ return; } // Hang up all calls. foreach(SIP_UA_Call call in m_pCalls.ToArray()){ call.Terminate(); } // Wait till all registrations and calls disposed or wait timeout reached. DateTime start = DateTime.Now; while(m_pCalls.Count > 0){ System.Threading.Thread.Sleep(500); // Timeout, just kill all UA. if(((TimeSpan)(DateTime.Now - start)).Seconds > 15){ break; } } m_IsDisposed = true; this.RequestReceived = null; this.IncomingCall = null; m_pStack.Dispose(); m_pStack = null; } }
/// <summary> /// Default constructor. /// </summary> /// <param name="stack">Reference to SIP stack.</param> /// <param name="flow">SIP data flow.</param> /// <param name="request">Recieved request.</param> /// <param name="transaction">SIP server transaction which must be used to send response back to request maker.</param> internal SIP_RequestReceivedEventArgs(SIP_Stack stack,SIP_Flow flow,SIP_Request request,SIP_ServerTransaction transaction) { m_pStack = stack; m_pFlow = flow; m_pRequest = request; m_pTransaction = transaction; }
/// <summary> /// Default constructor. /// </summary> /// <param name="stack">Owner stack.</param> /// <param name="request">Request to forward.</param> /// <param name="forkingMode">Specifies how proxy context must handle forking.</param> /// <param name="noCancel">Specifies if proxy should not send Cancel to forked requests.</param> /// <param name="noRecurse">Specifies what proxy server does when it gets 3xx response. If true proxy will forward /// request to new specified address if false, proxy will return 3xx response to caller.</param> /// <param name="destinations">Possible destinations. NOTE: These values must be in priority order !</param> /// <exception cref="ArgumentNullException">Is raised when any of the reference type prameters is null.</exception> public SIP_ProxyContext(SIP_Stack stack,SIP_Request request,SIP_ForkingMode forkingMode,bool noCancel,bool noRecurse,SIP_Destination[] destinations) { if(stack == null){ throw new ArgumentNullException("stack"); } if(request == null){ throw new ArgumentNullException("serverTransaction"); } if(destinations == null){ throw new ArgumentNullException("destinations"); } m_pStack = stack; m_pServerTransaction = stack.TransactionLayer.CreateServerTransaction(request); m_pServerTransaction.CanCreateDialog = false; m_pServerTransaction.Canceled += new EventHandler(m_pServerTransaction_Canceled); m_pServerTransaction.Terminated += new EventHandler(m_pServerTransaction_Terminated); m_ForkingMode = forkingMode; m_NoCancel = noCancel; m_NoRecurse = noRecurse; m_pClientTransactions = new List<SIP_ClientTransaction>(); m_pResponses = new List<SIP_Response>(); m_CreateTime = DateTime.Now; // Queue destinations up, higest to lowest. m_pRemainingDestinations = new Queue<SIP_Destination>(); foreach(SIP_Destination destination in destinations){ m_pRemainingDestinations.Enqueue(destination); } }
/// <summary> /// Default constructor. /// </summary> /// <param name="sipStack">Reference to SIP stack.</param> public SIP_TransactionLayer(SIP_Stack sipStack) { m_pSipStack = sipStack; m_pClientTransactions = new List<SIP_ClientTransaction>(); m_pServerTransactions = new List<SIP_ServerTransaction>(); m_pDialogs = new List<SIP_Dialog>(); }
/// <summary> /// Default constructor. /// </summary> /// <param name="stack">Owner SIP stack.</param> /// <param name="flow">SIP data flow which is used to send request.</param> /// <param name="request">SIP request that transaction will handle.</param> /// <exception cref="ArgumentNullException">Is raised when <b>stack</b>,<b>flow</b> or <b>request</b> is null reference.</exception> /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception> internal SIP_ClientTransaction(SIP_Stack stack,SIP_Flow flow,SIP_Request request) : base(stack,flow,request) { // Log if(this.Stack.Logger != null){ this.Stack.Logger.AddText(this.ID,"Transaction [branch='" + this.ID + "';method='" + this.Method + "';IsServer=false] created."); } SetState(SIP_TransactionState.WaitingToStart); }
/// <summary> /// Default constructor. /// </summary> /// <param name="stack">Owner SIP stack.</param> /// <param name="flow">SIP data flow which received request.</param> /// <param name="request">SIP request that transaction will handle.</param> /// <exception cref="ArgumentNullException">Is raised when <b>stack</b>,<b>flow</b> or <b>request</b> is null reference.</exception> /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception> public SIP_ServerTransaction(SIP_Stack stack,SIP_Flow flow,SIP_Request request) : base(stack,flow,request) { // Log if(this.Stack.Logger != null){ this.Stack.Logger.AddText(this.ID,"Transaction [branch='" + this.ID + "';method='" + this.Method + "';IsServer=true] created."); } Start(); }
/// <summary> /// Default constructor. /// </summary> /// <param name="sipStack">Reference to SIP stack.</param> /// <param name="request">SIP request what caused to create server transaction.</param> internal SIP_ServerTransaction(SIP_Stack sipStack,SIP_Request request) { m_pSipStack = sipStack; m_pRequest = request; m_ID = request.Via.GetTopMostValue().Branch; m_pResponses = new List<SIP_Response>(); Begin(); }
/// <summary> /// Default constructor. /// </summary> /// <param name="proxy">Owner proxy.</param> internal SIP_Registrar(SIP_ProxyCore proxy) { m_pProxy = proxy; m_pSipStack = m_pProxy.Stack; m_pRegistrations = new SIP_RegistrationCollection(); m_pTimer = new Timer(15000); m_pTimer.Elapsed += new ElapsedEventHandler(m_pTimer_Elapsed); m_pTimer.Enabled = true; }
/// <summary> /// Default constructor. /// </summary> /// <param name="stack">SIP stack.</param> /// <exception cref="ArgumentNullException">Is raised when <b>stack</b> is null reference.</exception> public wfrm_SIP_Debug(SIP_Stack stack) { if(stack == null){ throw new ArgumentNullException("stack"); } m_pStack = stack; m_pStack.Logger.WriteLog += new EventHandler<LumiSoft.Net.Log.WriteLogEventArgs>(Logger_WriteLog); InitUI(); }
/// <summary> /// Default constructor. /// </summary> /// <param name="sipStack">Reference to SIP stack.</param> public SIP_TransportLayer(SIP_Stack sipStack) { m_pSipStack = sipStack; m_pListeningPoints = new List<SipListeningPoint>(); m_pTcpReceiviePipes = new List<SipTcpPipe>(); m_pTcpPipesTimer = new System.Timers.Timer(20000); m_pTcpPipesTimer.Elapsed += new System.Timers.ElapsedEventHandler(m_pTcpPipesTimer_Elapsed); m_pTcpPipesTimer.Enabled = true; }
/// <summary> /// Default constructor. /// </summary> /// <param name="stack">Reference to SIP stack.</param> /// <exception cref="ArgumentNullException">Is raised when <b>stack</b> is null reference.</exception> internal SIP_TransactionLayer(SIP_Stack stack) { if(stack == null){ throw new ArgumentNullException("stack"); } m_pStack = stack; m_pClientTransactions = new Dictionary<string,SIP_ClientTransaction>(); m_pServerTransactions = new Dictionary<string,SIP_ServerTransaction>(); m_pDialogs = new Dictionary<string,SIP_Dialog>(); }
/// <summary> /// Default constructor. /// </summary> /// <param name="stack">Reference to SIP stack.</param> /// <exception cref="ArgumentNullException">Is raised when <b>sipStack</b> is null.</exception> public SIP_ProxyCore(SIP_Stack stack) { if(stack == null){ throw new ArgumentNullException("stack"); } m_pStack = stack; m_pStack.RequestReceived += new EventHandler<SIP_RequestReceivedEventArgs>(m_pStack_RequestReceived); m_pStack.ResponseReceived += new EventHandler<SIP_ResponseReceivedEventArgs>(m_pStack_ResponseReceived); m_pRegistrar = new SIP_Registrar(this); m_pB2BUA = new SIP_B2BUA(this); m_Opaque = Auth_HttpDigest.CreateOpaque(); m_pProxyContexts = new List<SIP_ProxyContext>(); }
/// <summary> /// Default constructor. /// </summary> /// <param name="proxy">Owner proxy.</param> /// <exception cref="ArgumentNullException">Is raised when <b>proxy</b> is null reference.</exception> internal SIP_Registrar(SIP_ProxyCore proxy) { if(proxy == null){ throw new ArgumentNullException("proxy"); } m_pProxy = proxy; m_pStack = m_pProxy.Stack; m_pRegistrations = new SIP_RegistrationCollection(); m_pTimer = new Timer(15000); m_pTimer.Elapsed += new ElapsedEventHandler(m_pTimer_Elapsed); m_pTimer.Enabled = true; }
/// <summary> /// Default constructor. /// </summary> /// <param name="stack">Owner stack.</param> /// <param name="request">SIP request.</param> /// <param name="flow">Active data flow what to try before RFC 3261 [4](RFC 3263) methods to use to send request. /// This value can be null.</param> /// <exception cref="ArgumentNullException">Is raised when <b>stack</b> or <b>request</b> is null.</exception> internal SIP_RequestSender(SIP_Stack stack,SIP_Request request,SIP_Flow flow) { if(stack == null){ throw new ArgumentNullException("stack"); } if(request == null){ throw new ArgumentNullException("request"); } m_pStack = stack; m_pRequest = request; m_pFlow = flow; m_pCredentials = new List<NetworkCredential>(); m_pHops = new Queue<SIP_Hop>(); }
/// <summary> /// Default constructor. /// </summary> /// <param name="stack">Reference to SIP stack.</param> /// <exception cref="ArgumentNullException">Is raised when <b>stack</b> is null reference.</exception> internal SIP_TransactionLayer(SIP_Stack stack) { if(stack == null){ throw new ArgumentNullException("stack"); } m_pStack = stack; m_pClientTransactions = new Dictionary<string,SIP_ClientTransaction>(); m_pServerTransactions = new Dictionary<string,SIP_ServerTransaction>(); m_pDialogs = new Dictionary<string,SIP_Dialog>(); m_pTimer = new Timer(20000); m_pTimer.AutoReset = true; m_pTimer.Elapsed += new ElapsedEventHandler(m_pTimer_Elapsed); }
/// <summary> /// Default constructor. /// </summary> /// <param name="stack">Owner SIP stack.</param> /// <param name="flow">Transaction data flow.</param> /// <param name="request">SIP request that transaction will handle.</param> /// <exception cref="ArgumentNullException">Is raised when <b>stack</b>,<b>flow</b> or <b>request</b> is null reference.</exception> public SIP_Transaction(SIP_Stack stack,SIP_Flow flow,SIP_Request request) { if(stack == null){ throw new ArgumentNullException("stack"); } if(flow == null){ throw new ArgumentNullException("flow"); } if(request == null){ throw new ArgumentNullException("request"); } m_pStack = stack; m_pFlow = flow; m_pRequest = request; m_Method = request.RequestLine.Method; m_CreateTime = DateTime.Now; m_pResponses = new List<SIP_Response>(); // Validate Via: SIP_t_ViaParm via = request.Via.GetTopMostValue(); if(via == null){ throw new ArgumentException("Via: header is missing !"); } if(via.Branch == null){ throw new ArgumentException("Via: header 'branch' parameter is missing !"); } m_ID = via.Branch; if(this is SIP_ServerTransaction){ /* We use branch and sent-by as indexing key for transaction, the only special what we need to do is to handle CANCEL, because it has same branch as transaction to be canceled. For avoiding key collision, we add branch + '-' + 'sent-by' + CANCEL for cancel index key. ACK has also same branch, but we won't do transaction for ACK, so it isn't problem. */ string key = request.Via.GetTopMostValue().Branch + '-' + request.Via.GetTopMostValue().SentBy; if(request.RequestLine.Method == SIP_Methods.CANCEL){ key += "-CANCEL"; } m_Key = key; } else{ m_Key = m_ID + "-" + request.RequestLine.Method; } }
/// <summary> /// Default constructor. /// </summary> /// <param name="stack">SIP stack.</param> /// <param name="request">SIP request.</param> /// <param name="hops">Priority ordered "hops" where to send request.</param> /// <exception cref="ArgumentNullException">Is raised when <b>stack</b>,<b>request</b> or <b>hops</b> is null reference.</exception> /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception> public SIP_RequestSender(SIP_Stack stack,SIP_Request request,Queue<SIP_Hop> hops) { if(stack == null){ throw new ArgumentNullException("stack"); } if(request == null){ throw new ArgumentNullException("request"); } if(hops == null){ throw new ArgumentNullException("hops"); } if(hops.Count == 0){ throw new ArgumentException("There must be at least 1 hop in 'hops' queue."); } m_pStack = stack; m_pRequest = request; m_pHops = hops; }
/// <summary> /// Cleans up any resources being used. /// </summary> public void Dispose() { if(m_IsDisposed){ return; } m_IsDisposed = true; m_pStack = null; m_pTimer.Dispose(); m_pTimer = null; SetState(SIP_UA_RegistrationState.Disposed); OnDisposed(); this.Registered = null; this.Unregistered = null; this.Error = null; this.Disposed = null; }
/// <summary> /// Cleans up any resources being used. /// </summary> internal void Dispose() { if(m_IsDisposed){ return; } m_IsDisposed = true; this.CanRegister = null; this.AorRegistered = null; this.AorUnregistered = null; this.AorUpdated = null; m_pProxy = null; m_pStack = null; m_pRegistrations = null; if(m_pTimer != null){ m_pTimer.Dispose(); m_pTimer = null; } }
/// <summary> /// Initializes dialog. /// </summary> /// <param name="stack">Owner stack.</param> /// <param name="transaction">Owner transaction.</param> /// <param name="response">SIP response what caused dialog creation.</param> /// <exception cref="ArgumentNullException">Is raised when <b>stack</b>,<b>transaction</b> or <b>response</b>.</exception> internal protected virtual void Init(SIP_Stack stack,SIP_Transaction transaction,SIP_Response response) { if(stack == null){ throw new ArgumentNullException("stack"); } if(transaction == null){ throw new ArgumentNullException("transaction"); } if(response == null){ throw new ArgumentNullException("response"); } m_pStack = stack; #region UAS /* RFC 3261 12.1.1. The UAS then constructs the state of the dialog. This state MUST be maintained for the duration of the dialog. If the request arrived over TLS, and the Request-URI contained a SIPS URI, the "secure" flag is set to TRUE. The route set MUST be set to the list of URIs in the Record-Route header field from the request, taken in order and preserving all URI parameters. If no Record-Route header field is present in the request, the route set MUST be set to the empty set. This route set, even if empty, overrides any pre-existing route set for future requests in this dialog. The remote target MUST be set to the URI from the Contact header field of the request. The remote sequence number MUST be set to the value of the sequence number in the CSeq header field of the request. The local sequence number MUST be empty. The call identifier component of the dialog ID MUST be set to the value of the Call-ID in the request. The local tag component of the dialog ID MUST be set to the tag in the To field in the response to the request (which always includes a tag), and the remote tag component of the dialog ID MUST be set to the tag from the From field in the request. A UAS MUST be prepared to receive a request without a tag in the From field, in which case the tag is considered to have a value of null. This is to maintain backwards compatibility with RFC 2543, which did not mandate From tags. The remote URI MUST be set to the URI in the From field, and the local URI MUST be set to the URI in the To field. */ if(transaction is SIP_ServerTransaction){ m_IsSecure = ((SIP_Uri)transaction.Request.RequestLine.Uri).IsSecure; m_pRouteSet = (SIP_t_AddressParam[])Net_Utils.ReverseArray(transaction.Request.RecordRoute.GetAllValues()); m_pRemoteTarget = (SIP_Uri)transaction.Request.Contact.GetTopMostValue().Address.Uri; m_RemoteSeqNo = transaction.Request.CSeq.SequenceNumber; m_LocalSeqNo = 0; m_CallID = transaction.Request.CallID; m_LocalTag = response.To.Tag; m_RemoteTag = transaction.Request.From.Tag; m_pRemoteUri = transaction.Request.From.Address.Uri; m_pLocalUri = transaction.Request.To.Address.Uri; m_pLocalContact = (SIP_Uri)response.Contact.GetTopMostValue().Address.Uri; List<string> allow = new List<string>(); foreach(SIP_t_Method m in response.Allow.GetAllValues()){ allow.Add(m.Method); } m_pRemoteAllow = allow.ToArray(); List<string> supported = new List<string>(); foreach(SIP_t_OptionTag s in response.Supported.GetAllValues()){ supported.Add(s.OptionTag); } m_pRemoteSupported = supported.ToArray(); } #endregion #region UAC /* RFC 3261 12.1.2. When a UAC receives a response that establishes a dialog, it constructs the state of the dialog. This state MUST be maintained for the duration of the dialog. If the request was sent over TLS, and the Request-URI contained a SIPS URI, the "secure" flag is set to TRUE. The route set MUST be set to the list of URIs in the Record-Route header field from the response, taken in reverse order and preserving all URI parameters. If no Record-Route header field is present in the response, the route set MUST be set to the empty set. This route set, even if empty, overrides any pre-existing route set for future requests in this dialog. The remote target MUST be set to the URI from the Contact header field of the response. The local sequence number MUST be set to the value of the sequence number in the CSeq header field of the request. The remote sequence number MUST be empty (it is established when the remote UA sends a request within the dialog). The call identifier component of the dialog ID MUST be set to the value of the Call-ID in the request. The local tag component of the dialog ID MUST be set to the tag in the From field in the request, and the remote tag component of the dialog ID MUST be set to the tag in the To field of the response. A UAC MUST be prepared to receive a response without a tag in the To field, in which case the tag is considered to have a value of null. This is to maintain backwards compatibility with RFC 2543, which did not mandate To tags. The remote URI MUST be set to the URI in the To field, and the local URI MUST be set to the URI in the From field. */ else{ // TODO: Validate request or client transaction must do it ? m_IsSecure = ((SIP_Uri)transaction.Request.RequestLine.Uri).IsSecure; m_pRouteSet = (SIP_t_AddressParam[])Net_Utils.ReverseArray(response.RecordRoute.GetAllValues()); m_pRemoteTarget = (SIP_Uri)response.Contact.GetTopMostValue().Address.Uri; m_LocalSeqNo = transaction.Request.CSeq.SequenceNumber; m_RemoteSeqNo = 0; m_CallID = transaction.Request.CallID; m_LocalTag = transaction.Request.From.Tag; m_RemoteTag = response.To.Tag; m_pRemoteUri = transaction.Request.To.Address.Uri; m_pLocalUri = transaction.Request.From.Address.Uri; m_pLocalContact = (SIP_Uri)transaction.Request.Contact.GetTopMostValue().Address.Uri; List<string> allow = new List<string>(); foreach(SIP_t_Method m in response.Allow.GetAllValues()){ allow.Add(m.Method); } m_pRemoteAllow = allow.ToArray(); List<string> supported = new List<string>(); foreach(SIP_t_OptionTag s in response.Supported.GetAllValues()){ supported.Add(s.OptionTag); } m_pRemoteSupported = supported.ToArray(); } #endregion m_pFlow = transaction.Flow; AddTransaction(transaction); }
/// <summary> /// Cleans up any resources being used. /// </summary> public virtual void Dispose() { lock(m_pLock){ if(this.State == SIP_DialogState.Disposed){ return; } SetState(SIP_DialogState.Disposed,true); this.RequestReceived = null; m_pStack = null; m_CallID = null; m_LocalTag = null; m_RemoteTag = null; m_pLocalUri = null; m_pRemoteUri = null; m_pLocalContact = null; m_pRemoteTarget = null; m_pRouteSet = null; m_pFlow = null; } }
/// <summary> /// Default constructor. /// </summary> /// <param name="stack">Reference to SIP stack.</param> /// <param name="flow">SIP data flow.</param> /// <param name="request">Recieved request.</param> internal SIP_RequestReceivedEventArgs(SIP_Stack stack,SIP_Flow flow,SIP_Request request) : this(stack,flow,request,null,null) { }
/// <summary> /// Default constructor. /// </summary> /// <param name="sipStack">Reference to SIP stack.</param> public SIP_ProxyCore(SIP_Stack sipStack) { m_pSipStack = sipStack; m_pRegistrar = new SIP_Registrar(this); }
/// <summary> /// Initializes SIP stack. /// </summary> private void InitStack() { #region Init audio devices if (AudioOut.Devices.Length == 0) { MessageBox.Show("Calling not possible, there are no speakers in computer.", "Error:", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (AudioIn.Devices.Length == 0) { MessageBox.Show("Calling not possible, there is no microphone in computer.", "Error:", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } m_pAudioOutDevice = AudioOut.Devices[0]; m_pAudioInDevice = AudioIn.Devices[0]; m_pAudioCodecs = new Dictionary<int, AudioCodec>(); m_pAudioCodecs.Add(0, new PCMU()); m_pAudioCodecs.Add(8, new PCMA()); m_pPlayer = new WavePlayer(AudioOut.Devices[0]); #endregion #region Get NAT handling methods m_pUPnP = new UPnP_NAT_Client(); STUN_Result stunResult = new STUN_Result(STUN_NetType.UdpBlocked, null); try { stunResult = STUN_Client.Query(m_StunServer, 3478, new IPEndPoint(IPAddress.Any, 0)); } catch { } if (stunResult.NetType == STUN_NetType.Symmetric || stunResult.NetType == STUN_NetType.UdpBlocked) { ToolStripMenuItem item_stun = new ToolStripMenuItem("STUN (" + stunResult.NetType + ")"); item_stun.Name = "stun"; item_stun.Enabled = false; ((ToolStripDropDownButton)m_pToolbar.Items["nat"]).DropDownItems.Add(item_stun); } else { ToolStripMenuItem item_stun = new ToolStripMenuItem("STUN (" + stunResult.NetType + ")"); item_stun.Name = "stun"; ((ToolStripDropDownButton)m_pToolbar.Items["nat"]).DropDownItems.Add(item_stun); } if (m_pUPnP.IsSupported) { ToolStripMenuItem item_upnp = new ToolStripMenuItem("UPnP"); item_upnp.Name = "upnp"; ((ToolStripDropDownButton)m_pToolbar.Items["nat"]).DropDownItems.Add(item_upnp); } else { ToolStripMenuItem item_upnp = new ToolStripMenuItem("UPnP Not Supported"); item_upnp.Name = "upnp"; item_upnp.Enabled = false; ((ToolStripDropDownButton)m_pToolbar.Items["nat"]).DropDownItems.Add(item_upnp); } //if(!((ToolStripDropDownButton)m_pToolbar.Items["nat"]).DropDownItems["stun"].Enabled && !((ToolStripDropDownButton)m_pToolbar.Items["nat"]).DropDownItems["upnp"].Enabled){ //MessageBox.Show("Calling may not possible, your firewall or router blocks STUN and doesn't support UPnP.\r\n\r\nSTUN Net Type: " + stunResult.NetType + "\r\n\r\nUPnP Supported: " + m_pUPnP.IsSupported,"Error:",MessageBoxButtons.OK,MessageBoxIcon.Error); //} ToolStripMenuItem item_no_nat = new ToolStripMenuItem("No NAT handling"); item_no_nat.Name = "no_nat"; ((ToolStripDropDownButton)m_pToolbar.Items["nat"]).DropDownItems.Add(item_no_nat); // Select first enabled item. foreach (ToolStripItem it in ((ToolStripDropDownButton)m_pToolbar.Items["nat"]).DropDownItems) { if (it.Enabled) { ((ToolStripMenuItem)it).Checked = true; m_NatHandlingType = it.Name; break; } } #endregion m_pStack = new SIP_Stack(); m_pStack.UserAgent = "GSDR"; m_pStack.BindInfo = new IPBindInfo[] { new IPBindInfo("", BindInfoProtocol.UDP, IPAddress.Any, m_SipPort) }; //m_pStack.Allow m_pStack.Error += new EventHandler<ExceptionEventArgs>(m_pStack_Error); m_pStack.RequestReceived += new EventHandler<SIP_RequestReceivedEventArgs>(m_pStack_RequestReceived); m_pStack.Start(); if (m_IsDebug) { wfrm_SIP_Debug debug = new wfrm_SIP_Debug(m_pStack); debug.Show(); } }