diff --git a/skyscraper8/InteractionChannel/InteractionChannelHandler.cs b/skyscraper8/InteractionChannel/InteractionChannelHandler.cs index 2a34fa4..8a94a1e 100644 --- a/skyscraper8/InteractionChannel/InteractionChannelHandler.cs +++ b/skyscraper8/InteractionChannel/InteractionChannelHandler.cs @@ -30,5 +30,6 @@ namespace skyscraper5.src.InteractionChannel void OnReturnTransmissionMOdes(PhysicalAddress macAddress, _0xb2_ReturnTransmissionModesDescriptor descriptor); void OnConnectionControl(PhysicalAddress macAddress, _0xaf_ConnectionControlDescriptor descriptor); void OnTerminalBurstTimePlan2(ushort interactiveNetworkId, Tbtp2 tbtp2); + void OnFrameComposition2(ushort? networkId, Fct2 fct2); } } diff --git a/skyscraper8/InteractionChannel/InteractionChannelPsiGatherer.cs b/skyscraper8/InteractionChannel/InteractionChannelPsiGatherer.cs index 1c84f37..36b5564 100644 --- a/skyscraper8/InteractionChannel/InteractionChannelPsiGatherer.cs +++ b/skyscraper8/InteractionChannel/InteractionChannelPsiGatherer.cs @@ -204,7 +204,9 @@ namespace skyscraper5.src.InteractionChannel _handler.OnInteractionChannelError(InteractionChannelErrorState.Fct2Invalid); return; } - throw new NotImplementedException("FCT2"); + + Handler.OnFrameComposition2(NetworkId, fct2); + return; case 0xAC: //BCT //see en_30154502v010401p.pdf, page 49 throw new NotImplementedException("BCT"); diff --git a/skyscraper8/InteractionChannel/Model2/Fct2.cs b/skyscraper8/InteractionChannel/Model2/Fct2.cs index 4f38348..a9c837a 100644 --- a/skyscraper8/InteractionChannel/Model2/Fct2.cs +++ b/skyscraper8/InteractionChannel/Model2/Fct2.cs @@ -9,11 +9,12 @@ using skyscraper5.Skyscraper.IO; namespace skyscraper5.src.InteractionChannel.Model2 { - internal class Fct2 : Validatable + public class Fct2 : Validatable { public Fct2(MemoryStream ms) { byte frameTypeLoopCount = ms.ReadUInt8(); + frameTypeLoopCount--; FrameTypes = new Frame[frameTypeLoopCount]; for (int i = 0; i < frameTypeLoopCount; i++) { diff --git a/skyscraper8/InteractionChannel/NullInteractionChannelHandler.cs b/skyscraper8/InteractionChannel/NullInteractionChannelHandler.cs index ea1b879..906a5f7 100644 --- a/skyscraper8/InteractionChannel/NullInteractionChannelHandler.cs +++ b/skyscraper8/InteractionChannel/NullInteractionChannelHandler.cs @@ -27,6 +27,11 @@ namespace skyscraper5.src.InteractionChannel } + public void OnFrameComposition2(ushort? networkId, Fct2 fct2) + { + throw new NotImplementedException(); + } + public void OnContentionControl(PhysicalAddress macAddress, _0xab_ContentionControlDescriptor ccd) { } diff --git a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs index 36e2d3d..a929c5e 100644 --- a/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs +++ b/skyscraper8/Skyscraper/Scraper/SkyscraperContext.cs @@ -2413,6 +2413,18 @@ namespace skyscraper5.Skyscraper.Scraper } } + public void OnFrameComposition2(ushort? networkId, Fct2 fct2) + { + foreach (Fct2.Frame frame in fct2.FrameTypes) + { + if (!DataStorage.TestForFrameComposition2(networkId.Value, frame)) + { + LogEvent(SkyscraperContextEvent.FrameComposition2,String.Format("Network ID = {0}, Frame Type = {1}",networkId.Value,frame.FrameType)); + DataStorage.InsertFct2Frame(networkId.Value, frame); + } + } + } + void InteractionChannelHandler.OnTimeslotComposition(ushort interactiveNetworkId, Tct tct) { throw new NotImplementedException(); diff --git a/skyscraper8/Skyscraper/Scraper/SkyscraperContextEvent.cs b/skyscraper8/Skyscraper/Scraper/SkyscraperContextEvent.cs index d0b6f3c..30d04e2 100644 --- a/skyscraper8/Skyscraper/Scraper/SkyscraperContextEvent.cs +++ b/skyscraper8/Skyscraper/Scraper/SkyscraperContextEvent.cs @@ -86,6 +86,7 @@ OtvSsuComplete, NdsSsuFileAnnounced, NdsSsuProgress, - TerminalBurstTimePlan2 + TerminalBurstTimePlan2, + FrameComposition2 } } diff --git a/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs index 28e5ddb..7a9e3e2 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs @@ -196,5 +196,7 @@ namespace skyscraper8.Skyscraper.Scraper.Storage object[] GetLastUiBlindscanSettings(); bool TestForTerminalBurstTimePlan2(ushort interactiveNetworkId, byte tbtp2GroupId, byte frameFrameNumber); void StoreTerminalBurstTimePlan2(ushort interactiveNetworkId, byte tbtp2GroupId, Tbtp2.Frame frame); + bool TestForFrameComposition2(ushort networkId, Fct2.Frame fct2); + void InsertFct2Frame(ushort networkId, Fct2.Frame frame); } } diff --git a/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs index becfd08..5f4af87 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/Filesystem/FilesystemStorage.cs @@ -1166,6 +1166,16 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.Filesystem throw new NotImplementedException(); } + public bool TestForFrameComposition2(ushort networkId, Fct2.Frame fct2) + { + throw new NotImplementedException(); + } + + public void InsertFct2Frame(ushort networkId, Fct2.Frame frame) + { + throw new NotImplementedException(); + } + public IEnumerable> SelectAllPmt() { throw new NotImplementedException(); diff --git a/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs index bc4d6db..cbb1783 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/InMemory/InMemoryScraperStorage.cs @@ -986,6 +986,25 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.InMemory _tbtp2.Add(key, frame); } + private Dictionary, Fct2.Frame> _fct2Frames; + public bool TestForFrameComposition2(ushort networkId, Fct2.Frame fct2) + { + if (_fct2Frames == null) + return false; + + Tuple key = new Tuple(networkId, fct2.FrameType); + return _fct2Frames.ContainsKey(key); + } + + public void InsertFct2Frame(ushort networkId, Fct2.Frame frame) + { + if (_fct2Frames == null) + _fct2Frames = new Dictionary, Fct2.Frame>(); + + Tuple key = new Tuple(networkId, frame.FrameType); + _fct2Frames.Add(key, frame); + } + public IEnumerable> SelectAllPmt() { for (int x = 0; x < pmtEntries.Length; x++) diff --git a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/InteractionChannelContestant.cs b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/InteractionChannelContestant.cs index bfd8d19..761ae6b 100644 --- a/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/InteractionChannelContestant.cs +++ b/skyscraper8/Skyscraper/Scraper/StreamAutodetection/Contestants/InteractionChannelContestant.cs @@ -192,5 +192,10 @@ namespace skyscraper5.src.Skyscraper.Scraper.StreamAutodetection.Contestants Score++; } } + + public void OnFrameComposition2(ushort? networkId, Fct2 fct2) + { + throw new NotImplementedException(); + } } }