feyris-tan af8edceca2
Some checks failed
🚀 Pack skyscraper8 / make-zip (push) Failing after 1m9s
Actually scrape LogonResponseDescriptor, LowerLayerServiceDescriptor and HigherLayersInitializeDescriptor.
2025-11-12 17:36:42 +01:00

357 lines
10 KiB
C#

using skyscraper5.Mpeg2;
using skyscraper5.Mpeg2.Descriptors;
using skyscraper5.Skyscraper;
using skyscraper5.Skyscraper.IO;
using skyscraper5.src.InteractionChannel.Model.Descriptors;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;
using skyscraper8.GSE.GSE;
using skyscraper8.InteractionChannel.Model2.Descriptors;
namespace skyscraper5.src.InteractionChannel.Model
{
public class Tim : Validatable
{
public Tim(MemoryStream ms, bool broadcast)
{
Broadcast = broadcast;
Status = ms.ReadUInt8();
byte descriptorLoopCount = ms.ReadUInt8(); descriptorLoopCount++;
int minimumRequiredLength = descriptorLoopCount * 2;
if (ms.GetAvailableBytes() < minimumRequiredLength)
{
Valid = false;
return;
}
Descriptors = new TsDescriptor[descriptorLoopCount];
for (int i = 0; i < descriptorLoopCount; i++)
{
//we don't have a way to read single descriptors so far
byte descriptorTag = ms.ReadUInt8();
byte descriptorLength = ms.ReadUInt8();
if (ms.GetAvailableBytes() < descriptorLength)
{
Valid = false;
return;
}
byte[] descriptorBuffer = ms.ReadBytes(descriptorLength);
switch(descriptorTag)
{
case 0x4a:
//Linkage_descriptor
//must appear in RMT, not TIM
Valid = false;
return;
case 0xa0:
Descriptors[i] = new _0xa0_NetworkLayerInfoDescriptor(descriptorBuffer);
break;
case 0xa1:
Descriptors[i] = new _0xa1_CorrectionMessageDescriptor(descriptorBuffer);
break;
case 0xa2:
Descriptors[i] = new _0xa2_LoginInitializeDescriptor(descriptorBuffer);
if (!Descriptors[i].Valid)
{
Valid = false;
return;
}
break;
case 0xa3:
Descriptors[i] = new _0xa3_AcqAssignDescriptor(descriptorBuffer);
if (!Descriptors[i].Valid)
{
Valid = false;
return;
}
break;
case 0xa4:
Descriptors[i] = new _0xa4_SyncAssignDescriptor(descriptorBuffer);
if (!Descriptors[i].Valid)
{
Valid = false;
return;
}
break;
case 0xa5:
Descriptors[i] = new _0xa5_EncryptedLoginIdDescriptor(descriptorBuffer);
if (!Descriptors[i].Valid)
{
Valid = false;
return;
}
break;
case 0xa7:
//RCS_content_descriptor
//can't appear in a TIM.
Valid = false;
return;
case 0xa8:
Descriptors[i] = new _0xa8_SatelliteForwardLinkDescriptor(descriptorBuffer);
if (!Descriptors[i].Valid)
{
Valid = false;
return;
}
break;
case 0xa9:
Descriptors[i] = new _0xa9_SatelliteReturnLinkDescriptor(descriptorBuffer);
if (!Descriptors[i].Valid)
{
Valid = false;
return;
}
break;
case 0xaa:
Descriptors[i] = new _0xaa_TableUpdateDescriptor(descriptorBuffer);
if (!Descriptors[i].Valid)
{
Valid = false;
return;
}
break;
case 0xab:
Descriptors[i] = new _0xab_ContentionControlDescriptor(descriptorBuffer);
break;
case 0xac:
Descriptors[i] = new _0xac_CorrectionControlDescriptor(descriptorBuffer);
break;
case 0xad:
Descriptors[i] = new _0xad_ForwardInteractionPathDescriptor(descriptorBuffer);
if (!Descriptors[i].Valid)
{
Valid = false;
return;
}
break;
case 0xae:
Descriptors[i] = new _0xae_ReturnInteractionPathDescriptor(descriptorBuffer);
if (!Descriptors[i].Valid)
{
Valid = false;
return;
}
break;
case 0xb1:
Descriptors[i] = new _0xb1_CorrectionMessageExtensionDescriptor(descriptorBuffer);
if (!Descriptors[i].Valid)
{
Valid = false;
return;
}
break;
case 0xb5:
Descriptors[i] = new _0xb5_ImplementationTypeDescriptor(descriptorBuffer);
if (!Descriptors[i].Valid)
{
Valid = false;
return;
}
break;
case 0xaf:
Descriptors[i] = new _0xaf_ConnectionControlDescriptor(descriptorBuffer);
break;
case 0xb2:
Descriptors[i] = new _0xb2_ReturnTransmissionModesDescriptor(descriptorBuffer);
if (!Descriptors[i].Valid)
{
Valid = false;
return;
}
break;
case 0xb3:
Descriptors[i] = new _0xb3_MeshLogonInitializeDescriptor(descriptorBuffer);
if (!Descriptors[i].Valid)
{
Valid = false;
return;
}
break;
case 0xb6:
Descriptors[i] = new _0xb6_LlFecIdentifierDescriptor(descriptorBuffer);
if (!Descriptors[i].Valid)
{
Valid = false;
return;
}
break;
case 0xb7:
Descriptors[i] = new _0xb7_FramePayloadFormatDescriptor(descriptorBuffer);
if (!Descriptors[i].Valid)
{
Valid = false;
return;
}
break;
case 0xb9:
Descriptors[i] = new _0xb9_LogonResponseDescriptor(descriptorBuffer);
if (!Descriptors[i].Valid)
{
Valid = false;
return;
}
break;
case 0xbb:
Descriptors[i] = new _0xbb_LowerLayerServiceDescriptor(descriptorBuffer);
if (!Descriptors[i].Valid)
{
Valid = false;
return;
}
break;
case 0xc4:
Descriptors[i] = new _0xc4_HigherLayersInitializeDescriptor(descriptorBuffer);
if (!Descriptors[i].Valid)
{
Valid = false;
return;
}
break;
default:
if (descriptorTag >= 0x00 && descriptorTag <= 0x49)
{
//Reserved
continue;
}
if (descriptorTag >= 0x4b && descriptorTag <= 0x9f)
{
//Reserved
continue;
}
if (descriptorTag >= 0xcc && descriptorTag <= 0xdf)
{
//Reserved
continue;
}
if (descriptorTag >= 0xe0 && descriptorTag <= 0xfe)
{
Descriptors[i] = new UserDefinedDescriptor(descriptorTag, descriptorBuffer);
break;
}
if (descriptorTag == 0xff)
{
//Forbidden
Valid = false;
return;
}
throw new NotImplementedException(String.Format("TIM Parse 0x{0:X2}", descriptorTag));
}
}
byte[] padBytes = ms.ReadBytes(ms.GetAvailableBytes() - 4);
uint crc32 = ms.ReadUInt32BE();
Valid = true;
}
public bool Broadcast { get; }
public byte Status { get; }
public TsDescriptor[] Descriptors { get; }
public bool IDEncrypt => (Status & 0x80) != 0;
public bool LogonFail => (!Broadcast & ((Status & 0x40) != 0));
public bool LogonDenied => (!Broadcast & ((Status & 0x20) != 0));
public bool Logoff => (!Broadcast & ((Status & 0x10) != 0));
public bool TransmitDisable => (!Broadcast & ((Status & 0x08) != 0));
public bool RainFadeRelease => (!Broadcast & ((Status & 0x04) != 0));
public bool RainFadeDetect => (!Broadcast & ((Status & 0x02) != 0));
public bool WakeUp => (!Broadcast & ((Status & 0x01) != 0));
public bool CscLinkFailureRec => (Broadcast & ((Status & 0x10) != 0));
public bool LinkFailureRecovery => (Broadcast & ((Status & 0x08) != 0));
public bool ReturnLinkFailure => (Broadcast & ((Status & 0x04) != 0));
public bool NccReceiveFailure => (Broadcast & ((Status & 0x02) != 0));
public bool SchedulerFailure => (Broadcast & ((Status & 0x01) != 0));
internal void Handle(PhysicalAddress macAddress, ushort? networkId, InteractionChannelHandler handler)
{
foreach(TsDescriptor descriptor in Descriptors)
{
if (descriptor == null)
{
continue;
}
if (descriptor is UserDefinedDescriptor)
{
continue;
}
if (!descriptor.Valid)
{
Valid = false;
return;
}
byte id = descriptor.GetDescriptorId();
switch(id)
{
case 0xa0:
handler.OnNetworkLayerInfo(macAddress, (_0xa0_NetworkLayerInfoDescriptor)descriptor);
break;
case 0xa1:
if (Broadcast)
{
if (networkId.HasValue)
{
handler.OnCorrectionMessage(networkId.Value, ToCmt((_0xa1_CorrectionMessageDescriptor)descriptor));
}
}
else
{
handler.OnCorrectionMessage(macAddress, ((_0xa1_CorrectionMessageDescriptor)descriptor));
}
break;
case 0xa4:
handler.OnControlAssignment(macAddress,(_0xa4_SyncAssignDescriptor)descriptor);
break;
case 0xa9:
handler.OnSatelliteReturnLink(macAddress, (_0xa9_SatelliteReturnLinkDescriptor)descriptor);
break;
case 0xab:
handler.OnContentionControl(macAddress, ((_0xab_ContentionControlDescriptor)descriptor));
break;
case 0xac:
handler.OnCorrectionControl(macAddress, (_0xac_CorrectionControlDescriptor)descriptor);
break;
case 0xad:
handler.OnForwardInteractionPath(macAddress, (_0xad_ForwardInteractionPathDescriptor)descriptor);
break;
case 0xaf:
handler.OnConnectionControl(macAddress, (_0xaf_ConnectionControlDescriptor)descriptor);
break;
case 0xb1:
handler.OnCorrectionMessageExtension(macAddress, (_0xb1_CorrectionMessageExtensionDescriptor)descriptor);
break;
case 0xb2:
handler.OnReturnTransmissionMOdes(macAddress, (_0xb2_ReturnTransmissionModesDescriptor)descriptor);
break;
case 0xb7:
handler.OnFramePayloadFormatAnnouncement(networkId.Value, (_0xb7_FramePayloadFormatDescriptor)descriptor);
break;
case 0xb9:
handler.LogonResponseDescriptor(macAddress, (_0xb9_LogonResponseDescriptor)descriptor);
break;
case 0xbb:
handler.OnLowerLayerService(macAddress, (_0xbb_LowerLayerServiceDescriptor)descriptor);
break;
case 0xc4:
handler.OnHigherLayerInitalization(macAddress, (_0xc4_HigherLayersInitializeDescriptor)descriptor);
break;
default:
if (id >= 0xe0 && id <= 0xfe)
break;
throw new NotImplementedException(String.Format("TIM Descriptor 0x{0:X2} ({1}) is not fully implemented yet. Please share a sample of this stream.", id, descriptor.GetType().Name));
}
}
}
private Cmt ToCmt(_0xa1_CorrectionMessageDescriptor descriptor)
{
throw new NotImplementedException();
}
}
}