109 lines
3.3 KiB
C#
109 lines
3.3 KiB
C#
using skyscraper5.Skyscraper.IO;
|
|
using skyscraper8.DvbNip;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace skyscraper8.Ietf.FLUTE
|
|
{
|
|
internal class LctHeader
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
/// <param name="headerBuffer">A buffer that contains an LCT Header starting from the first byte of the Congestion Control Information</param>
|
|
/// <param name="c">Congestion control flag</param>
|
|
/// <param name="s">Transport Session Identifier flag</param>
|
|
/// <param name="o">Transport Object Identifier flag</param>
|
|
/// <param name="h">Half-word flag</param>
|
|
/// <exception cref="NotSupportedException"></exception>
|
|
public LctHeader(byte[] headerBuffer, int c, bool sFlag, int o, bool hFlag)
|
|
{
|
|
int s = sFlag ? 1 : 0;
|
|
int h = hFlag ? 1 : 0;
|
|
|
|
MemoryStream ms = new MemoryStream(headerBuffer, false);
|
|
int cciLength = 32 * (c + 1);
|
|
int tsiLength = 32 * s + 16 * h;
|
|
int toiLength = 32 * o + 16 * h;
|
|
|
|
CongestionControlInformation = ReadField(ms, cciLength);
|
|
TransportSessionIdentifier = ReadField(ms, tsiLength);
|
|
TransportObjectIdentifier = ReadField(ms, toiLength);
|
|
|
|
while (ms.GetAvailableBytes() >= 1)
|
|
{
|
|
byte extensionId = ms.ReadUInt8();
|
|
if (extensionId >= 128)
|
|
{
|
|
ms.Position--;
|
|
uint fixedHeaderExtension = ms.ReadUInt32BE();
|
|
switch (extensionId)
|
|
{
|
|
case 192:
|
|
this.FdtInstanceId = new FdtInstanceHeader(fixedHeaderExtension);
|
|
break;
|
|
case 193:
|
|
this.ContentEncoding = new ContentEncodingOfFdtInstance(fixedHeaderExtension);
|
|
break;
|
|
default:
|
|
throw new NotImplementedException(String.Format("LCT Header Extension {0}", extensionId));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
uint headerExtensionLength = ms.ReadUInt8();
|
|
headerExtensionLength *= 4;
|
|
if (headerExtensionLength >= 2)
|
|
headerExtensionLength -= 2;
|
|
byte[] extensionBuffer = ms.ReadBytes(headerExtensionLength);
|
|
switch(extensionId)
|
|
{
|
|
case 0:
|
|
break;
|
|
case 2:
|
|
this.TimeExtenstion = new TimeHeaderExtension(extensionBuffer);
|
|
break;
|
|
case 64:
|
|
this.FecObjectTransmissionInformation = new FecObjectTransmissionInformation(extensionBuffer);
|
|
break;
|
|
case 68:
|
|
this.NipActualCarrierInformation = new NipActualCarrierInformation(extensionBuffer);
|
|
break;
|
|
default:
|
|
throw new NotImplementedException(String.Format("LCT Header Extension {0}", extensionId));
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
private ulong ReadField(Stream stream, int bits)
|
|
{
|
|
switch(bits)
|
|
{
|
|
case 16:
|
|
return stream.ReadUInt16BE();
|
|
case 32:
|
|
return stream.ReadUInt32BE();
|
|
case 48:
|
|
return stream.ReadUInt48BE();
|
|
case 64:
|
|
return stream.ReadUInt64BE();
|
|
default:
|
|
throw new NotImplementedException(String.Format("{0} bits.", bits));
|
|
}
|
|
}
|
|
public ulong CongestionControlInformation { get; private set; }
|
|
public ulong TransportSessionIdentifier { get; }
|
|
public ulong TransportObjectIdentifier { get; }
|
|
public FdtInstanceHeader FdtInstanceId { get; }
|
|
public NipActualCarrierInformation NipActualCarrierInformation { get; }
|
|
public FecObjectTransmissionInformation FecObjectTransmissionInformation { get; }
|
|
public TimeHeaderExtension TimeExtenstion { get; }
|
|
public ContentEncodingOfFdtInstance ContentEncoding { get; }
|
|
}
|
|
}
|