/// <summary> /// The purpose of this method is to determine the RTP port from the SDP packet. /// The so called Media Description from the stream is what is being parsed here. /// The string we are interested in will look like: /// m=audio <port> protocol and some other items. /// When the port number here is specified, this is what port the RTP packets wil /// be arriving on. /// </summary> /// <param name="parser">Instance of the SipParser</param> /// <returns>a port number if known or 0 if unknown.</returns> private int ParsePortFromSDP(SipParser parser) { int locPort = 0; if (parser.MediaDescriptions.Count > 0) { foreach (string str in parser.MediaDescriptions) { // this bit is able to properly extract the UDP port number // the RTP packets will be coming down on. So Once we get into // this state, everything cares about RTP at higher levels, but // when we get into sipstate, the prot will be known. Need to // verify that the channel has its own instance of this class. if (str.StartsWith("m=audio")) { string [] strings; strings = str.Split(' '); if (strings.Length > 1) { locPort = int.Parse(strings [1]); } } } } return(locPort); }
/// <summary> /// the purpose of this method is to process SIP packets and ultimately determine the /// rtp port number the local host will be communicating to the server with. /// </summary> /// <param name="parser">instance of the sip parser</param> /// <returns></returns> public SipConnectionState Process(SipParser parser) { SipConnectionState state; state = SipConnectionState.GOOD; // if the port is 0 we do not yet know what destination port the // client will be listening for incoming RTP traffic. if (rtpPort == 0) { if (parser.LocalSource) { rtpPort = ParsePortFromSDP(parser); if (rtpPort != 0) { state = SipConnectionState.RTP_DETECTED; } } } else { // if the port is set, may need to process sip messages and do things // when they are of appropriate status based on the source/destination. } return(state); }
/// <summary> /// The purpose of this method is to determine the RTP port from the SDP packet. /// The so called Media Description from the stream is what is being parsed here. /// The string we are interested in will look like: /// m=audio <port> protocol and some other items. /// When the port number here is specified, this is what port the RTP packets wil /// be arriving on. /// </summary> /// <param name="parser">Instance of the SipParser</param> /// <returns>a port number if known or 0 if unknown.</returns> private int ParsePortFromSDP( SipParser parser ) { int locPort=0; if( parser.MediaDescriptions.Count > 0 ) { foreach( string str in parser.MediaDescriptions ) { // this bit is able to properly extract the UDP port number // the RTP packets will be coming down on. So Once we get into // this state, everything cares about RTP at higher levels, but // when we get into sipstate, the prot will be known. Need to // verify that the channel has its own instance of this class. if( str.StartsWith( "m=audio" ) ) { string [] strings; strings = str.Split( ' ' ); if( strings.Length > 1 ) { locPort = int.Parse( strings [1] ); } } } } return locPort; }
/// <summary> /// The purpose of this method is to raise the SipArrived event to all /// subscribers. /// </summary> /// <param name="parser">Parser containing the SIP information</param> private void RaiseSipArrived(SipParser parser) { if (this.SipArrived != null) { // TODO: perform safe invokation of all delegates. SipArrived(this, parser); } }
/// <summary> /// Event handler called when a Pcap Packet has arrived /// </summary> /// <param name="sender">who raised it</param> /// <param name="packet">the packet</param> private void device_PcapOnPacketArrival(object sender, Packet packet) { string s; try { // not certain if this will be needed, but just for keep sake if (packet is TCPPacket) { /* * DateTime time = packet.PcapHeader.Date; * int len = packet.PcapHeader.PacketLength; * * TCPPacket tcp = (TCPPacket)packet; * string srcIp = tcp.SourceAddress; * string dstIp = tcp.DestinationAddress; * int srcPort = tcp.SourcePort; * int dstPort = tcp.estinationPort; * * Console.WriteLine( "{0}:{1}:{2},{3} Len={4} {5}:{6} -> {7}:{8}", * time.Hour, time.Minute, time.Second, time.Millisecond, len, * srcIp, srcPort, dstIp, dstPort ); */ } else if (packet is UDPPacket) { IPPacket p = packet as IPPacket; //if( p.DestinationAddress.Equals( ipAddress ) ) { DateTime time = packet.PcapHeader.Date; int len = packet.PcapHeader.PacketLength; UDPPacket udpPacket = (UDPPacket)packet; SipParser parser; if (packet.Data.Length > 0) { // TODO: Is there a better way here? s = System.Text.ASCIIEncoding.ASCII.GetString(packet.Data); if (s.Length > 0) { if (s.Contains("SIP")) { //DumpPacketToFiles( s ); //outs = String.Format( "{0}:{1}:{2},{3} Len={4} {5}:{6} -> {7}:{8}", // time.Hour, time.Minute, time.Second, time.Millisecond, len, // srcIp, srcPort, dstIp, dstPort ); //this.sw.WriteLine( outs ); //this.sw.Write( s ); //this.sw.Flush(); parser = new SipParser(s, ipAddress, udpPacket.DestinationAddress); //Console.WriteLine( // String.Format( "{0} {1} {2}", // parser.SipStatus, parser.SipStatusString, parser.ToField ) ); RaiseSipArrived(parser); packetCount++; } else { RTPPacketEventArgs eventArgs; eventArgs = new RTPPacketEventArgs(udpPacket.DestinationPort, udpPacket.Data); RaiseRTPArrived(eventArgs); } } } } } } catch (Exception ex) { ClsException.WriteToErrorLogFile(ex); } }
/// <summary> /// Event handler called when a Pcap Packet has arrived /// </summary> /// <param name="sender">who raised it</param> /// <param name="packet">the packet</param> private void device_PcapOnPacketArrival( object sender, Packet packet ) { string s; try { // not certain if this will be needed, but just for keep sake if( packet is TCPPacket ) { /* DateTime time = packet.PcapHeader.Date; int len = packet.PcapHeader.PacketLength; TCPPacket tcp = (TCPPacket)packet; string srcIp = tcp.SourceAddress; string dstIp = tcp.DestinationAddress; int srcPort = tcp.SourcePort; int dstPort = tcp.estinationPort; Console.WriteLine( "{0}:{1}:{2},{3} Len={4} {5}:{6} -> {7}:{8}", time.Hour, time.Minute, time.Second, time.Millisecond, len, srcIp, srcPort, dstIp, dstPort ); */ } else if( packet is UDPPacket ) { IPPacket p = packet as IPPacket; //if( p.DestinationAddress.Equals( ipAddress ) ) { DateTime time = packet.PcapHeader.Date; int len = packet.PcapHeader.PacketLength; UDPPacket udpPacket = (UDPPacket)packet; SipParser parser; if( packet.Data.Length > 0 ) { // TODO: Is there a better way here? s = System.Text.ASCIIEncoding.ASCII.GetString( packet.Data ); if( s.Length > 0 ) { if( s.Contains( "SIP" ) ) { //DumpPacketToFiles( s ); //outs = String.Format( "{0}:{1}:{2},{3} Len={4} {5}:{6} -> {7}:{8}", // time.Hour, time.Minute, time.Second, time.Millisecond, len, // srcIp, srcPort, dstIp, dstPort ); //this.sw.WriteLine( outs ); //this.sw.Write( s ); //this.sw.Flush(); parser = new SipParser( s, ipAddress, udpPacket.DestinationAddress ); //Console.WriteLine( // String.Format( "{0} {1} {2}", // parser.SipStatus, parser.SipStatusString, parser.ToField ) ); RaiseSipArrived( parser ); packetCount++; } else { RTPPacketEventArgs eventArgs; eventArgs = new RTPPacketEventArgs( udpPacket.DestinationPort, udpPacket.Data ); RaiseRTPArrived( eventArgs ); } } } } } } catch( Exception ex ) { ClsException.WriteToErrorLogFile( ex ); } }
/// <summary> /// The purpose of this method is to raise the SipArrived event to all /// subscribers. /// </summary> /// <param name="parser">Parser containing the SIP information</param> private void RaiseSipArrived( SipParser parser ) { if( this.SipArrived != null ) { // TODO: perform safe invokation of all delegates. SipArrived( this, parser ); } }
/// <summary> /// the purpose of this method is to process SIP packets and ultimately determine the /// rtp port number the local host will be communicating to the server with. /// </summary> /// <param name="parser">instance of the sip parser</param> /// <returns></returns> public SipConnectionState Process( SipParser parser ) { SipConnectionState state; state = SipConnectionState.GOOD; // if the port is 0 we do not yet know what destination port the // client will be listening for incoming RTP traffic. if( rtpPort == 0 ) { if( parser.LocalSource ) { rtpPort = ParsePortFromSDP( parser ); if( rtpPort != 0 ) { state = SipConnectionState.RTP_DETECTED; } } } else { // if the port is set, may need to process sip messages and do things // when they are of appropriate status based on the source/destination. } return state; }
private void OnSipArrived( object sender, SipParser parser ) { SipConnectionState state; string localNumber; // this is the number to use in the 'client' side try { if( (phoneNumber != null) && (phoneNumber != string.Empty) && (sipState != null) ) { // since the 5555 was added, need to skip over it; it may not always be present. // TODO: need to make this a configurable number from the application in some manner. // (both in length and content) if( phoneNumber.Substring( 0, 4 ).Equals( "5555" ) ) { localNumber = phoneNumber.Substring( 4 ); } else { localNumber = phoneNumber; } if( parser.ToField.Contains( localNumber ) ) { state = sipState.Process( parser ); if( state == SipConnectionState.RTP_DETECTED ) { RTPPort = sipState.RTPPort; } } } } catch( Exception ex ) { ex.Data.Add( "My Key", "VMukti--:--VmuktiModules--:--VmuktiModules--:--Call Center--:--AutoProgressiveSoftPhone--:--AutoProgressivePhone.Business--:--RTCAudioWithToneDetect.cs--:--OnSIPArrived()--" ); ClsException.WriteToErrorLogFile( ex ); } }