124 lines
3.0 KiB
C#
124 lines
3.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using log4net;
|
|
using skyscraper5.Ietf.Rfc768;
|
|
using skyscraper5.Ietf.Rfc971;
|
|
using skyscraper5.Skyscraper.Plugins;
|
|
using skyscraper5.Skyscraper.Scraper;
|
|
using skyscraper8.Ietf.FLUTE;
|
|
|
|
namespace skyscraper8.ThreemediaOtt
|
|
{
|
|
[SkyscraperPlugin]
|
|
internal class ThreemediaOttHandler : ISkyscraperMpePlugin
|
|
{
|
|
private static readonly IPAddress THREEMDIA_DESTINATION_IP = IPAddress.Parse("224.1.2.1");
|
|
private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
|
|
|
|
public void ConnectToStorage(object[] connector)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
private SkyscraperContext context;
|
|
public void SetContext(DateTime? currentTime, object skyscraperContext)
|
|
{
|
|
if (context != null)
|
|
{
|
|
context = skyscraperContext as SkyscraperContext;
|
|
}
|
|
}
|
|
|
|
public bool CanHandlePacket(InternetHeader internetHeader, byte[] ipv4Packet)
|
|
{
|
|
if (!internetHeader.IsDestinationMulticast)
|
|
return false;
|
|
|
|
if (!internetHeader.DestinationAddress.Equals(THREEMDIA_DESTINATION_IP))
|
|
return false;
|
|
if (internetHeader.Protocol != 17)
|
|
return false;
|
|
|
|
if (ipv4Packet[2] != 0x04)
|
|
return false;
|
|
if (ipv4Packet[3] != 0x61)
|
|
return false;
|
|
if (ipv4Packet[8] != 0x10)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
private Dictionary<ushort, ThreemediaSession> sessions;
|
|
public void HandlePacket(InternetHeader internetHeader, byte[] ipv4Packet)
|
|
{
|
|
UserDatagram udpPacket = new UserDatagram(ipv4Packet);
|
|
LctFrame lctFrame = new LctFrame(udpPacket.Payload, false);
|
|
if (lctFrame.CloseSessionFlag)
|
|
{
|
|
AssembleSegment(udpPacket.DestinationPort);
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
IngestPacket(udpPacket.DestinationPort, lctFrame);
|
|
return;
|
|
}
|
|
}
|
|
|
|
private void IngestPacket(ushort udpPacketDestinationPort, LctFrame lctFrame)
|
|
{
|
|
if (sessions == null)
|
|
sessions = new Dictionary<ushort, ThreemediaSession>();
|
|
|
|
ThreemediaSession selectedSession = null;
|
|
if (sessions.ContainsKey(udpPacketDestinationPort))
|
|
{
|
|
selectedSession = sessions[udpPacketDestinationPort];
|
|
}
|
|
else
|
|
{
|
|
selectedSession = new ThreemediaSession();
|
|
sessions[udpPacketDestinationPort] = selectedSession;
|
|
}
|
|
|
|
selectedSession.IngestPacket(lctFrame);
|
|
}
|
|
|
|
private void AssembleSegment(ushort destinationPort)
|
|
{
|
|
if (sessions == null)
|
|
return;
|
|
|
|
if (!sessions.ContainsKey(destinationPort))
|
|
{
|
|
return;
|
|
}
|
|
|
|
ThreemediaSession selectedSession = sessions[destinationPort];
|
|
if (!selectedSession.IsComplete())
|
|
{
|
|
logger.WarnFormat(String.Format("The session on Port {0} is incomplete and can not be recovered.", destinationPort));
|
|
selectedSession.Dispose();
|
|
return;
|
|
}
|
|
|
|
ThreemediaSessionStream stream = selectedSession.CreateStream();
|
|
|
|
FileStream fs = File.OpenWrite("test.bin");
|
|
stream.CopyTo(fs);
|
|
fs.Flush(true);
|
|
fs.Close();
|
|
}
|
|
|
|
public bool StopProcessingAfterThis()
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
}
|