diff --git a/skyscraper8/Atsc/A322/AtscPlpBasebandParser.cs b/skyscraper8/Atsc/A322/AtscPlpBasebandParser.cs new file mode 100644 index 0000000..e4e1587 --- /dev/null +++ b/skyscraper8/Atsc/A322/AtscPlpBasebandParser.cs @@ -0,0 +1,71 @@ +using skyscraper5.Skyscraper.IO; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; +using static skyscraper5.Dvb.SystemSoftwareUpdate.SystemSoftwareUpdateInfo; + +namespace skyscraper8.Atsc.A322 +{ + internal class AtscPlpBasebandParser + { + internal void PushBbframe(byte[] payload) + { + MemoryStream ms = new MemoryStream(payload); + byte a = ms.ReadUInt8(); + bool mode = ((a >> 7) & 0x01) != 0; + int pointer = (a & 0x7f); + int addToPointer; + + if (!mode) + { + //1 byte done. + addToPointer = 1; + } + else + { + addToPointer = 2; + byte b = ms.ReadUInt8(); + pointer |= (((b >> 2) & 0x3F) << 7); + OfiDescription ofi = (OfiDescription)(b & 0x3); + switch(ofi) + { + case OfiDescription.NoExtensionMode: + break; + case OfiDescription.LongExtensionMode: + byte lc = ms.ReadUInt8(); + addToPointer++; + int extType = (lc >> 5) & 0x7; + int extLen = (lc) & 0x1F; + byte ld = ms.ReadUInt8(); + addToPointer++; + extLen |= (((ld) & 0xFF) << 5); + // see A322-2026-04-Physical-Layer-Protocol.pdf, Table 5.2 + //0 = counter + //7 = padding + byte[] extensionFiled = ms.ReadBytes(extLen); + addToPointer += extLen; + if (extType != 7) + { + throw new NotImplementedException(String.Format("ATSC 3.0 BBFRAME Padding Type {0} not yet implemented.", extType)); + } + break; + default: + throw new NotImplementedException(String.Format("{0} is not yet implemented in the ATSC 3.0 BBFrame Parser.", ofi)); + } + } + + throw new NotImplementedException("Actually do the ATSC packets here.") + } + } + + internal enum OfiDescription + { + NoExtensionMode, + ShortExtensionMode, + LongExtensionMode, + MixedExtensionMode, + } +} diff --git a/skyscraper8/Atsc/A324/BasebandPacketDataStreamReceiver.cs b/skyscraper8/Atsc/A324/BasebandPacketDataStreamReceiver.cs new file mode 100644 index 0000000..cb59528 --- /dev/null +++ b/skyscraper8/Atsc/A324/BasebandPacketDataStreamReceiver.cs @@ -0,0 +1,134 @@ +using log4net; +using skyscraper5.Ietf.Rfc768; +using skyscraper5.Ietf.Rfc971; +using skyscraper5.Skyscraper.IO; +using skyscraper5.Skyscraper.Net.Pcap; +using skyscraper5.Skyscraper.Plugins; +using skyscraper5.Skyscraper.Scraper; +using skyscraper8.Atsc.A322; +using skyscraper8.Ietf.Rfc3550_RTP; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.Atsc.A324 +{ + [SkyscraperPlugin] + internal class BasebandPacketDataStreamReceiver : ISkyscraperMpePlugin + { + private static readonly ILog logger = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name); + private readonly IPAddress BPPS_IP_ADDRESS = IPAddress.Parse("239.0.51.48"); + private byte[] plpIndexHelpBuffer = new byte[2]; + + public bool CanHandlePacket(InternetHeader internetHeader, byte[] ipv4Packet) + { + if (internetHeader.Protocol != 0x11) + return false; + + if (ipv4Packet[8] != 0x80) + return false; + + if (!internetHeader.DestinationAddress.Equals(BPPS_IP_ADDRESS)) + return false; + + if (BitConverter.IsLittleEndian) + { + plpIndexHelpBuffer[0] = ipv4Packet[3]; + plpIndexHelpBuffer[1] = ipv4Packet[2]; + } + else + { + plpIndexHelpBuffer[0] = ipv4Packet[2]; + plpIndexHelpBuffer[1] = ipv4Packet[3]; + } + + ushort dstPort = BitConverter.ToUInt16(plpIndexHelpBuffer, 0); + + if (dstPort < 30000) + return false; + + if (dstPort > 30066) + return false; + + + return true; + } + + public void ConnectToStorage(object[] connector) + { + throw new NotImplementedException(); + } + + private bool warnedAboutNonMarkedPackets; + public void HandlePacket(InternetHeader internetHeader, byte[] ipv4Packet) + { + UserDatagram udpPacket = new UserDatagram(ipv4Packet); + ushort plp = (ushort)(udpPacket.DestinationPort - 30000); + RtpPacket rtpPacket = new RtpPacket(udpPacket.Payload); + + if (!rtpPacket.RtpMarker) + { + if (!warnedAboutNonMarkedPackets) + { + logger.WarnFormat("ATSC 3.0 BBFRAMEs spanning multiple packets are not supported yet. It would be great if you could share a sample of this, so this can be implemented."); + warnedAboutNonMarkedPackets = true; + } + return; + } + + if (plp == 64) + { + HandlePreambleData(rtpPacket.RtpPayload); + return; + } + else if (plp == 65) + { + HandleTimingAndManagementData(rtpPacket.RtpPayload); + return; + } + else if (plp <= 63) + { + HandlePlp(plp, rtpPacket.RtpPayload); + return; + } + } + + private AtscPlpBasebandParser[] plps; + private void HandlePlp(ushort plp, byte[] rtpPayload) + { + if (plps == null) + { + plps = new AtscPlpBasebandParser[64]; + } + if (plps[plp] == null) + { + plps[plp] = new AtscPlpBasebandParser(); + } + plps[plp].PushBbframe(rtpPayload); + } + + private void HandleTimingAndManagementData(byte[] rtpPayload) + { + throw new NotImplementedException(); + } + + private void HandlePreambleData(byte[] rtpPayload) + { + throw new NotImplementedException(); + } + + private SkyscraperContext context; + public void SetContext(DateTime? currentTime, object skyscraperContext) + { + context = skyscraperContext as SkyscraperContext; + } + + public bool StopProcessingAfterThis() + { + return true; + } + } +} diff --git a/skyscraper8/Atsc/A324/StltpReceiver.cs b/skyscraper8/Atsc/A324/StltpReceiver.cs index d626c16..02bf987 100644 --- a/skyscraper8/Atsc/A324/StltpReceiver.cs +++ b/skyscraper8/Atsc/A324/StltpReceiver.cs @@ -114,8 +114,6 @@ namespace skyscraper8.Atsc.A324 } break; case 4: //Deliver the packet - currentIpPacketBuffer[20] = 0x69; - currentIpPacketBuffer[21] = 0x69; context.OnIpDatagram(0x1fff, currentIpPacketBuffer.AsSpan().Slice(0, currentIpPacketBufferOffset).ToArray()); stateMachineState = 1; break; diff --git a/skyscraper8/Skyscraper/Net/Pcap/TcpdumpNetworkType.cs b/skyscraper8/Skyscraper/Net/Pcap/TcpdumpNetworkType.cs index 42c2cce..ac557ee 100644 --- a/skyscraper8/Skyscraper/Net/Pcap/TcpdumpNetworkType.cs +++ b/skyscraper8/Skyscraper/Net/Pcap/TcpdumpNetworkType.cs @@ -13,6 +13,15 @@ namespace skyscraper5.Skyscraper.Net.Pcap PPPoE = 51, RawIp = 101, WLAN = 105, - UserDefined = 147 + FibreChannel = 122, + DocsisMac = 143, + /// + /// Voile uses DLT_USER0 for LLC PDUs + /// + UserDefined = 147, + /// + /// Voile uses DLT_USER1 for RTP packets without any Transport layer headers. + /// + UserDefined2 = 148, } }