/// <summary> /// Create an ensemble package based off the buffer given. /// This will combine all the sentences into an ensemble. /// It will convert the ensemble to byte array and create /// an Ensemble package. /// </summary> /// <param name="buffer">Buffer of NMEA sentences.</param> /// <returns>Ensemble package containing ensemble data.</returns> protected DataSet.EnsemblePackage CreateEnsemble(List <NmeaSentence> buffer) { DataSet.EnsemblePackage package = new DataSet.EnsemblePackage(); // If no data, move on if (buffer.Count == 0) { package.Ensemble = null; package.RawEnsemble = null; return(package); } // Convert the sentences to an ensemble. try { var ens = DecodeSentences(buffer); if (ens != null) { package.Ensemble = ens; package.RawEnsemble = ens.Encode(); package.OrigDataFormat = AdcpCodec.CodecEnum.DVL; } } catch (Exception e) { StringBuilder sb = new StringBuilder(); foreach (var line in buffer) { sb.Append(line); } log.Error("Error Decoding DVL ensemble. " + sb.ToString(), e); } return(package); }
/// <summary> /// Find the entire ensemble in the file. This will look for the start location. /// Decode the payload size and checksum. If they are good, then generate an /// ensemble from the data. Add the data to the list and return it. /// /// IF isReturnEnsList to false, then returned list will be empty. This will /// save ram. The user will then need to use the events to get all the data. /// </summary> /// <param name="ensStart">List of all the ensembles.</param> /// <param name="file">File to look for the ensembles.</param> /// <param name="isReturnEnsList">Set flag whether to return a list of ensembles or let the user only use the events.</param> /// <returns>List of all the ensembles in the file.</returns> protected List <DataSet.EnsemblePackage> FindCompleteEnsembles(List <int> ensStart, string file, bool isReturnEnsList = true) { var list = new List <DataSet.EnsemblePackage>(ensStart.Count); using (var fileStream = new BinaryReader(File.Open(file, FileMode.Open, FileAccess.Read))) { // Go through each start location foreach (var start in ensStart) { try { // Move the start location and read in the header fileStream.BaseStream.Seek(start, SeekOrigin.Begin); byte[] buffer = fileStream.ReadBytes(DataSet.Ensemble.ENSEMBLE_HEADER_LEN); if (buffer.Length >= DataSet.Ensemble.ENSEMBLE_HEADER_LEN) { // Get the payload size int payloadSize = buffer[24]; payloadSize += buffer[25] << 8; payloadSize += buffer[26] << 16; payloadSize += buffer[27] << 24; // Get the payload inverse int notPayloadSize = buffer[28]; notPayloadSize += buffer[29] << 8; notPayloadSize += buffer[30] << 16; notPayloadSize += buffer[31] << 24; notPayloadSize = ~notPayloadSize; // Check the payload value is correct based off the inverse if (payloadSize == notPayloadSize) { // Get the ensemble size int ensSize = DataSet.Ensemble.CalculateEnsembleSize(payloadSize); // Sanity check // Check if it is too small or too large if (ensSize > DataSet.Ensemble.ENSEMBLE_HEADER_LEN && ensSize < MathHelper.MB_TO_BYTES) { // Get the entire ensemble fileStream.BaseStream.Seek(start, SeekOrigin.Begin); byte[] rawEns = fileStream.ReadBytes(ensSize); // Check the checksum long calculatedChecksum = DataSet.Ensemble.CalculateEnsembleChecksum(rawEns); long ensembleChecksum = DataSet.Ensemble.RetrieveEnsembleChecksum(rawEns); if (calculatedChecksum == ensembleChecksum) { // Pass event that a good ensemble was found if (GoodEnsembleEvent != null) { GoodEnsembleEvent(); } // Decode the ensemble and add it to the list var ens = DataSet.Ensemble.DecodeRawAdcpData(rawEns); // Set the file name ens.FileName = file; if (isReturnEnsList) { // Package the data var ensPak = new DataSet.EnsemblePackage(); ensPak.Ensemble = ens; ensPak.RawEnsemble = rawEns; ensPak.OrigDataFormat = AdcpCodec.CodecEnum.Binary; list.Add(ensPak); } // Publish the data // Send an event that data was processed // in this format if (ProcessDataEvent != null) { ProcessDataEvent(rawEns, ens); } //Debug.WriteLine("Ens: " + ens.EnsembleData.EnsembleNumber + " Count: " + count + " " + System.DateTime.Now); } else { // Pass event that a bad ensemble was found if (BadEnsembleEvent != null) { BadEnsembleEvent(); } } } else { Debug.WriteLine("AdcpBinaryCodecReadFile::Ensemble Size to large or small:" + start + ":" + ensSize); } } else { Debug.WriteLine("AdcpBinaryCodecReadFile::Playload and Inv do not match:" + start + " : " + payloadSize + ":" + notPayloadSize); } } } catch (Exception e) { log.Error("Error looking for an ensemble. Loc: " + start, e); } } } return(list); }
/// <summary> /// Parse the incoming packet for all the Data Sets. /// Add the data to a AdcpDataSet variable and /// return the filled variable when complete. /// </summary> /// <param name="binaryEnsemble">Byte array containing data from an ADCP.</param> /// <returns>Object holding decoded ADCP data.</returns> public DataSet.EnsemblePackage DecodeAdcpData(byte[] binaryEnsemble) { // Keep track where in the packet // we are currently decoding int packetPointer = DataSet.Ensemble.ENSEMBLE_HEADER_LEN; int type = 0; int numElements = 0; int elementMultiplier = 0; int imag = 0; int nameLen = 0; string name = ""; int dataSetSize = 0; Ensemble ensemble = new Ensemble(); for (int i = 0; i < DataSet.Ensemble.MAX_NUM_DATA_SETS; i++) { //Debug.Print("binaryEnsemble: " + binaryEnsemble.Length + " packetPointer: " + packetPointer + "\n"); type = MathHelper.ByteArrayToInt32(binaryEnsemble, packetPointer + (DataSet.Ensemble.BYTES_IN_INT32 * 0)); numElements = MathHelper.ByteArrayToInt32(binaryEnsemble, packetPointer + (DataSet.Ensemble.BYTES_IN_INT32 * 1)); elementMultiplier = MathHelper.ByteArrayToInt32(binaryEnsemble, packetPointer + (DataSet.Ensemble.BYTES_IN_INT32 * 2)); imag = MathHelper.ByteArrayToInt32(binaryEnsemble, packetPointer + (DataSet.Ensemble.BYTES_IN_INT32 * 3)); nameLen = MathHelper.ByteArrayToInt32(binaryEnsemble, packetPointer + (DataSet.Ensemble.BYTES_IN_INT32 * 4)); name = MathHelper.ByteArrayToString(binaryEnsemble, 8, packetPointer + (DataSet.Ensemble.BYTES_IN_FLOAT * 5)); // Verify the data is good if (string.IsNullOrEmpty(name)) { break; } //Debug.Print("name: " + name + "\n"); //Debug.Print("numElements: " + numElements + "\n"); //Debug.Print("elementMultiplier" + elementMultiplier + "\n"); // Get the size of this data set dataSetSize = BaseDataSet.GetDataSetSize(type, nameLen, numElements, elementMultiplier); if (Ensemble.BeamVelocityID.Equals(name, StringComparison.Ordinal)) { // Create a sub array of just this data set data byte[] velData = MathHelper.SubArray <byte>(binaryEnsemble, packetPointer, dataSetSize); // Add the data ensemble.AddBeamVelocityData(type, numElements, elementMultiplier, imag, nameLen, name, velData); //Debug.WriteLine(adcpData.BeamVelocityData.ToString()); // Advance the packet pointer packetPointer += dataSetSize; } else if (Ensemble.InstrumentVelocityID.Equals(name, StringComparison.Ordinal)) { // Create a sub array of just this data set data byte[] velData = MathHelper.SubArray <byte>(binaryEnsemble, packetPointer, dataSetSize); // Add the data ensemble.AddInstrumentVelocityData(type, numElements, elementMultiplier, imag, nameLen, name, velData); //Debug.WriteLine(adcpData.InstrVelocityData.ToString()); // Advance the packet pointer packetPointer += dataSetSize; } else if (Ensemble.EarthVelocityID.Equals(name, StringComparison.Ordinal)) { // Create a sub array of just this data set data byte[] velData = MathHelper.SubArray <byte>(binaryEnsemble, packetPointer, dataSetSize); // Add the data ensemble.AddEarthVelocityData(type, numElements, elementMultiplier, imag, nameLen, name, velData); //Debug.WriteLine(adcpData.EarthVelocityData.ToString()); // Advance the packet pointer packetPointer += dataSetSize; } else if (Ensemble.AmplitudeID.Equals(name, StringComparison.Ordinal)) { // Create a sub array of just this data set data byte[] ampData = MathHelper.SubArray <byte>(binaryEnsemble, packetPointer, dataSetSize); // Add the data ensemble.AddAmplitudeData(type, numElements, elementMultiplier, imag, nameLen, name, ampData); //Debug.WriteLine(adcpData.AmplitudeData.ToString()); // Advance the packet pointer packetPointer += dataSetSize; } else if (Ensemble.CorrelationID.Equals(name, StringComparison.Ordinal)) { // Create a sub array of just this data set data byte[] corrData = MathHelper.SubArray <byte>(binaryEnsemble, packetPointer, dataSetSize); // Add the data ensemble.AddCorrelationData(type, numElements, elementMultiplier, imag, nameLen, name, corrData); //Debug.WriteLine(adcpData.CorrelationData.ToString()); // Advance the packet pointer packetPointer += dataSetSize; } else if (Ensemble.GoodBeamID.Equals(name, StringComparison.Ordinal)) { // Create a sub array of just this data set data byte[] goodBeamData = MathHelper.SubArray <byte>(binaryEnsemble, packetPointer, dataSetSize); // Add the data ensemble.AddGoodBeamData(type, numElements, elementMultiplier, imag, nameLen, name, goodBeamData); //Debug.WriteLine(adcpData.GoodBeamData.ToString()); // Advance the packet pointer packetPointer += dataSetSize; } else if (Ensemble.GoodEarthID.Equals(name, StringComparison.Ordinal)) { // Create a sub array of just this data set data byte[] goodEarthData = MathHelper.SubArray <byte>(binaryEnsemble, packetPointer, dataSetSize); // Add the data ensemble.AddGoodEarthData(type, numElements, elementMultiplier, imag, nameLen, name, goodEarthData); //Debug.WriteLine(adcpData.GoodEarthData.ToString()); // Advance the packet pointer packetPointer += dataSetSize; } else if (Ensemble.EnsembleDataID.Equals(name, StringComparison.Ordinal)) { // Create a sub array of just this data set data byte[] ensembleData = MathHelper.SubArray <byte>(binaryEnsemble, packetPointer, dataSetSize); // Add the data ensemble.AddEnsembleData(type, numElements, elementMultiplier, imag, nameLen, name, ensembleData); //Debug.WriteLine(adcpData.EnsembleData.ToString()); // Advance the packet pointer packetPointer += dataSetSize; } else if (Ensemble.AncillaryID.Equals(name, StringComparison.Ordinal)) { // Create a sub array of just this data set data byte[] ancillaryData = MathHelper.SubArray <byte>(binaryEnsemble, packetPointer, dataSetSize); // Add the data ensemble.AddAncillaryData(type, numElements, elementMultiplier, imag, nameLen, name, ancillaryData); //Debug.WriteLine(adcpData.AncillaryData.ToString()); // Advance the packet pointer packetPointer += dataSetSize; } else if (Ensemble.BottomTrackID.Equals(name, StringComparison.Ordinal)) { // Create a sub array of just this data set data byte[] bottomTrackData = MathHelper.SubArray <byte>(binaryEnsemble, packetPointer, dataSetSize); // Add the data ensemble.AddBottomTrackData(type, numElements, elementMultiplier, imag, nameLen, name, bottomTrackData); //Debug.WriteLine(adcpData.BottomTrackData.ToString()); // Advance the packet pointer packetPointer += dataSetSize; } else if (Ensemble.NmeaID.Equals(name, StringComparison.Ordinal)) { // List of all data read byte[] nmeaData = new byte[dataSetSize]; // Scan through the data set and store all the data for (int x = 0; x < dataSetSize; x++) { nmeaData[x] = binaryEnsemble[packetPointer++]; } // Add the data ensemble.AddNmeaData(type, numElements, elementMultiplier, imag, nameLen, name, nmeaData); //Debug.WriteLine(adcpData.NmeaData.ToString()); } else if (Ensemble.ProfileEngineeringID.Equals(name, StringComparison.Ordinal)) { // Create a sub array of just this data set data byte[] peData = MathHelper.SubArray <byte>(binaryEnsemble, packetPointer, dataSetSize); // Add the data ensemble.AddProfileEngineeringData(type, numElements, elementMultiplier, imag, nameLen, name, peData); //Debug.WriteLine(adcpData.BottomTrackData.ToString()); // Advance the packet pointer packetPointer += dataSetSize; } else if (Ensemble.BottomTrackEngineeringID.Equals(name, StringComparison.Ordinal)) { // Create a sub array of just this data set data byte[] bteData = MathHelper.SubArray <byte>(binaryEnsemble, packetPointer, dataSetSize); // Add the data ensemble.AddBottomTrackEngineeringData(type, numElements, elementMultiplier, imag, nameLen, name, bteData); //Debug.WriteLine(adcpData.BottomTrackData.ToString()); // Advance the packet pointer packetPointer += dataSetSize; } else if (Ensemble.SystemSetupID.Equals(name, StringComparison.Ordinal)) { // Create a sub array of just this data set data byte[] ssData = MathHelper.SubArray <byte>(binaryEnsemble, packetPointer, dataSetSize); // Add the data ensemble.AddSystemSetupData(type, numElements, elementMultiplier, imag, nameLen, name, ssData); //Debug.WriteLine(adcpData.BottomTrackData.ToString()); // Advance the packet pointer packetPointer += dataSetSize; } else if (Ensemble.RangeTrackingID.Equals(name, StringComparison.Ordinal)) { // Create a sub array of just this data set data byte[] rtData = MathHelper.SubArray <byte>(binaryEnsemble, packetPointer, dataSetSize); // Add the data ensemble.AddRangeTrackingData(type, numElements, elementMultiplier, imag, nameLen, name, rtData); //Debug.WriteLine(adcpData.RangeTrackingData.ToString()); // Advance the packet pointer packetPointer += dataSetSize; } else if (Ensemble.GageHeightID.Equals(name, StringComparison.Ordinal)) { // Create a sub array of just this data set data byte[] ghData = MathHelper.SubArray <byte>(binaryEnsemble, packetPointer, dataSetSize); // Add the data ensemble.AddGageHeightData(type, numElements, elementMultiplier, imag, nameLen, name, ghData); //Debug.WriteLine(adcpData.GageHeightData.ToString()); // Advance the packet pointer packetPointer += dataSetSize; } else if (Ensemble.Adcp2InfoID.Equals(name, StringComparison.Ordinal)) { // Create a sub array of just this data set data byte[] adcp2InfoData = MathHelper.SubArray <byte>(binaryEnsemble, packetPointer, dataSetSize); // Add the data ensemble.AddAdcp2InfoData(type, numElements, elementMultiplier, imag, nameLen, name, adcp2InfoData); //Debug.WriteLine(adcpData.GageHeightData.ToString()); // Advance the packet pointer packetPointer += dataSetSize; } else { // Advance the packet pointer packetPointer += dataSetSize; } //Debug.Print("DataSetSize: " + dataSetSize + "\n"); //Debug.Print(" packetPointer: " + packetPointer + "\n"); if (packetPointer + 4 >= binaryEnsemble.Length || packetPointer < 0) { break; } } // If NMEA data is available, add it to the dataset // Add it to both the binary data and ensemble object if (_nmeaBuffer.Count > 0) { // Create a NMEA dataset MergeNmeaDataSet(ref ensemble); // Add the NMEA binary data to binary data if (ensemble.IsNmeaAvail) { MergeNmeaBinary(ref binaryEnsemble, ensemble.NmeaData); } } // Send an event that data was processed // in this format //if (ProcessDataEvent != null) //{ // ProcessDataEvent(binaryEnsemble, ensemble); //} // Set the values to return var pak = new DataSet.EnsemblePackage(); pak.Ensemble = ensemble; pak.RawEnsemble = binaryEnsemble; return(pak); }
/// <summary> /// Find the entire ensemble in the file. This will look for the start location. /// Decode the payload size and checksum. If they are good, then generate an /// ensemble from the data. Add the data to the list and return it. /// </summary> /// <param name="ensStart">List of all the ensembles.</param> /// <param name="file">File to look for the ensembles.</param> /// <returns>List of all the ensembles in the file.</returns> protected List <DataSet.EnsemblePackage> FindCompleteEnsembles(List <int> ensStart, string file) { var list = new List <DataSet.EnsemblePackage>(); using (var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read)) { foreach (var start in ensStart) { try { var buffer = new byte[DataSet.Ensemble.ENSEMBLE_HEADER_LEN]; //Buffer is byte array of size 32. In Binary codec, buffer is byte array of size 32, containing 32 bytes from file // Move the start location and read in the header fileStream.Seek(start, SeekOrigin.Begin); if (fileStream.Read(buffer, 0, buffer.Length) >= DataSet.Ensemble.ENSEMBLE_HEADER_LEN) // Always true, buffer always size of variable, this loads in bytes to Buffer, however { // Get the payload size int payloadSize = MathHelper.LsbMsbInt(buffer[2], buffer[3]) + PD0.CHECKSUM_NUM_BYTE; //When referencing positions in buffer, uses "start" Which implies it is looking for the position in the actual file. (Error?) // Get the ensemble size int ensSize = MathHelper.LsbMsbInt(buffer[2], buffer[3]) + PD0.CHECKSUM_NUM_BYTE; // Same equation as payload size, but the LsbMsbInt Might change buffer itself? // Sanity check if (ensSize > DataSet.Ensemble.ENSEMBLE_HEADER_LEN) { // Get the entire ensemble var rawEns = new byte[ensSize]; fileStream.Seek(start, SeekOrigin.Begin); fileStream.Read(rawEns, 0, rawEns.Length); // Check the checksum ushort calculatedChecksum = PD0.CalculateChecksum(rawEns, ensSize - PD0.CHECKSUM_NUM_BYTE); ushort ensembleChecksum = MathHelper.LsbMsbUShort(rawEns[rawEns.Length - 2], rawEns[rawEns.Length - 1]); if (calculatedChecksum == ensembleChecksum) { // Pass event that a good ensemble was found if (GoodEnsembleEvent != null) { GoodEnsembleEvent(); } //Pd0Codec _pd0Codec = new Pd0Codec(); //PD0 pd0 = _pd0Codec.DecodePd0Data(rawEns); PD0 pd0Ensemble = new PD0(rawEns); DataSet.Ensemble ens = new DataSet.Ensemble(pd0Ensemble); ens.FileName = file; // Generate a subsystem so that multiple configurations can be seprated // PD0 does not contain the CEPO index or CEPO Configuraiton Index if (ens.IsEnsembleAvail) { ens.EnsembleData.SubsystemConfig = _pd0SubsystemGen.GenSubsystem(ens); } // Package the data var ensPak = new DataSet.EnsemblePackage(); ensPak.Ensemble = ens; ensPak.RawEnsemble = rawEns; ensPak.OrigDataFormat = AdcpCodec.CodecEnum.PD0; list.Add(ensPak); } else { // Pass event that a good ensemble was found if (BadEnsembleEvent != null) { BadEnsembleEvent(); } } } } } catch (Exception e) { log.Error("Error looking for an ensemble. Loc: " + start, e); } } } return(list); }