Implemented parts of Docsis Annex C required for the Multipart Registration Response.

This commit is contained in:
feyris-tan 2025-05-21 22:23:54 +02:00
parent 0d0268509d
commit daa4ee87d4
20 changed files with 372 additions and 28 deletions

View File

@ -1,5 +1,6 @@
using skyscraper5; using skyscraper5;
using skyscraper5.Docsis.AnnexC; using skyscraper5.Docsis.AnnexC;
using skyscraper5.Docsis.MacManagement;
using skyscraper5.Mpeg2; using skyscraper5.Mpeg2;
using skyscraper5.Skyscraper.Scraper; using skyscraper5.Skyscraper.Scraper;
using skyscraper5.Skyscraper.Scraper.Storage; using skyscraper5.Skyscraper.Scraper.Storage;
@ -11,6 +12,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Net.NetworkInformation;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Xunit.Sdk; using Xunit.Sdk;
@ -66,5 +68,25 @@ namespace skyscraper8.Tests
ModemCapabilitiesEncoding modemCapabilitiesEncoding = new ModemCapabilitiesEncoding(buffer); ModemCapabilitiesEncoding modemCapabilitiesEncoding = new ModemCapabilitiesEncoding(buffer);
Assert.True(modemCapabilitiesEncoding.Valid); Assert.True(modemCapabilitiesEncoding.Valid);
} }
[Fact]
public void AAB_MultipartRegistrationResponseTest()
{
Random rng = new Random();
byte[] sourceBuffer = new byte[6];
rng.NextBytes(sourceBuffer);
PhysicalAddress source = new PhysicalAddress(sourceBuffer);
byte[] targetBuffer = new byte[6];
rng.NextBytes(targetBuffer);
PhysicalAddress target = new PhysicalAddress(targetBuffer);
byte[] buffer = Properties.Resources.MultipartRegistrationResponseTest;
T45_V4_MultipartRegistrationResponse test = new T45_V4_MultipartRegistrationResponse(source, target, buffer);
Assert.True(test.Valid);
}
} }
} }

View File

@ -70,6 +70,16 @@ namespace skyscraper8.Tests.Properties {
} }
} }
/// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
/// </summary>
internal static byte[] MultipartRegistrationResponseTest {
get {
object obj = ResourceManager.GetObject("MultipartRegistrationResponseTest", resourceCulture);
return ((byte[])(obj));
}
}
/// <summary> /// <summary>
/// Sucht eine lokalisierte Ressource vom Typ System.Byte[]. /// Sucht eine lokalisierte Ressource vom Typ System.Byte[].
/// </summary> /// </summary>

View File

@ -121,6 +121,9 @@
<data name="ModemCapabilitiesEncodingTest" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="ModemCapabilitiesEncodingTest" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\ModemCapabilitiesEncodingTest.bin;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>..\Resources\ModemCapabilitiesEncodingTest.bin;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data> </data>
<data name="MultipartRegistrationResponseTest" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\T45_V4_MultipartRegistrationResponseTest.bin;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="ranging_response_test" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="ranging_response_test" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Resources\ranging_response_test.bin;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>..\Resources\ranging_response_test.bin;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data> </data>

View File

@ -1,4 +1,6 @@
using skyscraper5.Skyscraper.IO; using skyscraper5.Docsis.MacManagement;
using skyscraper5.Skyscraper.IO;
using skyscraper8.Docsis.AnnexC;
using skyscraper8.Docsis.DQoS; using skyscraper8.Docsis.DQoS;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -10,7 +12,7 @@ using System.Threading.Tasks;
namespace skyscraper5.Docsis.AnnexC namespace skyscraper5.Docsis.AnnexC
{ {
class CommonTlvEncodingObject public class CommonTlvEncodingObject
{ {
public CommonTlvEncodingObject(MemoryStream ms) public CommonTlvEncodingObject(MemoryStream ms)
{ {
@ -25,10 +27,14 @@ namespace skyscraper5.Docsis.AnnexC
ModemCapabilitiesEncoding = new ModemCapabilitiesEncoding(v); ModemCapabilitiesEncoding = new ModemCapabilitiesEncoding(v);
break; break;
case 22: case 22:
UpstreamDropPacketClassificationEncoding = new GeneralPacketClassifierEncoding(v); if (UpstreamDropPacketClassificationEncoding == null)
UpstreamDropPacketClassificationEncoding = new List<GeneralPacketClassifierEncoding>();
UpstreamDropPacketClassificationEncoding.Add(new GeneralPacketClassifierEncoding(v));
break; break;
case 23: case 23:
DownstreamPacketClassificationEncoding = new GeneralPacketClassifierEncoding(v); if (DownstreamPacketClassificationEncoding == null)
DownstreamPacketClassificationEncoding = new List<GeneralPacketClassifierEncoding>();
DownstreamPacketClassificationEncoding.Add(new GeneralPacketClassifierEncoding(v));
break; break;
case 24: case 24:
if (UpstreamServiceFlows == null) if (UpstreamServiceFlows == null)
@ -50,7 +56,9 @@ namespace skyscraper5.Docsis.AnnexC
KeySequenceNumber = v[0]; KeySequenceNumber = v[0];
break; break;
case 46: case 46:
TransmitChannelConfiguration = new TransmitChannelConfigurationObject(v); if (TransmitChannelConfiguration == null)
TransmitChannelConfiguration = new List<TransmitChannelConfigurationObject>();
TransmitChannelConfiguration.Add(new TransmitChannelConfigurationObject(v));
break; break;
case 47: case 47:
ServiceFlowSidClusterAssignment = new ServiceFlowSidClusterAssignmentObject(v); ServiceFlowSidClusterAssignment = new ServiceFlowSidClusterAssignmentObject(v);
@ -58,6 +66,11 @@ namespace skyscraper5.Docsis.AnnexC
case 49: case 49:
RcpId = new RcpIdEncoding(v); RcpId = new RcpIdEncoding(v);
break; break;
case 50:
if (DsidEncodings == null)
DsidEncodings = new List<DsidEncoding>();
DsidEncodings.Add(new DsidEncoding(v));
break;
default: default:
//CM-SP-MULPIv4.0-I01-190815.pdf page 652 //CM-SP-MULPIv4.0-I01-190815.pdf page 652
throw new NotImplementedException(string.Format("Common TLV Encodings Type {0}", type)); throw new NotImplementedException(string.Format("Common TLV Encodings Type {0}", type));
@ -67,11 +80,11 @@ namespace skyscraper5.Docsis.AnnexC
public ModemCapabilitiesEncoding ModemCapabilitiesEncoding { get; private set; } public ModemCapabilitiesEncoding ModemCapabilitiesEncoding { get; private set; }
public ServiceFlowSidClusterAssignmentObject ServiceFlowSidClusterAssignment { get; private set; } public ServiceFlowSidClusterAssignmentObject ServiceFlowSidClusterAssignment { get; private set; }
public GeneralPacketClassifierEncoding DownstreamPacketClassificationEncoding { get; set; } public List<GeneralPacketClassifierEncoding> DownstreamPacketClassificationEncoding { get; set; }
public GeneralPacketClassifierEncoding UpstreamDropPacketClassificationEncoding { get; set; } public List<GeneralPacketClassifierEncoding> UpstreamDropPacketClassificationEncoding { get; set; }
public TransmitChannelConfigurationObject TransmitChannelConfiguration { get; set; } public List<TransmitChannelConfigurationObject> TransmitChannelConfiguration { get; set; }
public class TransmitChannelConfigurationObject public class TransmitChannelConfigurationObject
{ {
public TransmitChannelConfigurationObject(byte[] buffer) public TransmitChannelConfigurationObject(byte[] buffer)
@ -93,10 +106,16 @@ namespace skyscraper5.Docsis.AnnexC
case 3: case 3:
UpstreamChannelId = v[0]; UpstreamChannelId = v[0];
break; break;
case 5:
this.UpstreamChannelDescriptor = new UpstreamChannelDescriptor(null, null, v);
break;
case 6: case 6:
(v[0], v[1]) = (v[1], v[0]); (v[0], v[1]) = (v[1], v[0]);
RangingSid = BitConverter.ToUInt16(v, 0); RangingSid = BitConverter.ToUInt16(v, 0);
break; break;
case 7:
InitializationTechnique = (InitalizationTechniqueEnum?)v[0];
break;
case 11: case 11:
ListOfIucs = v; ListOfIucs = v;
break; break;
@ -125,7 +144,9 @@ namespace skyscraper5.Docsis.AnnexC
} }
public byte? TccReferenceId { get; set; } public byte? TccReferenceId { get; set; }
} public InitalizationTechniqueEnum? InitializationTechnique { get; }
public UpstreamChannelDescriptor UpstreamChannelDescriptor { get; }
}
public byte KeySequenceNumber { get; set; } public byte KeySequenceNumber { get; set; }
@ -136,5 +157,6 @@ namespace skyscraper5.Docsis.AnnexC
public List<GeneralServiceFlowEncoding> UpstreamServiceFlows { get; } public List<GeneralServiceFlowEncoding> UpstreamServiceFlows { get; }
public RcpIdEncoding RcpId { get; private set; } public RcpIdEncoding RcpId { get; private set; }
public AuthorizationBlock AuthorizationHint { get; } public AuthorizationBlock AuthorizationHint { get; }
public List<DsidEncoding> DsidEncodings { get; private set; }
} }
} }

View File

@ -0,0 +1,92 @@
using skyscraper5.Skyscraper.IO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Channels;
using System.Threading.Tasks;
namespace skyscraper8.Docsis.AnnexC
{
public class DsidEncoding
{
public DsidEncoding(byte[] buffer)
{
MemoryStream ms = new MemoryStream(buffer, false);
while (ms.GetAvailableBytes() > 2)
{
byte type = ms.ReadUInt8();
byte length = ms.ReadUInt8();
byte[] v = ms.ReadBytes(length);
switch (type)
{
case 1:
byte[] uintBuffer = new byte[] { v[2], v[1], v[0], 0 };
DSID = BitConverter.ToUInt32(uintBuffer);
break;
case 2:
DownstreamServiceIdentifierAction = (DownstreamServiceIdentifierActionEnum)v[0];
break;
case 3:
DownstreamResequencingEncodings = new EncodedResequencingAttributes(v);
break;
case 4:
MulticastEncodings = new EncodedMulticastAttributes(v);
break;
default:
//CM-SP-MULPIv4.0-I01-190815.pdf, page 731
throw new NotImplementedException(String.Format("DSID Encoding 50.{0}", type));
}
}
}
public uint? DSID { get; }
public DownstreamServiceIdentifierActionEnum? DownstreamServiceIdentifierAction { get; }
public enum DownstreamServiceIdentifierActionEnum
{
Add = 0,
Change = 1,
Delete = 2
}
public EncodedResequencingAttributes DownstreamResequencingEncodings { get; }
internal EncodedMulticastAttributes MulticastEncodings { get; }
public class EncodedResequencingAttributes
{
public EncodedResequencingAttributes(byte[] buffer)
{
MemoryStream ms = new MemoryStream(buffer, false);
while (ms.GetAvailableBytes() > 2)
{
byte type = ms.ReadUInt8();
byte length = ms.ReadUInt8();
byte[] v = ms.ReadBytes(length);
switch (type)
{
case 1:
IsResequencing = v[0] == 1;
break;
case 2:
DownstreamResequencingChannelList = v;
break;
case 3:
DsidResequencingWaitTime = v[0];
break;
default:
//CM-SP-MULPIv4.0-I01-190815.pdf, page 731
throw new NotImplementedException(String.Format("EncodedResequencingAttributes 50.3.{0}", type));
}
}
}
public bool? IsResequencing { get; }
public byte[] DownstreamResequencingChannelList { get; }
public byte DsidResequencingWaitTime { get; }
}
}
}

View File

@ -0,0 +1,31 @@
using skyscraper5.Skyscraper.IO;
using static skyscraper8.Docsis.AnnexC.DsidEncoding;
namespace skyscraper8.Docsis.AnnexC
{
internal class EncodedMulticastAttributes
{
public EncodedMulticastAttributes(byte[] buffer)
{
MemoryStream ms = new MemoryStream(buffer, false);
while (ms.GetAvailableBytes() > 2)
{
byte type = ms.ReadUInt8();
byte length = ms.ReadUInt8();
byte[] v = ms.ReadBytes(length);
switch (type)
{
case 2:
this.MulticastCmInterfaceMask = new MulticastCmInterfaceMask(v);
break;
default:
//CM-SP-MULPIv4.0-I01-190815.pdf, page 732
throw new NotImplementedException(String.Format("DSID Encoding 50.4.{0}", type));
}
}
}
public MulticastCmInterfaceMask MulticastCmInterfaceMask { get; }
}
}

View File

@ -0,0 +1,36 @@
using skyscraper5.Skyscraper.IO;
using skyscraper8.Docsis.DQoS;
using System;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace skyscraper5.Docsis.AnnexC
{
public class EthernetLlcPacketClassificationEncoding
{
public EthernetLlcPacketClassificationEncoding(byte[] buffer)
{
MemoryStream ms = new MemoryStream(buffer, false);
while (ms.GetAvailableBytes() > 3)
{
byte type = ms.ReadUInt8();
ushort length = ms.ReadUInt8();
byte[] v = ms.ReadBytes(length);
switch (type)
{
case 3:
(v[1], v[2]) = (v[2], v[1]);
this.Type = v[0];
this.EProt = BitConverter.ToUInt16(v, 1);
break;
default:
//CM-SP-MULPIv4.0-I01-190815.pdf, page 747
throw new NotImplementedException(string.Format("EthernetLlcPacketClassificationEncoding [22/23/60].10.{0}", type));
}
}
}
public byte Type { get; }
public ushort EProt { get; }
}
}

View File

@ -9,7 +9,7 @@ using skyscraper5.Skyscraper.IO;
namespace skyscraper5.Docsis.AnnexC namespace skyscraper5.Docsis.AnnexC
{ {
internal class GeneralPacketClassifierEncoding public class GeneralPacketClassifierEncoding
{ {
public GeneralPacketClassifierEncoding(byte[] buffer) public GeneralPacketClassifierEncoding(byte[] buffer)
{ {
@ -49,7 +49,13 @@ namespace skyscraper5.Docsis.AnnexC
case 9: case 9:
Ipv4PacketClassification = new Ipv4PacketClassificationEncodings(v); Ipv4PacketClassification = new Ipv4PacketClassificationEncodings(v);
break; break;
default: case 10:
EthernetLlcPacketClassificationEncodings = new EthernetLlcPacketClassificationEncoding(v);
break;
case 12:
Ipv6PacketClassification = new Ipv6PacketClassificationEncoding(v);
break;
default:
//see CM-SP-MULPIv4.0-I01-190815.pdf page 742->743 //see CM-SP-MULPIv4.0-I01-190815.pdf page 742->743
throw new NotImplementedException(string.Format("{0} TLV Type {1}", nameof(GeneralPacketClassifierEncoding), type)); throw new NotImplementedException(string.Format("{0} TLV Type {1}", nameof(GeneralPacketClassifierEncoding), type));
} }
@ -87,10 +93,16 @@ namespace skyscraper5.Docsis.AnnexC
case 3: case 3:
Ipv4SourceAddress = new IPAddress(v); Ipv4SourceAddress = new IPAddress(v);
break; break;
case 4:
Ipv4SourceMask = new IPAddress(v);
break;
case 5: case 5:
Ipv4DestinationAddress = new IPAddress(v); Ipv4DestinationAddress = new IPAddress(v);
break; break;
case 7: case 6:
Ipv4DestinationMask = new IPAddress(v);
break;
case 7:
(v[0], v[1]) = (v[1], v[0]); (v[0], v[1]) = (v[1], v[0]);
SourcePortStart = BitConverter.ToUInt16(v, 0); SourcePortStart = BitConverter.ToUInt16(v, 0);
break; break;
@ -126,7 +138,9 @@ namespace skyscraper5.Docsis.AnnexC
public ushort? SourcePortStart { get; set; } public ushort? SourcePortStart { get; set; }
public ushort? SourcePortEnd { get; set; } public ushort? SourcePortEnd { get; set; }
} public IPAddress Ipv4SourceMask { get; private set; }
public IPAddress Ipv4DestinationMask { get; private set; }
}
public ushort? ServiceFlowReference { get; set; } public ushort? ServiceFlowReference { get; set; }
public byte? ClassifierReference { get; set; } public byte? ClassifierReference { get; set; }
@ -134,5 +148,7 @@ namespace skyscraper5.Docsis.AnnexC
public ushort? ClassifierIdentifier { get; set; } public ushort? ClassifierIdentifier { get; set; }
public uint? ServiceFlowIdentifier { get; set; } public uint? ServiceFlowIdentifier { get; set; }
} public EthernetLlcPacketClassificationEncoding EthernetLlcPacketClassificationEncodings { get; }
internal Ipv6PacketClassificationEncoding Ipv6PacketClassification { get; }
}
} }

View File

@ -5,10 +5,11 @@ using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using skyscraper5.Skyscraper.IO; using skyscraper5.Skyscraper.IO;
using static skyscraper5.Dvb.Descriptors.ServiceListDescriptor;
namespace skyscraper5.Docsis.AnnexC namespace skyscraper5.Docsis.AnnexC
{ {
internal class GeneralServiceFlowEncoding public class GeneralServiceFlowEncoding
{ {
public GeneralServiceFlowEncoding(byte[] buffer) public GeneralServiceFlowEncoding(byte[] buffer)
{ {
@ -56,7 +57,11 @@ namespace skyscraper5.Docsis.AnnexC
(v[0], v[1]) = (v[1], v[0]); (v[0], v[1]) = (v[1], v[0]);
TimeoutForActiveQosParameters = BitConverter.ToUInt16(v, 0); TimeoutForActiveQosParameters = BitConverter.ToUInt16(v, 0);
break; break;
case 15: case 14:
(v[0], v[1]) = (v[1], v[0]);
MaximumConcatenatedBurst = BitConverter.ToUInt16(v, 0);
break;
case 15:
ServiceFlowSchedulingType = (ServiceFlowSchedulingTypeEnum)v[0]; ServiceFlowSchedulingType = (ServiceFlowSchedulingTypeEnum)v[0];
break; break;
case 16: case 16:
@ -98,11 +103,22 @@ namespace skyscraper5.Docsis.AnnexC
case 22: case 22:
GrantsPerInterval = v[0]; GrantsPerInterval = v[0];
break; break;
case 23:
IpTypeOfServiceOverwrite = v;
break;
case 24: case 24:
(v[0], v[1], v[2], v[3]) = (v[3], v[2], v[1], v[0]); (v[0], v[1], v[2], v[3]) = (v[3], v[2], v[1], v[0]);
CmtsTimestamp = BitConverter.ToUInt32(v, 0); CmtsTimestamp = BitConverter.ToUInt32(v, 0);
break; break;
default: case 26:
MultiplierToNumberOfBytesRequested = v[0];
break;
case 32:
(v[0], v[1], v[2], v[3]) = (v[3], v[2], v[1], v[0]);
ServiceFlowForbiddenAttributeMask = BitConverter.ToUInt32(v);
break;
default:
//CM-SP-MULPIv4.0-I01-190815.pdf page 758 //CM-SP-MULPIv4.0-I01-190815.pdf page 758
throw new NotImplementedException(string.Format("General Service Flow Encodings Type {0}", type)); throw new NotImplementedException(string.Format("General Service Flow Encodings Type {0}", type));
} }
@ -177,8 +193,12 @@ namespace skyscraper5.Docsis.AnnexC
public bool? AdmittedSet { get; set; } public bool? AdmittedSet { get; set; }
public bool? ProvisionedSet { get; set; } public bool? ProvisionedSet { get; set; }
public byte[] IpTypeOfServiceOverwrite { get; }
public ushort MaximumConcatenatedBurst { get; }
public byte MultiplierToNumberOfBytesRequested { get; }
public uint ServiceFlowForbiddenAttributeMask { get; }
public override string ToString() public override string ToString()
{ {
return $"{nameof(ServiceFlowIdentifier)}: {ServiceFlowIdentifier}"; return $"{nameof(ServiceFlowIdentifier)}: {ServiceFlowIdentifier}";
} }

View File

@ -0,0 +1,14 @@
namespace skyscraper5.Docsis.AnnexC
{
public enum InitalizationTechniqueEnum : byte
{
BroadcastInitialRanging = 1,
UnicastInitialRanging = 2,
EitherBroadcastOrUnicast = 3,
NewChannel = 4,
ProbeNewChannel = 5,
UnicastInitialRangingOnNewChannel = 6,
StationRanging = 7,
AssumeSucessful = 8
}
}

View File

@ -0,0 +1,39 @@
using skyscraper5.Skyscraper.IO;
using System.Net;
namespace skyscraper5.Docsis.AnnexC
{
internal class Ipv6PacketClassificationEncoding
{
public Ipv6PacketClassificationEncoding(byte[] buffer)
{
MemoryStream ms = new MemoryStream(buffer, false);
while (ms.GetAvailableBytes() > 3)
{
byte type = ms.ReadUInt8();
ushort length = ms.ReadUInt8();
byte[] v = ms.ReadBytes(length);
switch (type)
{
case 3:
(v[0], v[1]) = (v[1], v[0]);
NextHeaderType = BitConverter.ToUInt16(v, 0);
break;
case 4:
Ipv6SourceAddress = new IPAddress(v);
break;
case 6:
Ipv6DestinationAddress = new IPAddress(v);
break;
default:
//CM-SP-MULPIv4.0-I01-190815.pdf, page 749
throw new NotImplementedException(string.Format("Ipv6PacketClassificationEncoding [22/23/60].12.{0}", type));
}
}
}
public ushort NextHeaderType { get; }
public IPAddress Ipv6DestinationAddress { get; }
public IPAddress Ipv6SourceAddress { get; }
}
}

View File

@ -0,0 +1,30 @@
using skyscraper5.Mpeg2.Descriptors;
namespace skyscraper8.Docsis.AnnexC
{
internal class MulticastCmInterfaceMask
{
public MulticastCmInterfaceMask(byte[] v)
{
uint buffered = BitConverter.ToUInt32(v, 0);
CmIpStack = (buffered & 0x00000001) != 0;
PrimaryCpeInterfae = (buffered & 0x00000002) != 0;
RfInterface = (buffered & 0x00000004) != 0;
//Reserved = (buffered & 0x00000018) != 0;
OtherCpeInterfaces = (buffered & 0x0000ffe0) != 0;
PacketCableEmta = (buffered & 0x00010000) != 0;
EstbIp = (buffered & 0x00020000) != 0;
//Reserved = (buffered & 0x00040000) != 0;
OtherESafeInterfaces = (buffered & 0xfff80000) != 0;
}
public bool CmIpStack { get; }
public bool PrimaryCpeInterfae { get; }
public bool RfInterface { get; }
public bool OtherCpeInterfaces { get; }
public bool PacketCableEmta { get; }
public bool EstbIp { get; }
public bool OtherESafeInterfaces { get; }
}
}

View File

@ -10,7 +10,7 @@ using static skyscraper5.src.InteractionChannel.Model2.Tbtp2;
namespace skyscraper5.Docsis.AnnexC namespace skyscraper5.Docsis.AnnexC
{ {
internal class RcpIdEncoding public class RcpIdEncoding
{ {
public RcpIdEncoding(byte[] buffer) public RcpIdEncoding(byte[] buffer)
{ {
@ -35,7 +35,7 @@ namespace skyscraper5.Docsis.AnnexC
public SimplifiedReceiveChannelAssignmentEncoding SimplifiedReceiveChannelConfiguration { get; private set; } public SimplifiedReceiveChannelAssignmentEncoding SimplifiedReceiveChannelConfiguration { get; private set; }
} }
class SimplifiedReceiveChannelAssignmentEncoding public class SimplifiedReceiveChannelAssignmentEncoding
{ {
public SimplifiedReceiveChannelAssignmentEncoding(byte[] buffer) public SimplifiedReceiveChannelAssignmentEncoding(byte[] buffer)
{ {

View File

@ -8,7 +8,7 @@ using skyscraper5.Skyscraper.IO;
namespace skyscraper5.Docsis.AnnexC namespace skyscraper5.Docsis.AnnexC
{ {
internal class ServiceFlowSidClusterAssignmentObject public class ServiceFlowSidClusterAssignmentObject
{ {
public ServiceFlowSidClusterAssignmentObject(byte[] buffer) public ServiceFlowSidClusterAssignmentObject(byte[] buffer)
{ {

View File

@ -8,7 +8,7 @@ using System.Threading.Tasks;
namespace skyscraper8.Docsis.DQoS namespace skyscraper8.Docsis.DQoS
{ {
internal class AuthorizationBlock : Validatable public class AuthorizationBlock : Validatable
{ {
public AuthorizationBlock(byte[] buffer) public AuthorizationBlock(byte[] buffer)
{ {

View File

@ -8,7 +8,7 @@ using System.Threading.Tasks;
namespace skyscraper8.Docsis.DQoS namespace skyscraper8.Docsis.DQoS
{ {
internal class PacketCableAuthorizationBlockEncoding : Validatable public class PacketCableAuthorizationBlockEncoding : Validatable
{ {
public PacketCableAuthorizationBlockEncoding(byte[] buffer) public PacketCableAuthorizationBlockEncoding(byte[] buffer)
{ {

View File

@ -28,6 +28,11 @@ namespace skyscraper5.Docsis.MacManagement
{ {
byte type = ms.ReadUInt8(); byte type = ms.ReadUInt8();
byte length = ms.ReadUInt8(); byte length = ms.ReadUInt8();
if (ms.GetAvailableBytes() < length)
{
Valid = false;
return;
}
byte[] v = ms.ReadBytes(length); byte[] v = ms.ReadBytes(length);
switch (type) switch (type)
{ {

View File

@ -8,7 +8,7 @@ namespace skyscraper5.Docsis.MacManagement
{ {
[SkyscraperPlugin] [SkyscraperPlugin]
[MacManagementMessageType(4,45)] [MacManagementMessageType(4,45)]
internal class T45_V4_MultipartRegistrationResponse : MacManagementMessage public class T45_V4_MultipartRegistrationResponse : MacManagementMessage
{ {
public T45_V4_MultipartRegistrationResponse(PhysicalAddress source, PhysicalAddress destination, byte[] buffer) : base(source, destination, buffer) public T45_V4_MultipartRegistrationResponse(PhysicalAddress source, PhysicalAddress destination, byte[] buffer) : base(source, destination, buffer)
{ {
@ -18,6 +18,7 @@ namespace skyscraper5.Docsis.MacManagement
NumberOfFragments = ms.ReadUInt8(); NumberOfFragments = ms.ReadUInt8();
FragmentSequenceNumber = ms.ReadUInt8(); FragmentSequenceNumber = ms.ReadUInt8();
TlvEncodedInformation = new CommonTlvEncodingObject(ms); TlvEncodedInformation = new CommonTlvEncodingObject(ms);
Valid = true;
} }
public CommonTlvEncodingObject TlvEncodedInformation { get; set; } public CommonTlvEncodingObject TlvEncodedInformation { get; set; }

View File

@ -150,19 +150,20 @@ namespace skyscraper8.Skyscraper.IO
public override bool CanRead => throw new NotImplementedException(); public override bool CanRead => throw new NotImplementedException();
public override bool CanSeek => throw new NotImplementedException(); public override bool CanSeek => false;
public override bool CanWrite => throw new NotImplementedException(); public override bool CanWrite => false;
public override long Length => throw new NotImplementedException(); public override long Length => throw new NotSupportedException();
public override long Position { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } public override long Position { get => actuallyRead; set => throw new NotSupportedException(); }
public override void Flush() public override void Flush()
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
private long actuallyRead;
public override int Read(byte[] buffer, int offset, int count) public override int Read(byte[] buffer, int offset, int count)
{ {
int result = 0; int result = 0;
@ -173,6 +174,7 @@ namespace skyscraper8.Skyscraper.IO
{ {
if (!GetNextSegment()) if (!GetNextSegment())
{ {
actuallyRead += result;
return result; return result;
} }
continue; continue;
@ -181,6 +183,7 @@ namespace skyscraper8.Skyscraper.IO
count -= readResult; count -= readResult;
result += readResult; result += readResult;
} }
actuallyRead += result;
return result; return result;
} }