Created
December 21, 2014 08:53
-
-
Save Diefenthal/32956e58c9428ba2d58c to your computer and use it in GitHub Desktop.
Recieves RTP Packets from a Satip Server
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
namespace SatIp.Library.Rtp | |
{ | |
class RtpPacket | |
{ | |
private static int MinHeaderLength = 12; | |
// <summary> | |
/// Construktor | |
/// </summary> | |
public RtpPacket() | |
{ | |
} | |
/// <summary> | |
/// Constuktor | |
/// </summary> | |
/// <param name="_data"></param> | |
public RtpPacket(byte[] data) | |
{ | |
Parse(data); | |
} | |
public Int32 HeaderSize = MinHeaderLength; | |
public Int32 Version { get; set; } | |
public Boolean Padding { get; set; } | |
public Boolean Extension { get; set; } | |
public Int32 CsrcCount { get; set; } | |
public Boolean Marker { get; set; } | |
public Int32 PayloadType { get; set; } | |
public UInt16 SequenceNumber { get; set; } | |
public UInt32 Timestamp { get; set; } | |
public UInt32 SourceId { get; set; } | |
public UInt16 ExtensionHeaderId = 0; | |
public UInt16 ExtensionLengthAsCount = 0; | |
public Int32 ExtensionLengthInBytes = 0; | |
public Byte[] Payload { get; set; } | |
///<summary> | |
///Parse | |
///</summary> | |
///<param name="linearData"></param> | |
public void Parse(Byte[] data) | |
{ | |
if (data.Length >= MinHeaderLength) | |
{ | |
Version = ValueFromByte(data[0], 6, 2); | |
Padding = Convert.ToBoolean(ValueFromByte(data[0], 5, 1)); | |
Extension = Convert.ToBoolean(ValueFromByte(data[0], 4, 1)); | |
CsrcCount = ValueFromByte(data[0], 0, 4); | |
Marker = Convert.ToBoolean(ValueFromByte(data[1], 7, 1)); | |
PayloadType = ValueFromByte(data[1], 0, 7); | |
HeaderSize = MinHeaderLength + (CsrcCount * 4); | |
Byte[] seqNum = new Byte[2]; | |
seqNum[0] = data[3]; | |
seqNum[1] = data[2]; | |
SequenceNumber = System.BitConverter.ToUInt16(seqNum, 0); | |
Byte[] timeStmp = new Byte[4]; | |
timeStmp[0] = data[7]; | |
timeStmp[1] = data[6]; | |
timeStmp[2] = data[5]; | |
timeStmp[3] = data[4]; | |
Timestamp = System.BitConverter.ToUInt32(timeStmp, 0); | |
Byte[] srcId = new Byte[4]; | |
srcId[0] = data[11]; | |
srcId[1] = data[10]; | |
srcId[2] = data[9]; | |
srcId[3] = data[8]; | |
SourceId = System.BitConverter.ToUInt32(srcId, 0); | |
Byte[] csrcid = new byte[4]; | |
if (Extension) | |
{ | |
Byte[] extHeaderId = new Byte[2]; | |
extHeaderId[1] = data[HeaderSize + 0]; | |
extHeaderId[0] = data[HeaderSize + 1]; | |
ExtensionHeaderId = System.BitConverter.ToUInt16(extHeaderId, 0); | |
Byte[] extHeaderLength16 = new Byte[2]; | |
extHeaderLength16[1] = data[HeaderSize + 2]; | |
extHeaderLength16[0] = data[HeaderSize + 3]; | |
ExtensionLengthAsCount = System.BitConverter.ToUInt16(extHeaderLength16.ToArray(), 0); | |
ExtensionLengthInBytes = ExtensionLengthAsCount * 4; | |
HeaderSize += ExtensionLengthInBytes + 4; | |
} | |
Payload = new Byte[data.Length - HeaderSize]; | |
Array.Copy(data, HeaderSize, Payload, 0, data.Length - HeaderSize); | |
} | |
} | |
/// <summary> | |
/// GetValueFromByte | |
/// </summary> | |
/// <param name="value"></param> | |
/// <param name="startPos"></param> | |
/// <param name="length"></param> | |
/// <returns></returns> | |
private Int32 ValueFromByte(Byte value, int startPos, int length) | |
{ | |
Byte mask = 0; | |
for (int i = 0; i < length; i++) | |
{ | |
mask = (Byte)(mask | 0x1 << startPos + i); | |
} | |
Byte result = (Byte)((value & mask) >> startPos); | |
return Convert.ToInt32(result); | |
} | |
public override string ToString() | |
{ | |
return string.Format(" RtpPacket V:{0}, P:{1}, EX:{2}, CSRC:{3}, M:{4}, PT:{5}, SQ:{6}, TS:{7}, SSRC:{8}", Version, Padding, Extension, CsrcCount, Marker, PayloadType, SequenceNumber, Timestamp, SourceId); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text; | |
using System.Threading; | |
using System.Net.Sockets; | |
using System.Net; | |
namespace SatIp.Library.Rtp | |
{ | |
public class RtpClient | |
{ | |
#region Private Fields | |
private Thread _rtpListenerThread; | |
private AutoResetEvent _rtpListenerThreadStopEvent = null; | |
private UdpClient _udpClient; | |
private IPEndPoint _serverEndPoint; | |
private int _receivedBytes; | |
private int _receivedPackets; | |
#endregion | |
#region Constructor | |
/// <summary> | |
/// Recieves RtpPackets | |
/// </summary> | |
/// <param name="destination">is the Address for Recieving the Data it can be a Unicast or Multicast Address</param> | |
/// <param name="clientRtpPort">is only needed for Unicast Transmission</param> | |
/// <param name="source">is only needed for Unicast Transmission</param> | |
/// <param name="serverRtpPort">is needed for Unicast and Multicast Transmission</param> | |
public RtpClient(string destination, int clientRtpPort, string source, int serverRtpPort) | |
{ | |
if (isValid(destination)) | |
{ | |
_serverEndPoint = new IPEndPoint(IPAddress.Parse(destination), serverRtpPort); | |
_udpClient = new UdpClient(serverRtpPort); | |
_udpClient.JoinMulticastGroup(IPAddress.Parse(destination)); | |
} | |
else | |
{ | |
_serverEndPoint = new IPEndPoint(IPAddress.Parse(source), serverRtpPort); | |
_udpClient = new UdpClient(new IPEndPoint(IPAddress.Parse(destination), clientRtpPort)); | |
_udpClient.Client.ReceiveTimeout = 400; | |
} | |
} | |
#endregion | |
#region Properties | |
/// <summary> | |
/// | |
/// </summary> | |
public int ReceivedBytes | |
{ | |
get { return _receivedBytes; } | |
set { _receivedBytes = value; } | |
} | |
/// <summary> | |
/// | |
/// </summary> | |
public int ReceivedPackets | |
{ | |
get { return _receivedPackets; } | |
set { _receivedPackets = value; } | |
} | |
#endregion | |
#region Methods | |
public static bool isValid(string ip) | |
{ | |
try | |
{ | |
int octet1 = Int32.Parse(ip.Split(new Char[] { '.' }, 4)[0]); | |
if ((octet1 >= 224) && (octet1 <= 239)) | |
return true; | |
} | |
catch (Exception e) | |
{ | |
} | |
return false; | |
} | |
public void StartRtpListenerThread() | |
{ | |
if (_rtpListenerThread != null && !_rtpListenerThread.IsAlive) | |
{ | |
StopRtpListenerThread(); | |
} | |
if (_rtpListenerThread == null) | |
{ | |
_rtpListenerThreadStopEvent = new AutoResetEvent(false); | |
_rtpListenerThread = new Thread(new ThreadStart(RtpListener)); | |
_rtpListenerThread.Name = string.Format("SAT>IP tuner RTP listener"); | |
_rtpListenerThread.IsBackground = true; | |
_rtpListenerThread.Priority = ThreadPriority.Lowest; | |
_rtpListenerThread.Start(); | |
} | |
} | |
public void StopRtpListenerThread() | |
{ | |
if (_rtpListenerThread != null) | |
{ | |
if (!_rtpListenerThread.IsAlive) | |
{ | |
_rtpListenerThread.Abort(); | |
} | |
else | |
{ | |
_rtpListenerThreadStopEvent.Set(); | |
if (!_rtpListenerThread.Join(400 * 2)) | |
{ | |
_rtpListenerThread.Abort(); | |
} | |
} | |
_rtpListenerThread = null; | |
if (_rtpListenerThreadStopEvent != null) | |
{ | |
_rtpListenerThreadStopEvent.Close(); | |
_rtpListenerThreadStopEvent = null; | |
} | |
} | |
} | |
private void RtpListener() | |
{ | |
try | |
{ | |
_receivedBytes = 0; | |
_receivedPackets = 0; | |
try | |
{ | |
while (!_rtpListenerThreadStopEvent.WaitOne(1)) | |
{ | |
byte[] packets = _udpClient.Receive(ref _serverEndPoint); | |
RtpPacket packet = new RtpPacket(); | |
packet.Parse(packets); | |
Console.Write(packet.ToString()+"\r\n"); | |
if (packets == null) | |
{ | |
continue; | |
} | |
_receivedBytes += packets.Length; | |
_receivedPackets++; | |
} | |
} | |
finally | |
{ | |
_udpClient.Close(); | |
} | |
} | |
catch (ThreadAbortException) | |
{ | |
} | |
catch (Exception ex) | |
{ | |
return; | |
} | |
} | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment