Detect broken GS encapsulation.
All checks were successful
🚀 Pack skyscraper8 / make-zip (push) Successful in 1m57s
All checks were successful
🚀 Pack skyscraper8 / make-zip (push) Successful in 1m57s
This commit is contained in:
parent
fe66c643f8
commit
a46e4ff556
1
.gitignore
vendored
1
.gitignore
vendored
@ -129,3 +129,4 @@ imgui.ini
|
||||
/skyscraper8.Manual/skyscraper8.Manual.out
|
||||
/skyscraper8.Manual/skyscraper8.Manual.pdf
|
||||
/skyscraper8.Manual/skyscraper8.Manual.synctex.gz
|
||||
/.vs/skyscraper8/CopilotIndices/17.14.1231.31060
|
||||
|
||||
@ -90,6 +90,11 @@ namespace skyscraper8.GSE
|
||||
break;
|
||||
}
|
||||
|
||||
if (!packet.Valid)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (packet.IsCompletePacket)
|
||||
{
|
||||
if (ValidateEthertype(packet.ProtocolType.Value))
|
||||
@ -113,6 +118,25 @@ namespace skyscraper8.GSE
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!packet.StartIndicator && packet.EndIndicator)
|
||||
{
|
||||
if (gseFragmentations == null)
|
||||
continue;
|
||||
if (gseFragmentations[packet.FragmentId.Value] == null)
|
||||
continue;
|
||||
|
||||
gseFragmentations[packet.FragmentId.Value].AddPacket(packet);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!packet.StartIndicator && !packet.EndIndicator)
|
||||
{
|
||||
if (gseFragmentations == null)
|
||||
continue;
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
@ -129,8 +153,8 @@ namespace skyscraper8.GSE
|
||||
|
||||
long availableBytes = ms.GetAvailableBytes();
|
||||
byte[] readBytes = ms.ReadBytes(availableBytes);
|
||||
|
||||
GseAssemblyState assemblyState = ValidateGse(gseAssembler);
|
||||
|
||||
GseAssemblyState assemblyState = ValidateGse(gseAssembler, true);
|
||||
if (assemblyState == GseAssemblyState.NOT_YET_BEGUN)
|
||||
{
|
||||
if ((syncByte & 0xc0) == 0xc0)
|
||||
@ -195,7 +219,7 @@ namespace skyscraper8.GSE
|
||||
VALID_NULL_PACKET, //somehow these only show up on TBS6903x, not DD Max SX8?
|
||||
}
|
||||
|
||||
private GseAssemblyState ValidateGse(MemoryStream ms)
|
||||
private GseAssemblyState ValidateGse(MemoryStream ms, bool tryFix = false)
|
||||
{
|
||||
if (ms == null)
|
||||
return GseAssemblyState.NOT_YET_BEGUN;
|
||||
@ -204,6 +228,8 @@ namespace skyscraper8.GSE
|
||||
ms.Position = 0;
|
||||
while (ms.GetAvailableBytes() > 2)
|
||||
{
|
||||
long fixPosition = ms.Position;
|
||||
|
||||
//GSE-Header
|
||||
byte byteA = ms.ReadUInt8();
|
||||
bool startIndicator = (byteA & 0x80) != 0;
|
||||
@ -224,6 +250,12 @@ namespace skyscraper8.GSE
|
||||
//Console.WriteLine("GSE Length: {0}", gseLength);
|
||||
if (gseLength > 9000)
|
||||
{
|
||||
if (tryFix)
|
||||
{
|
||||
ms.Position = fixPosition;
|
||||
ms.WriteUInt8Repeat(0, (int)ms.GetAvailableBytes());
|
||||
break;
|
||||
}
|
||||
ms.Position = backupPosition;
|
||||
return GseAssemblyState.BROKEN_SUSPECT_LENGTH;
|
||||
}
|
||||
@ -236,6 +268,11 @@ namespace skyscraper8.GSE
|
||||
|
||||
if (startIndicator && !endIndicator)
|
||||
{
|
||||
if (2 > ms.GetAvailableBytes())
|
||||
{
|
||||
ms.Position = backupPosition;
|
||||
return GseAssemblyState.NEED_MORE_DATA;
|
||||
}
|
||||
ushort totalLength = ms.ReadUInt16BE();
|
||||
gseLength -= 2;
|
||||
}
|
||||
@ -250,6 +287,12 @@ namespace skyscraper8.GSE
|
||||
ushort protocolType = ms.ReadUInt16BE();
|
||||
if (!ValidateEthertype(protocolType))
|
||||
{
|
||||
if (tryFix)
|
||||
{
|
||||
ms.Position = fixPosition;
|
||||
ms.WriteUInt8Repeat(0, (int)ms.GetAvailableBytes());
|
||||
break;
|
||||
}
|
||||
ms.Position = backupPosition;
|
||||
return GseAssemblyState.BROKEN_SUSPECT_ETHERTYPE;
|
||||
}
|
||||
@ -278,6 +321,12 @@ namespace skyscraper8.GSE
|
||||
|
||||
if (gseLength < 0)
|
||||
{
|
||||
if (tryFix)
|
||||
{
|
||||
ms.Position = fixPosition;
|
||||
ms.WriteUInt8Repeat(0, (int)ms.GetAvailableBytes());
|
||||
break;
|
||||
}
|
||||
ms.Position = backupPosition;
|
||||
return GseAssemblyState.BROKEN_NEGATIVE_LENGTH;
|
||||
}
|
||||
@ -291,6 +340,11 @@ namespace skyscraper8.GSE
|
||||
ms.Position += gseLength;
|
||||
if (!startIndicator && endIndicator)
|
||||
{
|
||||
if (4 > ms.GetAvailableBytes())
|
||||
{
|
||||
ms.Position = backupPosition;
|
||||
return GseAssemblyState.NEED_MORE_DATA;
|
||||
}
|
||||
uint crc32 = ms.ReadUInt32BE();
|
||||
int endCrc32 = (int)ms.Position;
|
||||
DvbCrc32.ValidateCrc(ms, startCrc32, endCrc32);
|
||||
|
||||
@ -9,7 +9,7 @@ using skyscraper5.Skyscraper;
|
||||
|
||||
namespace skyscraper8.GSE
|
||||
{
|
||||
internal class GsePacket
|
||||
internal class GsePacket : Validatable
|
||||
{
|
||||
public static GsePacket Read(MemoryStream ms)
|
||||
{
|
||||
@ -62,12 +62,23 @@ namespace skyscraper8.GSE
|
||||
if (!packet.StartIndicator && packet.EndIndicator)
|
||||
gseLength -= 4;
|
||||
|
||||
if (gseLength < 0)
|
||||
{
|
||||
packet.Valid = false;
|
||||
return packet;
|
||||
}
|
||||
if (gseLength > ms.GetAvailableBytes())
|
||||
{
|
||||
packet.Valid = false;
|
||||
return packet;
|
||||
}
|
||||
packet.GseData = ms.ReadBytes(gseLength);
|
||||
|
||||
if (!packet.StartIndicator && packet.EndIndicator)
|
||||
packet.Crc32 = ms.ReadUInt32BE();
|
||||
}
|
||||
|
||||
packet.Valid = true;
|
||||
return packet;
|
||||
}
|
||||
|
||||
|
||||
@ -1,15 +1,17 @@
|
||||
using System;
|
||||
using log4net;
|
||||
using skyscraper5.Skyscraper;
|
||||
using skyscraper5.src.Mpeg2.PacketFilter;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Runtime.CompilerServices;
|
||||
using skyscraper5.Skyscraper;
|
||||
using skyscraper5.src.Mpeg2.PacketFilter;
|
||||
|
||||
namespace skyscraper5.Mpeg2
|
||||
{
|
||||
public class TsContext : ITsPacketProcessor
|
||||
{
|
||||
private ITsPacketProcessor[] processors;
|
||||
private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name);
|
||||
private ITsPacketProcessor[] processors;
|
||||
private uint[] continuities;
|
||||
private ulong[] pidPackets;
|
||||
|
||||
@ -42,6 +44,8 @@ namespace skyscraper5.Mpeg2
|
||||
if (FilterChain == null || FilterChain.Count == 0)
|
||||
throw new InvalidOperationException("The filter chain has not been initialized.");
|
||||
|
||||
CheckBrokenEncapsulation(packet);
|
||||
|
||||
for (int i = 0; i < FilterChain.Count; i++)
|
||||
{
|
||||
if (FilterChain[i] == null)
|
||||
@ -61,6 +65,44 @@ namespace skyscraper5.Mpeg2
|
||||
processors[packet.PID].PushPacket(packet);
|
||||
}
|
||||
|
||||
private bool encapsulationBrokenConfirmed;
|
||||
private bool CheckBrokenEncapsulation(TsPacket packet)
|
||||
{
|
||||
if (encapsulationBrokenConfirmed)
|
||||
return true;
|
||||
|
||||
switch (packet.PID)
|
||||
{
|
||||
case 0x0000:
|
||||
case 0x0001:
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
int occupiedPids = CountOccupiedPids();
|
||||
if (occupiedPids < 1000)
|
||||
return false;
|
||||
|
||||
if (packet.TSC == 0)
|
||||
return false;
|
||||
|
||||
logger.WarnFormat("It looks like you're either having bad reception or this is a GS with broken encapsulation. This means that you either have FrameMode enabled, or are not using a STiD135.");
|
||||
encapsulationBrokenConfirmed = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private int CountOccupiedPids()
|
||||
{
|
||||
int result = 0;
|
||||
for (int i = 0; i < pidPackets.Length; i++)
|
||||
{
|
||||
if (pidPackets[i] > 0)
|
||||
result++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private bool EnsureContinuity(TsPacket packet)
|
||||
{
|
||||
//Found in ISO 13818-1.pdf, page 38
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"profiles": {
|
||||
"skyscraper8": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "\"\\\\utena\\mergerfs\\Skyscraper\\ipProto253_eutelsat7_10803h-max-sx8.ts\"",
|
||||
"commandLineArgs": "cscan tcp://172.20.20.203:6969",
|
||||
"remoteDebugEnabled": false
|
||||
},
|
||||
"Container (Dockerfile)": {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user