public Tuple <int, byte[]> CreatePacket(byte[] data) { int apid = -1; while (true) { if (data.Length < 6) { return(Tuple.Create(-1, data)); } MSDU msdu = MSDU.parseMSDU(data); temporaryStorage[msdu.APID] = msdu; apid = msdu.APID; if (msdu.RemainingData.Length > 0 || msdu.Full) { data = msdu.RemainingData; msdu.RemainingData = new byte[0]; FinishMSDU(msdu); temporaryStorage.Remove(msdu.APID); apid = -1; } else { break; } } return(Tuple.Create(apid, new byte[0])); }
public void FinishMSDU(MSDU msdu) { try { if (msdu.APID == 2047) { // Skip fill packet return; } bool firstOrSinglePacket = msdu.Sequence == SequenceType.FIRST_SEGMENT || msdu.Sequence == SequenceType.SINGLE_DATA; Packets++; if (manager != null) { manager.Packets++; } if (!msdu.Valid) { CRCFails++; if (manager != null) { manager.CRCFails++; } } if (manager != null) { LengthFails++; if (!msdu.Full) { manager.LengthFails++; } } if (!msdu.Valid || !msdu.Full) { if (msdu.FrameLost) { UIConsole.Error($"Lost some frames on MSDU, the file will be corrupted. CRC Match: {msdu.Valid} - Size Match: {msdu.Full}"); } else { UIConsole.Error($"Corrupted MSDU. CRC Match: {msdu.Valid} - Size Match: {msdu.Full}"); } } if (msdu.Sequence == SequenceType.FIRST_SEGMENT || msdu.Sequence == SequenceType.SINGLE_DATA) { if (startnum != -1) { UIConsole.Warn("Received First Segment but last data wasn't finished! Forcing dump."); // This can only happen for multi-segment file. filename = Path.Combine(FileHandler.TemporaryFileFolder, channelId.ToString()); filename = Path.Combine(filename, $"{lastMSDU.APID}_{lastMSDU.Version}.lrit"); FileHandler.HandleFile(filename, fileHeader, manager); startnum = -1; endnum = -1; } fileHeader = FileParser.GetHeader(msdu.Data.Skip(10).ToArray()); if (msdu.Sequence == SequenceType.FIRST_SEGMENT) { startnum = msdu.PacketNumber; } } else if (msdu.Sequence == SequenceType.LAST_SEGMENT) { endnum = msdu.PacketNumber; if (startnum == -1) { // Orphan Packet endnum = -1; return; } } else if (msdu.Sequence != SequenceType.SINGLE_DATA && startnum == -1) { // Orphan Packet return; } // LRIT EMWIN /* Uncomment to enable EMWIN Ingestor * Its broken right now * if (fileHeader.PrimaryHeader.FileType == FileTypeCode.EMWIN) { * //Ingestor * int offset = 10 + (int)fileHeader.PrimaryHeader.HeaderLength; * EMWIN.Ingestor.Process(msdu.Data.Skip(offset).ToArray()); * return; * } */ string path = Path.Combine(FileHandler.TemporaryFileFolder, channelId.ToString()); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } filename = Path.Combine(path, $"{msdu.APID}_{msdu.Version}.lrit"); byte[] dataToSave = msdu.Data.Skip(firstOrSinglePacket ? 10 : 0).Take(firstOrSinglePacket ? msdu.PacketLength - 10 : msdu.PacketLength).ToArray(); if (fileHeader.Compression == CompressionType.LRIT_RICE && !firstOrSinglePacket) { int missedPackets = lastMSDU.PacketNumber - msdu.PacketNumber - 1; if (lastMSDU.PacketNumber == 16383 && msdu.PacketNumber == 0) { missedPackets = 0; } if (missedPackets > 0) { UIConsole.Warn(String.Format("Missed {0} packets on image. Filling with null bytes. Last Packet Number: {1} Current: {2}", missedPackets, lastMSDU.PacketNumber, msdu.PacketNumber)); byte[] fill = Decompress.GenerateFillData(fileHeader.ImageStructureHeader.Columns); using (FileStream fs = new FileStream(filename, FileMode.Append, FileAccess.Write)) { using (BinaryWriter sw = new BinaryWriter(fs)) { while (missedPackets > 0) { sw.Write(fill); missedPackets--; } sw.Flush(); } } } dataToSave = Decompress.InMemoryDecompress(dataToSave, fileHeader.ImageStructureHeader.Columns, fileHeader.RiceCompressionHeader.Pixel, fileHeader.RiceCompressionHeader.Flags); } lastMSDU = msdu; using (FileStream fs = new FileStream(filename, firstOrSinglePacket ? FileMode.Create : FileMode.Append, FileAccess.Write)) { using (BinaryWriter sw = new BinaryWriter(fs)) { sw.Write(dataToSave); sw.Flush(); } } if (msdu.Sequence == SequenceType.LAST_SEGMENT || msdu.Sequence == SequenceType.SINGLE_DATA) { FileHandler.HandleFile(filename, fileHeader, manager); startnum = -1; endnum = -1; } } catch (Exception e) { UIConsole.Error(String.Format("Exception on FinishMSDU: {0}", e)); } }
public void FinishMSDU(MSDU msdu) { try { if (msdu.APID == 2047) { // Skip fill packet return; } bool firstOrSinglePacket = msdu.Sequence == SequenceType.FIRST_SEGMENT || msdu.Sequence == SequenceType.SINGLE_DATA; Packets++; if (manager != null) { manager.Packets++; } if (!msdu.Valid) { CRCFails++; if (manager != null) { manager.CRCFails++; } } if (manager != null) { LengthFails++; if (!msdu.Full) { manager.LengthFails++; } } if (!msdu.Valid || !msdu.Full) { if (msdu.FrameLost) { UIConsole.Error($"Lost some frames on MSDU, the file will be corrupted. CRC Match: {msdu.Valid} - Size Match: {msdu.Full}"); } else { UIConsole.Error($"Corrupted MSDU. CRC Match: {msdu.Valid} - Size Match: {msdu.Full}"); } } if (msdu.Sequence == SequenceType.FIRST_SEGMENT || msdu.Sequence == SequenceType.SINGLE_DATA) { if (msduCache.ContainsKey(msdu.APID)) { var minfo = msduCache[msdu.APID]; UIConsole.Warn($"Received First Segment for {msdu.APID:X3} but last data wasn't saved to disk yet! Forcing dump."); string ofilename = Path.Combine(FileHandler.TemporaryFileFolder, channelId.ToString()); ofilename = Path.Combine(ofilename, minfo.FileName); FileHandler.HandleFile(ofilename, minfo.Header, manager); msduCache.Remove(msdu.APID); } var msInfo = new MSDUInfo() { APID = msdu.APID, FileName = msdu.TemporaryFilename, Header = FileParser.GetHeader(msdu.Data.Skip(10).ToArray()), LastPacketNumber = msdu.PacketNumber, }; msduCache.Add(msdu.APID, msInfo); } else if (msdu.Sequence == SequenceType.LAST_SEGMENT || msdu.Sequence == SequenceType.CONTINUED_SEGMENT) { if (!msduCache.ContainsKey(msdu.APID)) { UIConsole.Debug($"Orphan Packet for APID {msdu.APID}!"); return; } } var msduInfo = msduCache[msdu.APID]; msduInfo.Refresh(); // LRIT EMWIN /* Uncomment to enable EMWIN Ingestor * Its broken right now * if (fileHeader.PrimaryHeader.FileType == FileTypeCode.EMWIN) { * //Ingestor * int offset = 10 + (int)fileHeader.PrimaryHeader.HeaderLength; * EMWIN.Ingestor.Process(msdu.Data.Skip(offset).ToArray()); * return; * } */ string path = Path.Combine(FileHandler.TemporaryFileFolder, channelId.ToString()); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } string filename = Path.Combine(path, msduInfo.FileName); byte[] dataToSave = msdu.Data.Skip(firstOrSinglePacket ? 10 : 0).Take(firstOrSinglePacket ? msdu.PacketLength - 10 : msdu.PacketLength).ToArray(); if (msduInfo.Header.Compression == CompressionType.LRIT_RICE && !firstOrSinglePacket) { int missedPackets = msduInfo.LastPacketNumber - msdu.PacketNumber - 1; if (msduInfo.LastPacketNumber == 16383 && msdu.PacketNumber == 0) { missedPackets = 0; } if (missedPackets > 0) { UIConsole.Warn(String.Format("Missed {0} packets on image. Filling with null bytes. Last Packet Number: {1} Current: {2}", missedPackets, msduInfo.LastPacketNumber, msdu.PacketNumber)); byte[] fill = Decompress.GenerateFillData(msduInfo.Header.ImageStructureHeader.Columns); using (FileStream fs = new FileStream(filename, FileMode.Append, FileAccess.Write)) { using (BinaryWriter sw = new BinaryWriter(fs)) { while (missedPackets > 0) { sw.Write(fill); missedPackets--; } sw.Flush(); } } } if (msduInfo.Header.RiceCompressionHeader == null) // Fix bug for GOES-15 TX after GOES-16 switch. Weird, but let's try defaults { dataToSave = Decompress.InMemoryDecompress(dataToSave, msduInfo.Header.ImageStructureHeader.Columns, 16, AEC.ALLOW_K13_OPTION_MASK | AEC.MSB_OPTION_MASK | AEC.NN_OPTION_MASK); // 49 } else { dataToSave = Decompress.InMemoryDecompress(dataToSave, msduInfo.Header.ImageStructureHeader.Columns, msduInfo.Header.RiceCompressionHeader.Pixel, msduInfo.Header.RiceCompressionHeader.Flags); } } msduInfo.LastPacketNumber = msdu.PacketNumber; using (FileStream fs = new FileStream(filename, firstOrSinglePacket ? FileMode.Create : FileMode.Append, FileAccess.Write)) { using (BinaryWriter sw = new BinaryWriter(fs)) { sw.Write(dataToSave); sw.Flush(); } } if (msdu.Sequence == SequenceType.LAST_SEGMENT || msdu.Sequence == SequenceType.SINGLE_DATA) { FileHandler.HandleFile(filename, msduInfo.Header, manager); msduCache.Remove(msdu.APID); } } catch (Exception e) { UIConsole.Error(String.Format("Exception on FinishMSDU: {0}", e)); } }