コード例 #1
0
        /// <summary>
        /// Default incoming call constructor.
        /// </summary>
        /// <param name="ua">Owner UA.</param>
        /// <param name="invite">INVITE server transaction.</param>
        /// <exception cref="ArgumentNullException">Is riased when <b>ua</b> or <b>invite</b> is null reference.</exception>
        internal SIP_UA_Call(SIP_UA ua, SIP_ServerTransaction invite)
        {
            if (ua == null)
            {
                throw new ArgumentNullException("ua");
            }
            if (invite == null)
            {
                throw new ArgumentNullException("invite");
            }

            m_pUA = ua;
            m_pInitialInviteTransaction = invite;
            m_pLocalUri  = invite.Request.To.Address.Uri;
            m_pRemoteUri = invite.Request.From.Address.Uri;
            m_pInitialInviteTransaction.Canceled += new EventHandler(delegate(object sender, EventArgs e){
                // If transaction canceled, terminate call.
                SetState(SIP_UA_CallState.Terminated);
            });

            // Parse SDP if INVITE contains SDP.
            // RFC 3261 13.2.1. INVITE may be offerless, we must thne send offer and remote party sends sdp in ACK.
            if (invite.Request.ContentType != null && invite.Request.ContentType.ToLower().IndexOf("application/sdp") > -1)
            {
                m_pRemoteSDP = SDP_Message.Parse(Encoding.UTF8.GetString(invite.Request.Data));
            }

            m_pTags = new Dictionary <string, object>();

            m_State = SIP_UA_CallState.WaitingToAccept;
        }
コード例 #2
0
        private void toResponse(SIP_RequestReceivedEventArgs e)
        {
            SIP_Uri uri = e.Request.RequestLine.Uri as SIP_Uri;

            try
            {
                _sdp     = SDP_Message.Parse(MyEncoder.Encoder.GetString(e.Request.Data));
                RemoteIP = _sdp.Origin.UnicastAddress;
                if (_sdp.MediaDescriptions.Count == 0)
                {
                    e.ServerTransaction.SendResponse(_sipServer.Stack.CreateResponse(SIP_ResponseCodes.x400_Bad_Request, e.Request));
                    return;
                }
                else
                {
                    RemotePort = _sdp.MediaDescriptions[0].Port;
                }
            }
            catch (Exception)
            {
                //解析SDP失败。
                e.ServerTransaction.SendResponse(_sipServer.Stack.CreateResponse(SIP_ResponseCodes.x400_Bad_Request, e.Request));
                return;
            }

            //send 100 Trying;
            e.ServerTransaction.SendResponse(_sipServer.Stack.CreateResponse(SIP_ResponseCodes.x100_Trying, e.Request));

            _videoId = _sipServer.DeviceManager.GetVideoId(uri.User);
            if (_videoId != null)
            {
                RTPServer   rtp     = _sipServer.RTPManager.GetOrAddServer(_videoId);
                SDP_Message respSDP = new SDP_Message();
                respSDP.Version     = "0";
                respSDP.Origin      = new SDP_Origin(uri.User, 0, 0, "IN", "IPV4", rtp.LocalIP);
                respSDP.SessionName = "Play";
                respSDP.Connection  = new SDP_Connection("IN", "IPV4", rtp.LocalIP);
                respSDP.SSRC        = SDP_Utils.SSRC2String(SDP_Utils.GenSSRC(uri.User, true)); //根据国标补充协议标准生成SSRC。
                respSDP.Times.Add(new SDP_Time(0, 0));
                respSDP.MediaDescriptions.Add(new SDP_MediaDescription("video", rtp.Port, 2, "RTP/AVP", new string[] { "96", "97", "98" }));
                respSDP.Attributes.Add(new SDP_Attribute("sendonly", ""));
                respSDP.Attributes.Add(new SDP_Attribute("rtpmap", "96 PS/90000"));
                respSDP.Attributes.Add(new SDP_Attribute("rtpmap", "97 MPEG4/90000"));
                respSDP.Attributes.Add(new SDP_Attribute("rtpmap", "98 H264/90000"));

                SIP_Response resp = _sipServer.Stack.CreateResponse(SIP_ResponseCodes.x200_Ok, e.Request);
                resp.Data = respSDP.ToByte();
                e.ServerTransaction.SendResponse(resp);
            }
            else
            {
                //没有找到视频源。
                e.ServerTransaction.SendResponse(_sipServer.Stack.CreateResponse(SIP_ResponseCodes.x404_Not_Found, e.Request));
            }
        }
コード例 #3
0
        /// <summary>
        /// This method is called when initial INVITE sender got response.
        /// </summary>
        /// <param name="sender">Sender.</param>
        /// <param name="e">Event data.</param>
        private void m_pInitialInviteSender_ResponseReceived(object sender, SIP_ResponseReceivedEventArgs e)
        {
            try{
                lock (m_pLock){
                    // If remote party provided SDP, parse it.
                    if (e.Response.ContentType != null && e.Response.ContentType.ToLower().IndexOf("application/sdp") > -1)
                    {
                        m_pRemoteSDP = SDP_Message.Parse(Encoding.UTF8.GetString(e.Response.Data));

                        // TODO: If parsing failed, end call.
                    }

                    if (e.Response.StatusCodeType == SIP_StatusCodeType.Provisional)
                    {
                        if (e.Response.StatusCode == 180)
                        {
                            SetState(SIP_UA_CallState.Ringing);
                        }
                        else if (e.Response.StatusCode == 182)
                        {
                            SetState(SIP_UA_CallState.Queued);
                        }
                        // We don't care other status responses.

                        /* RFC 3261 13.2.2.1.
                         *  Zero, one or multiple provisional responses may arrive before one or
                         *  more final responses are received.  Provisional responses for an
                         *  INVITE request can create "early dialogs".  If a provisional response
                         *  has a tag in the To field, and if the dialog ID of the response does
                         *  not match an existing dialog, one is constructed using the procedures
                         *  defined in Section 12.1.2.
                         */
                        if (e.Response.StatusCode > 100 && e.Response.To.Tag != null)
                        {
                            m_pEarlyDialogs.Add((SIP_Dialog_Invite)m_pUA.Stack.TransactionLayer.GetOrCreateDialog(e.ClientTransaction, e.Response));
                        }
                    }
                    else if (e.Response.StatusCodeType == SIP_StatusCodeType.Success)
                    {
                        m_StartTime = DateTime.Now;
                        SetState(SIP_UA_CallState.Active);

                        m_pDialog = m_pUA.Stack.TransactionLayer.GetOrCreateDialog(e.ClientTransaction, e.Response);
                        m_pDialog.StateChanged += new EventHandler(m_pDialog_StateChanged);

                        /* Exit all all other dialogs created by this call (due to forking).
                         * That is not defined in RFC but, since UAC can send BYE to early and confirmed dialogs,
                         * because of this all 100% valid.
                         */
                        foreach (SIP_Dialog_Invite dialog in m_pEarlyDialogs.ToArray())
                        {
                            if (!m_pDialog.Equals(dialog))
                            {
                                dialog.Terminate("Another forking leg accepted.", true);
                            }
                        }
                    }
                    else
                    {
                        /* RFC 3261 13.2.2.3.
                         *  All early dialogs are considered terminated upon reception of the non-2xx final response.
                         */
                        foreach (SIP_Dialog_Invite dialog in m_pEarlyDialogs.ToArray())
                        {
                            dialog.Terminate("All early dialogs are considered terminated upon reception of the non-2xx final response. (RFC 3261 13.2.2.3)", false);
                        }
                        m_pEarlyDialogs.Clear();

                        Error();

                        SetState(SIP_UA_CallState.Terminated);
                    }
                }
            }
            catch (Exception x) {
                m_pUA.Stack.OnError(x);
            }
        }
コード例 #4
0
ファイル: SIPDump.cs プロジェクト: skrusty/SIPDump
        private static void device_OnPacketArrival(object sender, CaptureEventArgs e)
        {
            var time = e.Packet.Timeval.Date;
            var len  = e.Packet.Data.Length;

            var packet = PacketDotNet.Packet.ParsePacket(e.Packet.LinkLayerType, e.Packet.Data);

            var udpPacket = PacketDotNet.UdpPacket.GetEncapsulated(packet);

            if (udpPacket != null)
            {
                try
                {
                    // signalling packet
                    SIP_Message msg = ParseSIPMessage(udpPacket.PayloadData);
                    if (msg != null && msg.CallID != null)
                    {
                        SDP_Message sdp = null;

                        try
                        {
                            sdp = SDP_Message.Parse(System.Text.ASCIIEncoding.Default.GetString(msg.Data));
                        }
                        catch { }

                        if (msg is SIP_Request && msg.CallID != null)
                        {
                            SIP_Request r = (SIP_Request)msg;

                            if (!Call.Calls.ContainsKey(r.CallID))
                            {
                                if (r.RequestLine.Method == "INVITE")
                                {
                                    Call.Calls.Add(r.CallID, new Call(r.CallID));
                                    Call.Calls[r.CallID].CallerIP = ((IpPacket)udpPacket.ParentPacket).SourceAddress;
                                    Call.Calls[r.CallID].CalleeIP = ((IpPacket)udpPacket.ParentPacket).DestinationAddress;
                                }
                                else
                                {
                                    return;     // Ignore this conversation
                                }
                            }

                            // if this is an invite, do we have an audio rtp port defined?
                            if (r.RequestLine.Method == "INVITE")
                            {
                                if (sdp != null)
                                {
                                    foreach (var a in sdp.MediaDescriptions)
                                    {
                                        Console.Out.WriteLine(r.CallID + " - Got RTP Media Port: " + ((IpPacket)udpPacket.ParentPacket).SourceAddress + ":" + a.Port.ToString());
                                        if (Call.Calls[r.CallID].CallerIP.ToString() == ((IpPacket)udpPacket.ParentPacket).SourceAddress.ToString())
                                        {
                                            Call.Calls[r.CallID].CallerRTPPort = a.Port;
                                        }
                                        else
                                        {
                                            Call.Calls[r.CallID].CalleeRTPPort = a.Port;
                                        }
                                    }
                                }
                            }

                            if (r.RequestLine.Method == "BYE")
                            {
                                if (Call.Calls.ContainsKey(r.CallID))
                                {
                                    // Log bye was recevied
                                    Call.Calls[r.CallID].SeenBYE = true;

                                    // Now indicate who hung up
                                    Call.Calls[r.CallID].WhoHungUp = ((IpPacket)udpPacket.ParentPacket).SourceAddress == Call.Calls[r.CallID].CallerIP ?
                                                                     Call.CallDirection.Caller : Call.CallDirection.Callee;
                                }
                                else
                                {
                                    Console.WriteLine("Unknown CallID: " + r.CallID);
                                }
                            }
                        }
                        else if (msg is SIP_Response && msg.CallID != null)
                        {
                            SIP_Response r = (SIP_Response)msg;

                            if (sdp != null)
                            {
                                foreach (var a in sdp.MediaDescriptions)
                                {
                                    Console.Out.WriteLine(r.CallID + " - Got RTP Media Port: " + ((IpPacket)udpPacket.ParentPacket).SourceAddress + ":" + a.Port.ToString());
                                    if (Call.Calls[r.CallID].CallerIP.ToString() == ((IpPacket)udpPacket.ParentPacket).SourceAddress.ToString())
                                    {
                                        Call.Calls[r.CallID].CallerRTPPort = a.Port;
                                    }
                                    else
                                    {
                                        Call.Calls[r.CallID].CalleeRTPPort = a.Port;
                                    }
                                }
                            }

                            if (Call.Calls.ContainsKey(r.CallID))
                            {
                                if (r.StatusCodeType == SIP_StatusCodeType.Success && Call.Calls[r.CallID].SeenBYE)
                                {
                                    Call.Calls[r.CallID].Confirmed = true;
                                }
                            }
                        }

                        // Add packet to history
                        if (Call.Calls.ContainsKey(msg.CallID))
                        {
                            Call.Calls[msg.CallID].WritePacket(e.Packet, Call.PacketType.SIPDialog);
                            // Check to see is this call has been terminated
                            if (Call.Calls[msg.CallID].Confirmed)
                            {
                                // Close off the call now last data has been written
                                Console.WriteLine("Call Ended: " + msg.CallID);

                                // Close off the call
                                Call.Calls[msg.CallID].CloseCall();

                                // Remove the call from the in-memory list
                                Call.Calls.Remove(msg.CallID);
                            }
                        }
                    }
                    else
                    {
                        Call c = Call.GetCallByRTPPort(udpPacket.SourcePort);
                        if (c != null)
                        {
                            c.WritePacket(e.Packet, Call.PacketType.RTP);
                        }
                    }
                }
                catch (Exception ex) {
                    Console.WriteLine(ex.ToString());
                }
            }
        }
コード例 #5
0
        public void Handler(Packet packet)
        {
            var udpPacket = UdpPacket.GetEncapsulated(packet);

            // if it's not udp , udpPacket will be null and we don't handle it.
            if (udpPacket != null)
            {
                try
                {
                    // signalling packet
                    SIP_Message msg = ParseSIPMessage(udpPacket.PayloadData);
                    if (msg != null && msg.CallID != null)
                    {
                        SDP_Message sdp = null;
                        Console.WriteLine("SIP capture");
                        try
                        {
                            sdp = SDP_Message.Parse(System.Text.Encoding.Default.GetString(msg.Data));
                        }
                        catch { }

                        if (msg is SIP_Request && msg.CallID != null)
                        {
                            SIP_Request r = (SIP_Request)msg;
                            //already containsKey
                            if (!Call.SIPSessions.ContainsKey(r.CallID))
                            {
                                if (r.RequestLine.Method == "INVITE")
                                {
                                    Call.SIPSessions.Add(r.CallID, new Call(r.CallID));
                                    Call.SIPSessions[r.CallID].CallerIP = ((IpPacket)udpPacket.ParentPacket).SourceAddress;
                                    Call.SIPSessions[r.CallID].CalleeIP = ((IpPacket)udpPacket.ParentPacket).DestinationAddress;
                                }
                                else
                                {
                                    return;     // Ignore this conversation
                                }
                            }

                            // if this is an invite, do we have an audio rtp port defined?
                            if (r.RequestLine.Method == "INVITE")
                            {
                                if (sdp != null)
                                {
                                    foreach (var a in sdp.MediaDescriptions)
                                    {
                                        Console.Out.WriteLine(r.CallID + " - Got RTP Media Port: " + ((IpPacket)udpPacket.ParentPacket).SourceAddress + ":" + a.Port.ToString());
                                        if (Call.SIPSessions[r.CallID].CallerIP.ToString() == ((IpPacket)udpPacket.ParentPacket).SourceAddress.ToString())
                                        {
                                            Call.SIPSessions[r.CallID].CallerRTPPort = a.Port;
                                        }
                                        else
                                        {
                                            Call.SIPSessions[r.CallID].CalleeRTPPort = a.Port;
                                        }
                                        a.MediaFormats.GetType();

                                        break; // First description is about audio . Second is about viedo and we don't need it, so break.
                                    }
                                }
                            }

                            if (r.RequestLine.Method == "BYE")
                            {
                                if (Call.SIPSessions.ContainsKey(r.CallID))
                                {
                                    // Log bye was recevied
                                    Call.SIPSessions[r.CallID].SeenBYE = true;

                                    // Now indicate who hung up
                                    Call.SIPSessions[r.CallID].WhoHungUp = ((IpPacket)udpPacket.ParentPacket).SourceAddress == Call.SIPSessions[r.CallID].CallerIP ?
                                                                           Call.CallDirection.Caller : Call.CallDirection.Callee;
                                }
                                else
                                {
                                    Console.WriteLine("Unknown CallID: " + r.CallID);
                                }
                            }
                        }//    if (msg is SIP_Request && msg.CallID != null)
                        else if (msg is SIP_Response && msg.CallID != null)
                        {
                            SIP_Response r = (SIP_Response)msg;

                            if (r.StatusCode != 183 && r.StatusCode != 100 && r.StatusCode != 200)
                            {
                                Call.SIPSessions[r.CallID].isEnd = true;
                            }

                            if (sdp != null)
                            {
                                foreach (var a in sdp.MediaDescriptions)
                                {
                                    Console.Out.WriteLine(r.CallID + " - Got RTP Media Port: " + ((IpPacket)udpPacket.ParentPacket).SourceAddress + ":" + a.Port.ToString());
                                    if (Call.SIPSessions[r.CallID].CallerIP.ToString() == ((IpPacket)udpPacket.ParentPacket).SourceAddress.ToString())
                                    {
                                        Call.SIPSessions[r.CallID].CallerRTPPort = a.Port;
                                    }
                                    else
                                    {
                                        Call.SIPSessions[r.CallID].CalleeRTPPort = a.Port;
                                    }

                                    break; // First description is about audio . Second is about viedo and we don't need it, so break.
                                }
                            }

                            if (Call.SIPSessions.ContainsKey(r.CallID))
                            {
                                if (r.StatusCodeType == SIP_StatusCodeType.Success && Call.SIPSessions[r.CallID].SeenBYE)
                                {
                                    Call.SIPSessions[r.CallID].Confirmed = true;
                                    Call.SIPSessions[r.CallID].isEnd     = true;
                                }
                            }
                        }

                        // Add packet to history
                        if (Call.SIPSessions.ContainsKey(msg.CallID))
                        {
                            Call.SIPSessions[msg.CallID].WritePacket(packet, Call.PacketType.SIPDialog);
                            // Check to see is this call has been terminated
                            if (Call.SIPSessions[msg.CallID].Confirmed)
                            {
                                // Close off the call now last data has been written
                                Console.WriteLine("Call Ended: " + msg.CallID);

                                // Close off the call
                                Call.SIPSessions[msg.CallID].CloseCall();

                                StringBuilder file        = new StringBuilder(Directory.GetCurrentDirectory() + "//" + Call.SIPSessions[msg.CallID].SIPPacketFilePathAndName);
                                StringBuilder StoragePath = new StringBuilder(Directory.GetCurrentDirectory() + "//" + Call.SIPSessions[msg.CallID].SIPPacketFilePath);
                                pacp_to_wav(file, StoragePath);
                            }

                            if (Call.SIPSessions[msg.CallID].isEnd == true)
                            {
                                Call.SIPSessions.Remove(msg.CallID);
                            }
                        }
                    }
                    else
                    {
                        Call c = Call.GetCallByRTPPort(udpPacket.SourcePort);
                        if (c != null)
                        {
                            c.WritePacket(packet, Call.PacketType.RTP);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.ToString());
                }
            }
        }