/* * /// <summary> * /// Transfers call to specified recipient. * /// </summary> * /// <param name="to">Address where to transfer call.</param> * public void CallTransfer(string to) * { * throw new NotImplementedException(); * }*/ #endregion #region method CopyMessage /// <summary> /// Copies header fileds from 1 message to antother. /// </summary> /// <param name="source">Source message.</param> /// <param name="destination">Destination message.</param> /// <param name="exceptHeaders">Header fields not to copy.</param> private void CopyMessage(SIP_Message source, SIP_Message destination, string[] exceptHeaders) { foreach (SIP_HeaderField headerField in source.Header) { bool copy = true; foreach (string h in exceptHeaders) { if (h.ToLower() == headerField.Name.ToLower()) { copy = false; break; } } if (copy) { destination.Header.Add(headerField.Name, headerField.Value); } } destination.Data = source.Data; }
/* /// <summary> /// Transfers call to specified recipient. /// </summary> /// <param name="to">Address where to transfer call.</param> public void CallTransfer(string to) { throw new NotImplementedException(); }*/ /// <summary> /// Copies header fileds from 1 message to antother. /// </summary> /// <param name="source">Source message.</param> /// <param name="destination">Destination message.</param> /// <param name="exceptHeaders">Header fields not to copy.</param> private void CopyMessage(SIP_Message source, SIP_Message destination, string[] exceptHeaders) { foreach (SIP_HeaderField headerField in source.Header) { bool copy = true; foreach (string h in exceptHeaders) { if (h.ToLower() == headerField.Name.ToLower()) { copy = false; break; } } if (copy) { destination.Header.Add(headerField.Name, headerField.Value); } } destination.Data = source.Data; }
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()); } } }
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()); } } }