void ThreadLoop() { UIConsole.Debug("File Handler started"); while (running) { Tuple <string, object> fileToHandle; if (packets.TryDequeue(out fileToHandle)) { string filename = fileToHandle.Item1; object obj = fileToHandle.Item2; if (obj.GetType() == typeof(GRBImageHeader)) { HandleImage(filename, (GRBImageHeader)obj); } else if (obj.GetType() == typeof(GRBGenericHeader)) { HandleGeneric(filename, (GRBGenericHeader)obj); } else { UIConsole.Error($"Invalid Type: {obj.GetType().Name}"); } } // Thread.Yield(); // This might be better Thread.Sleep(5); } UIConsole.Debug("File Handler stopped"); }
public static void HandleFile(string filename, GRBGenericHeader header) { string dir = Path.GetDirectoryName(filename); string ofilename = header.filename ?? Path.GetFileName(filename); if (Tools.IsXML(filename)) { ofilename = ofilename.Replace(".grb", ".xml"); } string productFolder = Products.GetFolderByAPID(header.apid); string f = Path.Combine(FileHandler.FinalFileFolder, productFolder); try { Directory.CreateDirectory(f); } catch (IOException e) { UIConsole.Error($"Cannot create directory {f}: {e}"); } f = Path.Combine(f, ofilename); if (File.Exists(f)) { string timestamp = DateTime.Now.ToString("yyyyMMddHHmmssffff"); string ext = Path.GetExtension(f); string append = $"--dup-{timestamp}{ext}"; f = f.Replace(ext, append); } try { File.Move(filename, f); } catch (IOException e) { UIConsole.Error($"Error moving file {filename} to {f}: {e}"); } }
public void AddMetadataFrom(GrbData grbData) { Metadata = grbData.Metadata; try { ParseMetadataFromText(Metadata); } catch (Exception e) { UIConsole.Error($"Error parsing metadata: {e.Message}"); } }
public static void HandleFile(string filename, GRBImageHeader header) { string dir = Path.GetDirectoryName(filename); string ofilename = header.filename ?? Path.GetFileName(filename); // Separate DQF string dqfFilename = $"{filename}.dqf"; try { byte[] buffer = File.ReadAllBytes(filename); buffer = buffer.Skip((int)header.dqfOffset).ToArray(); File.WriteAllBytes(dqfFilename, buffer); } catch (Exception) { } string productFolder = Products.GetFolderByAPID(header.apid); string bPath = productFolder; string zPath = Path.Combine(bPath, $"{header.epoch:D16}", $"{header.sequence:D8}"); string f = Path.Combine(FileHandler.FinalFileFolder, zPath); try { Directory.CreateDirectory(Path.Combine(FileHandler.FinalFileFolder, bPath, $"{header.epoch:D16}")); } catch (IOException e) { UIConsole.Error($"Cannot create directory {bPath}: {e}"); } if (!ImageCache.ContainsKey(zPath)) { ImageCache.Add(zPath, new ImageAssembler((int)header.width, (int)header.height)); DQFCache.Add(zPath, new ImageAssembler((int)header.width, (int)header.height)); } ImageCache[zPath].AppendJ2K(filename); DQFCache[zPath].AppendJ2K(dqfFilename); try { File.Delete(filename); File.Delete(dqfFilename); } catch (IOException e) { UIConsole.Error($"Error erasing file {filename}: {e}"); } if (ImageCache[zPath].Done) { // UIConsole.Log ($"New image at {f}"); // ImageCache [zPath].SavePGM ($"{f}.pgm"); // ImageCache [zPath].SaveJPG ($"{f}.jpg"); // File.WriteAllText($"{f}.txt", header.ToString()); ProcessBigImage(bPath, ImageCache[zPath], header); ImageCache.Remove(zPath); // FIXME: Discarding DQF // DQFCache[zPath].SavePGM($"{f}.dqf.pgm"); DQFCache.Remove(zPath); } }
/// <summary> /// Stores plain data /// </summary> /// <param name="filename">Filename.</param> /// <param name="header">Header.</param> public void ParseData(string filename, GRBGenericHeader header) { lock (syncLock) { try { Data = File.ReadAllBytes(filename); } catch (Exception e) { UIConsole.Error($"Error parsing data file {filename}: {e.Message}"); UIConsole.Debug($"{e}"); } } }
/// <summary> /// Generates the land map using GeoConverter /// </summary> /// <returns>The land map.</returns> /// <param name="gc">Gc.</param> /// <param name="width">Width.</param> /// <param name="height">Height.</param> /// <param name="fixCrop">If set to <c>true</c> fix crop.</param> public Bitmap GenerateLandMap(GeoConverter gc, int width, int height, bool fixCrop = false) { if (shapeFile == null) { UIConsole.Error("Trying to draw a LandMap without a loaded shapefile!"); return(null); } var bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb); Brush bgBrush = new SolidBrush(Color.Black); Brush polyBrush = new SolidBrush(Color.White); using (var graphics = Graphics.FromImage(bmp)) { graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; graphics.FillRectangle(bgBrush, 0, 0, width, height); lock (shapeFile) { // TODO: This is BAD, SO BAD, PLEASE FIX ME // Thats because for some reason running this in multiple // threads is causing Features to be modified (wtf?) foreach (var f in shapeFile.Features.ToList()) { for (int i = 0; i < f.NumGeometries; i++) { var geom = f.GetBasicGeometryN(i); var k = geom.Coordinates; var points = new List <PointF> (); foreach (var z in k) { float lon = (float)z.X; float lat = (float)z.Y; var xy = gc.latlon2xy(lat, lon); float cx = (float)xy.Item1; float cy = (float)xy.Item2; if (fixCrop) { cx -= gc.CropLeft; } points.Add(new PointF(cx, cy)); } // Search if any of the points are inside the image foreach (var p in points) { if (p.X >= 0 && p.X < bmp.Width && p.Y >= 0 && p.Y < bmp.Height) { graphics.FillPolygon(polyBrush, points.ToArray()); break; } } } } } } return(bmp); }
public MapDrawer(string shapeFile) { this.shapeFile = null; UIConsole.Debug($"MapDrawer -- Loading ShapeFile {shapeFile}"); try { this.shapeFile = Shapefile.OpenFile(shapeFile); UIConsole.Debug("MapDrawer -- ShapeFile Loaded at MapDrawer"); } catch (Exception e) { UIConsole.Error($"MapDrawer -- Cannot load ShapeFile at {shapeFile}: {e}"); } }
/// <summary> /// Parses a metadata file /// </summary> /// <param name="filename">Filename.</param> public void ParseMetadata(string filename) { lock (syncLock) { try { Metadata = File.ReadAllText(filename); ParseMetadataFromText(Metadata); } catch (Exception e) { UIConsole.Error($"Error parsing metadata file {filename}: {e.Message}"); // UIConsole.Debug($"{e}"); } } }
public void Stop() { if (running) { UIConsole.Log("Stopping Thread"); running = false; channelThread.Join(); } else { UIConsole.Error("MSDU Manager already stopped!"); } }
private static void ManageImageManager(ImageManager im) { try { UIConsole.Debug($"Processing folder {im.Folder}"); im.RunningSingleThread = true; im.SingleThreadRun(); Thread.Sleep(200); } catch (Exception e) { UIConsole.Error($"Error processing image manager single thread: {e}"); CrashReport.Report(e); throw; } }
/// <summary> /// Processes a new image part /// </summary> /// <param name="filename">Filename.</param> /// <param name="header">Header.</param> public void NewImage(string filename, GRBImageHeader header) { lock (syncLock) { if (ImageCache == null) { if (SaveDQF) { DQF = new ImageAssembler((int)header.width, (int)header.height, Epoch); } ImageCache = new ImageAssembler((int)header.width, (int)header.height, Epoch); } if (SaveDQF) { // Separate DQF string dqfFilename = $"{filename}.dqf"; try { byte[] buffer = File.ReadAllBytes(filename); buffer = buffer.Skip((int)header.dqfOffset).ToArray(); File.WriteAllBytes(dqfFilename, buffer); } catch (Exception e) { UIConsole.Error($"Error slicing DQF file to {filename}.dqf: {e.Message}"); UIConsole.Debug($"{e}"); } DQF.AppendJ2K(dqfFilename); try { File.Delete(dqfFilename); } catch (IOException e) { UIConsole.Error($"Error erasing file {filename}: {e.Message}"); UIConsole.Debug($"{e}"); } } ImageCache.AppendJ2K(filename); try { File.Delete(filename); } catch (IOException e) { UIConsole.Error($"Error erasing file {filename}: {e.Message}"); UIConsole.Debug($"{e}"); } if (ImageCache.Done) { ProcessBigImage(header); } } }
/// <summary> /// Draws the Map using the loaded Shapefile on bitmap. /// </summary> /// <param name="bmp">Bitmap to be draw</param> /// <param name="gc">Initialized GeoConverter</param> /// <param name="color">Color of the lines</param> /// <param name="lineWidth">Thickness of the Lines</param> public void DrawMap(ref Bitmap bmp, GeoConverter gc, Color color, int lineWidth = 5, bool fixCrop = false, bool useOldDrawMap = false) { if (shapeFile == null) { UIConsole.Error("Trying to draw a Map without a loaded shapefile!"); return; } if (useOldDrawMap) { OldDrawMap(ref bmp, gc, color, lineWidth, fixCrop); } else { NewDrawMap(ref bmp, gc, color, lineWidth, fixCrop); } }
public void Start() { if (!running) { UIConsole.Log("Starting channel thread"); running = true; channelThread = new Thread(new ThreadStart(ThreadLoop)) { IsBackground = true, Priority = ThreadPriority.AboveNormal, }; channelThread.Start(); } else { UIConsole.Error("File Handler already running!"); } }
public void Start() { if (!running) { UIConsole.Log("Starting MSDU thread"); running = true; channelThread = new Thread(new ThreadStart(ThreadLoop)) { IsBackground = true, Priority = ThreadPriority.Highest, }; channelThread.Start(); } else { UIConsole.Error("MSDU Manager already running!"); } }
public static void CLBuilder(ComputeContext context) { UIConsole.Log("Loading kernel.cl"); var clProgramSource = File.ReadAllText("kernel.cl"); UIConsole.Log("Compiling kernel"); program = new ComputeProgram(context, clProgramSource); try { program.Build(null, null, null, IntPtr.Zero); } catch (Exception e) { UIConsole.Error("Build Log: \n" + program.GetBuildLog(context.Devices[0])); throw e; } reprojectKernel = program.CreateKernel("reproject"); apply2DLUTKernel = program.CreateKernel("apply2DLUT"); applyCurveKernel = program.CreateKernel("applyCurve"); UIConsole.Log("Building Curve LUT"); curveLut = new byte[256]; for (int i = 0; i < 256; i++) { float v = 255 * OpenSatelliteProject.Presets.NEW_VIS_FALSE_CURVE[i]; curveLut[i] = (byte)(((int)Math.Floor(v)) & 0xFF); } curveLutBuffer = new ComputeBuffer <byte>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, curveLut); UIConsole.Log("Loading LUT2D"); byte[] buffer = ReadFileFromOSPAssembly("falsecolor.png"); Bitmap lutBmp; using (MemoryStream stream = new MemoryStream(buffer)) { lutBmp = new Bitmap(stream); } lut2D = new uint[256 * 256]; for (int i = 0; i < 256; i++) { for (int j = 0; j < 256; j++) { lut2D[(i * 256) + j] = (uint)(lutBmp.GetPixel(j, i).ToArgb() & 0xFFFFFFFF); } } lut2DBuffer = new ComputeBuffer <uint>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, lut2D); }
void ChannelDataLoop() { try { UIConsole.Log($"UDP Channel Data Loop started at port {ChannelDataServerPort}"); UdpClient udpClient = new UdpClient(ChannelDataServerPort); IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0); udpClient.Client.ReceiveTimeout = 200; // udpClient.Client.ReceiveBufferSize = 7278 * BufferSizeInFrames; // Ray found out that this is making rx bad. while (channelDataThreadRunning) { try { byte[] buffer = udpClient.Receive(ref RemoteIpEndPoint); switch (buffer.Length) { case 5380: case 5384: case 7274: case 7278: HandleBBFrame(buffer); break; case 2052: case 2048: HandleCADU(buffer); break; default: UIConsole.Error($"Received invalid frame size: {buffer.Length}"); break; } } catch (Exception e) { // TODO: Handle UIConsole.Error(e.ToString()); } } UIConsole.Log("UDP Channel Data Thread closed."); } catch (Exception e) { CrashReport.Report(e); } }
void HandleCADU(byte[] data) { long caduNumber = -1; if (data.Length == 2052) { byte[] counter = data.Take(4).ToArray(); data = data.Skip(4).ToArray(); caduNumber = BitConverter.ToUInt32(counter, 0); } if (lastCaduNumber != -1 && caduNumber != -1) { if (lastCaduNumber == caduNumber) { UIConsole.Warn("CADU Packet arrived duplicated! Dropping."); return; } if (lastCaduNumber > caduNumber) { UIConsole.Warn("CADU Packet arrived out of order! Dropping."); return; } if (lastCaduNumber + 1 != caduNumber) { long missingPackets = caduNumber - lastPacketNumber + 1; UIConsole.Warn($"Missing {missingPackets} CADU packets!"); } } if (FindSyncMark(data) != 0) { UIConsole.Error("Corrupted CADU data!"); return; } PostChannelData(data.Skip(4).ToArray()); }
public static void Main(string[] args) { try { Process thisProc = Process.GetCurrentProcess(); thisProc.PriorityClass = ProcessPriorityClass.RealTime; } catch (Exception e) { UIConsole.Error($"Failed changing process priority: {e}"); } fileHandlerManager = new FileHandlerManager(); msduManager = new MSDUManager(fileHandlerManager); channel5 = new ChannelManager(msduManager); channel6 = new ChannelManager(msduManager); // cn = new Connector(); channel5.Start(); channel6.Start(); msduManager.Start(); fileHandlerManager.Start(); UIConsole.GlobalEnableDebug = true; /*cn = new Connector (); * cn.ChannelDataAvailable += data => { * data = data.Take(2042).ToArray(); * int vcid = (data[1] & 0x3F); * if (vcid == 5) { * channel5.NewPacket(data); * } else if (vcid == 6) { * channel6.NewPacket(data); * } else { * UIConsole.Error($"Unknown VCID for GRB: {vcid}"); * } * }; * cn.Start (); */ udpReceiver = new UdpReceiver(); udpReceiver.ChannelDataAvailable += data => { data = data.Take(2042).ToArray(); int vcid = (data[1] & 0x3F); if (vcid == 5) { channel5.NewPacket(data); } else if (vcid == 6) { channel6.NewPacket(data); } else if (vcid == 63) { // Fill Frame } else { UIConsole.Error($"Unknown VCID for GRB: {vcid}"); } }; udpReceiver.Start(); while (true) { Thread.Sleep(1000); Thread.Yield(); } }
/// <summary> /// Saves this instance to disk /// </summary> /// <returns>Async Task of saving</returns> public async Task Save() { string folder = Path.Combine(FileHandler.FinalFileFolder, ProductFolder); if (Filename == null) { Filename = $"{Epoch}.nc"; } try { Directory.CreateDirectory(folder); } catch (IOException e) { UIConsole.Error($"Cannot create directory {folder}: {e}"); } string dqfFilename = Filename.Replace(".nc", ".dqf.pgm"); string imgFilename = Filename.Replace(".nc", ".pgm"); string metaFilename = Filename.Replace(".nc", ".xml"); string dataFilename = Filename.Replace(".nc", ".bin"); if (Title == null) { Title = Products.GetNameByAPID(APID); } UIConsole.Log($"New Product: {Title}"); if (Metadata != null) { metaFilename = Path.Combine(folder, metaFilename); UIConsole.Debug($"Saving file {metaFilename}"); File.WriteAllText(metaFilename, Metadata); } if (Data != null) { dataFilename = Path.Combine(folder, dataFilename); UIConsole.Debug($"Saving file {dataFilename}"); File.WriteAllBytes(dataFilename, Data); } if (FullDQFCache != null && SaveDQF) { dqfFilename = Path.Combine(folder, dqfFilename); UIConsole.Debug($"Saving file {dqfFilename}"); await FullDQFCache.AsyncSavePGM(dqfFilename); } if (FullImageCache != null) { if (SavePGM) { imgFilename = Path.Combine(folder, imgFilename); UIConsole.Debug($"Saving file {imgFilename}"); await FullImageCache.AsyncSavePGM(imgFilename); } if (SaveJPG) { string jpgFilename = imgFilename.Replace(".pgm", ".jpg"); jpgFilename = Path.Combine(folder, jpgFilename); UIConsole.Debug($"Saving file {jpgFilename}"); await FullImageCache.AsyncSaveJPG(jpgFilename); } if (SavePNG) { string pngFilename = imgFilename.Replace(".pgm", ".png"); pngFilename = Path.Combine(folder, pngFilename); UIConsole.Debug($"Saving file {pngFilename}"); await FullImageCache.AsyncSavePNG(pngFilename); } } }
public void ParseBytes(byte[] data) { uint counter; bool replayFlag; bool ovfVcnt; bool ovfVcntProblem; bool frameJump; if (data.Length < FRAMESIZE) { throw new Exception(String.Format("Not enough data. Expected {0} and got {1}", FRAMESIZE, data.Length)); } channelId = (data[1] & 0x3F); byte[] cb = data.Skip(2).Take(4).ToArray(); if (BitConverter.IsLittleEndian) { Array.Reverse(cb); } cb[0] = 0x00; counter = BitConverter.ToUInt32(cb, 0); //counter &= 0xFFFFFF00; counter >>= 8; replayFlag = (data[5] & 0x80) > 0; if (replayFlag) { UIConsole.Debug("Replay Flag set. Skipping packet."); return; } if (counter - lastFrame - 1 == -1) { UIConsole.Warn("Last packet same ID as the current one but no replay bit set! Skipping packet."); return; } frameJump = lastFrame > counter; ovfVcnt = frameJump && counter == 0; ovfVcntProblem = ovfVcnt && (0xFFFFFF - lastFrame) + counter - 1 > 0; if (frameJump && !ovfVcnt) { UIConsole.Warn($"Frame Jump occured. Current Frame: {counter} Last Frame: {lastFrame}"); if (lastAPID != -1) { temporaryStorage[lastAPID].FrameLost = true; } } else if (lastFrame != -1 && lastFrame + 1 != counter && !ovfVcnt) { UIConsole.Error(String.Format("Lost {0} frames. Last Frame #{1} - Current Frame #{2} on VCID {3}", counter - lastFrame - 1, lastFrame, counter, channelId)); if (lastAPID != -1) { temporaryStorage[lastAPID].FrameLost = true; } } else if (!IgnoreCounterJump && lastFrame != -1 && ovfVcntProblem) { UIConsole.Error(String.Format("Lost {0} frames. Last Frame #{1} - Current Frame #{2} on VCID {3}", (0xFFFFFF - lastFrame) + counter - 1, lastFrame, counter, channelId)); if (lastAPID != -1) { temporaryStorage[lastAPID].FrameLost = true; } } if (ovfVcntProblem && IgnoreCounterJump || frameJump && IgnoreCounterJump) { UIConsole.Warn($"Frame Jump detected from {lastFrame} to {counter} on VCID {channelId} but IgnoreCounterJump is set to true. Ignoring..."); } if (lastFrame != -1) { if (frameJump && !ovfVcnt) { // manager.FrameLoss++; } else if (!IgnoreCounterJump && ovfVcnt) { int losses = (int)Math.Abs((0xFFFFFF - lastFrame) + counter - 1); if (losses < MAX_ACCOUTABLE_LOSSES) { FrameLoss += losses; } else { UIConsole.Warn($"Frame Lost ({losses}) in this section is higher than max accountable losses. Not accounting for it (probably corrupt frame)."); } } else if (!ovfVcnt) { int losses = (int)Math.Abs(counter - lastFrame - 1); if (losses < MAX_ACCOUTABLE_LOSSES) { FrameLoss += losses; } else { UIConsole.Warn($"Frame Lost ({losses}) in this section is higher than max accountable losses. Not accounting for it (probably corrupt frame)."); } } } if (frameJump && !ovfVcnt) { FrameJumps++; } if (lastFrame < counter || ovfVcnt || frameJump) { lastFrame = (int)counter; } else { UIConsole.Warn($"LastFrame is bigger than currentFrame ({lastFrame} > {counter}). Not changing current number..."); } cb = data.Skip(6).Take(2).ToArray(); if (BitConverter.IsLittleEndian) { Array.Reverse(cb); } int fhp = BitConverter.ToUInt16(cb, 0) & 0x7FF; data = data.Skip(8).ToArray(); // Data is now TP_PDU var p = Tuple.Create(0, new byte[0]); if (fhp != 2047) // Has a packet start { if (lastAPID == -1 && buffer.Length > 0) { // There was not enough data to packetize last time. So lets fill the buffer until the fhp and create packet. if (fhp > 0) { buffer = buffer.Concat(data.Take(fhp)).ToArray(); data = data.Skip(fhp).ToArray(); fhp = 0; } p = CreatePacket(buffer); lastAPID = p.Item1; buffer = p.Item2; } if (lastAPID != -1) { if (fhp > 0) { temporaryStorage[lastAPID].AddDataBytes(buffer.Concat(data.Take(fhp)).ToArray()); data = data.Skip(fhp).ToArray(); fhp = 0; } if (!temporaryStorage[lastAPID].Full && !temporaryStorage[lastAPID].FrameLost && lastAPID != 2047) { Bugs++; StackFrame callStack = new StackFrame(0, true); UIConsole.Debug(String.Format("Problem at line {0} in file {1}! Not full! Check code for bugs!", callStack.GetFileLineNumber(), callStack.GetFileName())); } msduManager.FinishMSDU(temporaryStorage[lastAPID]); temporaryStorage.Remove(lastAPID); lastAPID = -1; } buffer = buffer.Concat(data.Skip(fhp)).ToArray(); p = CreatePacket(buffer); lastAPID = p.Item1; buffer = p.Item2; } else { if (buffer.Length > 0 && lastAPID != -1) { buffer = buffer.Concat(data).ToArray(); p = CreatePacket(buffer); lastAPID = p.Item1; buffer = p.Item2; } else if (lastAPID == -1) { buffer = buffer.Concat(data).ToArray(); p = CreatePacket(buffer); lastAPID = p.Item1; buffer = p.Item2; } else if (buffer.Length > 0) { UIConsole.Error("EDGE CASE! PLEASE REPORT THIS MESSAGE"); } else { temporaryStorage[lastAPID].AddDataBytes(data); } } }
void ChannelDataLoop() { try { UIConsole.Log("Channel Data Loop started"); byte[] buffer = new byte[2042]; IPHostEntry ipHostInfo = Dns.GetHostEntry(ChannelDataServerName); IPAddress ipAddress = new IPAddress(new byte[] { 127, 0, 0, 1 }); foreach (IPAddress ip in ipHostInfo.AddressList) { if (ip.AddressFamily != AddressFamily.InterNetworkV6) { ipAddress = ip; break; } } IPEndPoint remoteEP = new IPEndPoint(ipAddress, ChannelDataServerPort); Socket sender = null; while (channelDataThreadRunning) { bool isConnected = true; UIConsole.Log("Channel Data Thread connect"); try { sender = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) { ReceiveTimeout = 5000 }; sender.Connect(remoteEP); isConnected = true; UIConsole.Log($"Socket connected to {sender.RemoteEndPoint}"); int nullReceive = 0; while (isConnected) { try { var receivedBytes = sender.Receive(buffer); if (receivedBytes < buffer.Length && receivedBytes != 0) { UIConsole.Error("Received less bytes than channel data!"); Thread.Sleep(200); nullReceive = 0; } else if (receivedBytes == 0) { nullReceive++; if (nullReceive == 5) { UIConsole.Error("Cannot reach server. Dropping connection!"); isConnected = false; sender.Shutdown(SocketShutdown.Both); sender.Disconnect(false); sender.Close(); } } else { nullReceive = 0; this.PostChannelData(buffer); } } catch (ArgumentNullException ane) { UIConsole.Error($"ArgumentNullException : {ane}"); isConnected = false; } catch (SocketException) { isConnected = false; } catch (Exception e) { UIConsole.Error($"Unexpected exception : {e}"); isConnected = false; } DataConnected = isConnected; if (!channelDataThreadRunning) { break; } } sender.Shutdown(SocketShutdown.Both); sender.Disconnect(false); sender.Close(); } catch (ArgumentNullException ane) { UIConsole.Error($"ArgumentNullException : {ane}"); } catch (SocketException se) { UIConsole.Error($"SocketException : {se}"); } catch (Exception e) { UIConsole.Error($"Unexpected exception : {e}"); } if (channelDataThreadRunning) { UIConsole.Warn("Socket closed. Waiting 1s before trying again."); Thread.Sleep(1000); } } UIConsole.Debug("Requested to close Channel Data Thread!"); try { if (sender != null) { sender.Shutdown(SocketShutdown.Both); sender.Disconnect(false); sender.Close(); } } catch (Exception e) { UIConsole.Debug($"Exception thrown when closing socket: {e} Ignoring."); } UIConsole.Log("Channel Data Thread closed."); } catch (Exception e) { CrashReport.Report(e); } }
public static List <XRITBaseHeader> GetHeaderData(byte[] data) { List <XRITBaseHeader> headers = new List <XRITBaseHeader>(); int maxLength = data.Length; // Initial Guess int c = 0; // Parse Primary Header for size int type = data[0]; if (type != (int)HeaderType.PrimaryHeader) { UIConsole.Error($"Expected PrimaryHeader({(int)HeaderType.PrimaryHeader} got {type}. File is corrupt."); return(headers); } byte[] tmp = data.Skip(1).Take(2).ToArray(); if (BitConverter.IsLittleEndian) { Array.Reverse(tmp); } int size = BitConverter.ToUInt16(tmp, 0); tmp = data.Take(size).ToArray(); PrimaryRecord fh = LLTools.ByteArrayToStruct <PrimaryRecord>(tmp); fh = LLTools.StructToSystemEndian(fh); maxLength = (int)fh.HeaderLength; // Set the correct size byte[] headerData = data.Take(maxLength).ToArray(); data = data.Skip(maxLength).ToArray(); // Parse Secondary Headers while (c < maxLength) { type = headerData[0]; tmp = headerData.Skip(1).Take(2).ToArray(); if (BitConverter.IsLittleEndian) { Array.Reverse(tmp); } size = BitConverter.ToUInt16(tmp, 0); tmp = headerData.Take(size).ToArray(); if (tmp.Length < size) { UIConsole.Warn($"Not enough data for unpack header: Expected {size} got {tmp.Length} - Header Type: {type} - File might be corrupted."); if (c + size > maxLength) { UIConsole.Debug($"c + size > maxLength: {c} + {size} > {maxLength}"); size = maxLength - c - 1; c = maxLength; } } else { c += size; } headerData = headerData.Skip(size).ToArray(); XRITBaseHeader h; switch (type) { case (int)HeaderType.PrimaryHeader: fh = LLTools.ByteArrayToStruct <PrimaryRecord>(tmp); fh = LLTools.StructToSystemEndian(fh); h = new PrimaryHeader(fh); maxLength = (int)fh.HeaderLength; // Set the correct size break; case (int)HeaderType.ImageStructureRecord: ImageStructureRecord isr = LLTools.ByteArrayToStruct <ImageStructureRecord>(tmp); isr = LLTools.StructToSystemEndian(isr); h = new ImageStructureHeader(isr); break; case (int)HeaderType.ImageNavigationRecord: ImageNavigationRecord inr = LLTools.ByteArrayToStruct <ImageNavigationRecord>(tmp); inr = LLTools.StructToSystemEndian(inr); h = new ImageNavigationHeader(inr); break; case (int)HeaderType.ImageDataFunctionRecord: // Cannot marshable due variable length //ImageDataFunctionRecord idfr = LLTools.ByteArrayToStruct<ImageDataFunctionRecord>(tmp); //idfr = LLTools.StructToSystemEndian(idfr); ImageDataFunctionRecord idfr = new ImageDataFunctionRecord(); idfr.Data = System.Text.Encoding.UTF8.GetString(tmp.Skip(3).ToArray()); h = new ImageDataFunctionHeader(idfr); break; case (int)HeaderType.AnnotationRecord: // Cannot be marshalled due variable length //AnnotationRecord ar = LLTools.ByteArrayToStruct<AnnotationRecord>(tmp); //ar = LLTools.StructToSystemEndian(ar); AnnotationRecord ar = new AnnotationRecord(); ar.Filename = System.Text.Encoding.UTF8.GetString(tmp.Skip(3).ToArray()); h = new AnnotationHeader(ar); break; case (int)HeaderType.TimestampRecord: TimestampRecord tr = LLTools.ByteArrayToStruct <TimestampRecord>(tmp); tr = LLTools.StructToSystemEndian(tr); h = new TimestampHeader(tr); break; case (int)HeaderType.AncillaryTextRecord: // Cannot be marshalled due variable length. // AncillaryText at = LLTools.ByteArrayToStruct<AncillaryText>(tmp); //at = LLTools.StructToSystemEndian(at); AncillaryText at = new AncillaryText(); at.Data = System.Text.Encoding.UTF8.GetString(tmp.Skip(3).ToArray()); h = new AncillaryHeader(at); break; case (int)HeaderType.KeyRecord: h = new XRITBaseHeader(HeaderType.KeyRecord, tmp); break; case (int)HeaderType.SegmentIdentificationRecord: SegmentIdentificationRecord sir = LLTools.ByteArrayToStruct <SegmentIdentificationRecord>(tmp); sir = LLTools.StructToSystemEndian(sir); h = new SegmentIdentificationHeader(sir); break; case (int)HeaderType.NOAASpecificHeader: NOAASpecificRecord nsr = LLTools.ByteArrayToStruct <NOAASpecificRecord>(tmp); nsr = LLTools.StructToSystemEndian(nsr); h = new NOAASpecificHeader(nsr); break; case (int)HeaderType.HeaderStructuredRecord: // Cannot be marshalled due variable length //HeaderStructuredRecord hsr = LLTools.ByteArrayToStruct<HeaderStructuredRecord>(tmp); //hsr = LLTools.StructToSystemEndian(hsr); // Header Structured Record doesn't have endianess dependant fields HeaderStructuredRecord hsr = new HeaderStructuredRecord(); hsr.Data = System.Text.Encoding.UTF8.GetString(tmp.Skip(3).ToArray()); h = new HeaderStructuredHeader(hsr); break; case (int)HeaderType.RiceCompressionRecord: RiceCompressionRecord rcr = LLTools.ByteArrayToStruct <RiceCompressionRecord>(tmp); rcr = LLTools.StructToSystemEndian(rcr); h = new RiceCompressionHeader(rcr); break; case (int)HeaderType.DCSFileNameRecord: // Cannot be marshalled due variable length //DCSFilenameRecord dfr = LLTools.ByteArrayToStruct<DCSFilenameRecord>(tmp); //dfr = LLTools.StructToSystemEndian(dfr); // DCS Filename Record doesn't have endianess dependant fields DCSFilenameRecord dfr = new DCSFilenameRecord(); dfr.Filename = System.Text.Encoding.UTF8.GetString(tmp.Skip(3).ToArray()); h = new DCSFilenameHeader(dfr); break; case (int)HeaderType.Head9: Head9 h9 = new Head9(); h9.Data = tmp.Skip(3).ToArray(); h = new Head9Header(h9); ((Head9Header)h).FileName = $"buggy_file_{LLTools.TimestampMS()}.lrit"; tmp.Skip(3).ToArray().Separate(new byte[] { 0x00 }).ToList().ForEach((barr) => { if (barr.Length > 0 && barr[0] == 0x1F) { ((Head9Header)h).FileName = System.Text.Encoding.UTF8.GetString(barr.Skip(1).ToArray()); ((Head9Header)h).FileName = LLTools.StripNonPrintable(((Head9Header)h).FileName); } }); UIConsole.Debug($"Got Head9 which may be a bug. Filename: {((Head9Header)h).FileName}"); break; default: h = new XRITBaseHeader(); h.Type = HeaderType.Unknown; break; } h.RawData = tmp; headers.Add(h); } return(headers); }
void ProcessMSDU(OpenSatelliteProject.GRB.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 (!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.Valid) { CRCFails++; return; } var payloadType = EnumHelpers.APID2Type(msdu.APID); 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."); // This can only happen for multi-segment file. string msduFile = Path.Combine(FileHandler.TemporaryFileFolder, minfo.FileName); string target = Path.Combine(FileHandler.TemporaryFileFolder, $"{msdu.APID:X3}-{LLTools.TimestampMS()}-{Tools.RandomString(8)}"); File.Move(msduFile, target); if (payloadType == PayloadType.Generic) { fileHandleManager.NewFile(new Tuple <string, object>(target, minfo.GenericHeader)); } else { fileHandleManager.NewFile(new Tuple <string, object>(target, minfo.ImageHeader)); } msduCache.Remove(msdu.APID); } var msInfo = new MSDUInfo() { APID = msdu.APID, FileName = msdu.TemporaryFilename, GenericHeader = payloadType == PayloadType.Generic ? new GRBGenericHeader(msdu.APID, msdu.Data.Skip(8).Take(21).ToArray()) : null, ImageHeader = payloadType == PayloadType.ImageData ? new GRBImageHeader(msdu.APID, msdu.Data.Skip(8).Take(34).ToArray()) : null, }; msduCache.Add(msdu.APID, msInfo); } else if (msdu.Sequence == SequenceType.LAST_SEGMENT || msdu.Sequence == SequenceType.CONTINUED_SEGMENT) { if (!msduCache.ContainsKey(msdu.APID)) { UIConsole.Warn("Orphan Packet!"); return; } } var msduInfo = msduCache[msdu.APID]; msduInfo.Refresh(); string path = FileHandler.TemporaryFileFolder; if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } string filename = Path.Combine(FileHandler.TemporaryFileFolder, msduInfo.FileName); int totalOffset; if (firstOrSinglePacket) { totalOffset = 8; if (payloadType == PayloadType.Generic) { totalOffset += 21; } else { totalOffset += 34; } } else { totalOffset = 8; } byte[] dataToSave = msdu.Data.Skip(totalOffset).ToArray(); dataToSave = dataToSave.Take(dataToSave.Length - 4).ToArray(); // Remove CRC 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) { string target = Path.Combine(FileHandler.TemporaryFileFolder, $"{msdu.APID:X3}-{LLTools.TimestampMS()}-{Tools.RandomString(8)}"); File.Move(filename, target); if (payloadType == PayloadType.Generic) { fileHandleManager.NewFile(new Tuple <string, object>(target, msduInfo.GenericHeader)); } else { fileHandleManager.NewFile(new Tuple <string, object>(target, msduInfo.ImageHeader)); } msduCache.Remove(msdu.APID); } } catch (Exception e) { UIConsole.Error(String.Format("Exception on FinishMSDU: {0}", e)); } }