예제 #1
0
 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");
 }
예제 #2
0
        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}");
            }
        }
예제 #3
0
 public void AddMetadataFrom(GrbData grbData)
 {
     Metadata = grbData.Metadata;
     try {
         ParseMetadataFromText(Metadata);
     } catch (Exception e) {
         UIConsole.Error($"Error parsing metadata: {e.Message}");
     }
 }
예제 #4
0
        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);
            }
        }
예제 #5
0
 /// <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}");
         }
     }
 }
예제 #6
0
        /// <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);
        }
예제 #7
0
 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}");
     }
 }
예제 #8
0
 /// <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}");
         }
     }
 }
예제 #9
0
 public void Stop()
 {
     if (running)
     {
         UIConsole.Log("Stopping Thread");
         running = false;
         channelThread.Join();
     }
     else
     {
         UIConsole.Error("MSDU Manager already stopped!");
     }
 }
예제 #10
0
 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;
     }
 }
예제 #11
0
        /// <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);
                }
            }
        }
예제 #12
0
 /// <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);
     }
 }
예제 #13
0
 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!");
     }
 }
예제 #14
0
 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!");
     }
 }
예제 #15
0
        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);
        }
예제 #16
0
        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);
            }
        }
예제 #17
0
        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());
        }
예제 #18
0
        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();
            }
        }
예제 #19
0
        /// <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);
                }
            }
        }
예제 #20
0
        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);
                }
            }
        }
예제 #21
0
        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);
            }
        }
예제 #22
0
        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);
        }
예제 #23
0
        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));
            }
        }