123 lines
3.1 KiB
C#
123 lines
3.1 KiB
C#
using log4net;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using skyscraper5.Ietf.Rfc768;
|
|
using skyscraper5.Ietf.Rfc971;
|
|
using skyscraper5.Skyscraper;
|
|
using skyscraper5.Skyscraper.Plugins;
|
|
using skyscraper5.Skyscraper.Scraper;
|
|
using skyscraper8.Atsc.A331.Schema;
|
|
using skyscraper8.Ietf.FLUTE;
|
|
|
|
namespace skyscraper8.Atsc.A331
|
|
{
|
|
[SkyscraperPlugin]
|
|
[PluginPriority(3)]
|
|
internal class Atsc3Unpacker : ISkyscraperMpePlugin
|
|
{
|
|
private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
|
|
private static readonly IPAddress LLS_IP = IPAddress.Parse("224.0.23.60");
|
|
private static readonly ushort LLS_PORT = 4937;
|
|
|
|
private IAtsc3EventHandler eventHandler;
|
|
private bool systimeDetected;
|
|
|
|
public void ConnectToStorage(object[] connector)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public void SetContext(DateTime? currentTime, object skyscraperContext)
|
|
{
|
|
eventHandler = (IAtsc3EventHandler)skyscraperContext;
|
|
}
|
|
|
|
private bool atsc3detected;
|
|
public bool CanHandlePacket(InternetHeader internetHeader, byte[] ipv4Packet)
|
|
{
|
|
if (internetHeader.Protocol != 0x11)
|
|
return false;
|
|
|
|
if (atsc3detected && internetHeader.IsDestinationMulticast)
|
|
return true;
|
|
|
|
if (internetHeader.DestinationAddress.Equals(LLS_IP))
|
|
{
|
|
if (ipv4Packet.GetUInt16BE(2) == LLS_PORT)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public void HandlePacket(InternetHeader internetHeader, byte[] ipv4Packet)
|
|
{
|
|
_stopProcessIndicator = false;
|
|
UserDatagram udpPacket = new UserDatagram(ipv4Packet);
|
|
if (internetHeader.DestinationAddress.Equals(LLS_IP) && udpPacket.DestinationPort == LLS_PORT)
|
|
{
|
|
//Handle LLS
|
|
LlsTable lls = new LlsTable(udpPacket.Payload);
|
|
HandleLls(lls);
|
|
return;
|
|
}
|
|
|
|
if (!atsc3detected)
|
|
{
|
|
return;
|
|
}
|
|
|
|
LctFrame lctFrame = new LctFrame(udpPacket.Payload, true);
|
|
}
|
|
|
|
private void HandleLls(LlsTable lls)
|
|
{
|
|
if (!lls.Valid)
|
|
return;
|
|
|
|
_stopProcessIndicator = true;
|
|
|
|
switch (lls.LlsTableId)
|
|
{
|
|
case 0x01:
|
|
//SLT
|
|
if (!atsc3detected)
|
|
{
|
|
atsc3detected = true;
|
|
eventHandler.OnAtsc3Detected();
|
|
}
|
|
sltType slt = Atsc3Utilities.UnpackSlt(lls.Payload);
|
|
eventHandler.OnAtsc3ServiceList(slt);
|
|
break;
|
|
case 0x03:
|
|
SysTimeType systime = Atsc3Utilities.UnpackSystime(lls.Payload);
|
|
if (systime.ptpPrepend != 0 && !systimeDetected)
|
|
{
|
|
logger.WarnFormat("Found valid ATSC A/331 SYSTIME, however it is not implemented yet. ");
|
|
systimeDetected = true;
|
|
}
|
|
break;
|
|
case 0xff:
|
|
//User defined, can be removed.
|
|
break;
|
|
default:
|
|
logger.InfoFormat(
|
|
"Encountered unknown ATSC A/331 LLS Table: 0x{0:X2} This means that this stream uses a version of ATSC 3 than skyscraper8 knows about. It would be great if you could share a recording of this stream so this can be implemented.", lls.LlsTableId);
|
|
break;
|
|
}
|
|
}
|
|
|
|
private bool _stopProcessIndicator;
|
|
public bool StopProcessingAfterThis()
|
|
{
|
|
return _stopProcessIndicator;
|
|
}
|
|
}
|
|
}
|