/// <summary> /// Unmarshals the data stored in the specified <paramref name="buffer"/> into this /// <see cref="NcomPacket"/>. If no marshalled NCOM packet can be found, /// <see langword="false"/> is returned. /// </summary> /// <param name="buffer">The byte array containing the marshalled NCOM packet.</param> /// <param name="offset"> /// The zero-based index indicating the location in the buffer to start looking for a sync /// byte from. /// </param> /// <returns> /// <see langword="false"/> if no marshalled NCOM packet can be found, otherwise /// <see langword="true"/>. /// </returns> /// <exception cref="ArgumentNullException"> /// When the <paramref name="buffer"/> is null. /// </exception> /// <exception cref="IndexOutOfRangeException"> /// When the <paramref name="offset"/> is less than <c>0</c>. /// </exception> /// <remarks> /// <para> /// If the first byte of the buffer is not <see cref="SyncByte"/> then the method will look /// for the first occurance of the sync byte. /// </para> /// <para> /// The <paramref name="offset"/> can be greater than the length of the /// <paramref name="buffer"/> without throwing an exception, returning /// <see langword="false"/>. This allows for easy unmarshalling of multiple consecutive /// packets, e.g. <see langword="while" /> loops. /// </para> /// </remarks> public virtual bool Unmarshal(byte[] buffer, int offset) { // Check that the buffer is not null if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } // Check that the offset is in the expected range if (offset < 0) { throw new IndexOutOfRangeException("Offset in buffer can not be less than zero"); } // Seek the sync byte while (offset <= buffer.Length - PacketLength) { // Have we found the sync byte? if (buffer[offset++] == SyncByte) { // packet found. offset now points to [1] // Get navigation status byte NavigationStatus = ByteHandling.ParseEnum(buffer[offset + 20], NavigationStatus.Unknown); // Calculate Checksum 3 Checksum3 = CalculateChecksum(buffer, offset, 70) == buffer[offset + PacketLength - 2]; // Unmarshalled OK, return true return(true); } } // Couldn't find packet, return false; return(false); }
/// <summary> /// Unmarshals the data stored in the specified <paramref name="buffer" /> into this /// <see cref="NcomPacket" />. If no marshalled NCOM packet can be found, /// <see langword="false" /> is returned. /// </summary> /// <param name="buffer">The byte array containing the marshalled NCOM packet.</param> /// <param name="offset">The zero-based index indicating the location in the buffer to start looking for a sync /// byte from.</param> /// <returns> /// <see langword="false" /> if no marshalled NCOM packet can be found, otherwise /// <see langword="true" />. /// </returns> /// <remarks> /// <para> /// If the first byte of the buffer is not <see cref="NcomPacket.SyncByte" /> then the method will look /// for the first occurance of the sync byte. /// </para> /// <para> /// The <paramref name="offset" /> can be greater than the length of the /// <paramref name="buffer" /> without throwing an exception, returning /// <see langword="false" />. This allows for easy unmarshalling of multiple consecutive /// packets, e.g. <see langword="while" /> loops. /// </para> /// </remarks> public override bool Unmarshal(byte[] buffer, int offset) { // Check that the buffer is not null if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } // Check that the offset is in the expected range if (offset < 0) { throw new IndexOutOfRangeException("Offset in buffer can not be less than zero"); } // Seek the sync byte while (offset <= buffer.Length - PacketLength) { // Have we found the sync byte? if (buffer[offset++] == SyncByte) { int pkt_start = offset - 1; // offset points to pkt[1] // Call base method if (!base.Unmarshal(buffer, offset - 1)) { return(false); } // Check the navigation status byte if (!AllowedNavigationStatus.Contains(NavigationStatus)) { return(false); } // Batch A // -------- // Extract the time Time = ByteHandling.UnmarshalUInt16(buffer, ref offset); // Extract the Accelerations AccelerationX = ByteHandling.UnmarshalInt24(buffer, ref offset) * AccelerationScaling; AccelerationY = ByteHandling.UnmarshalInt24(buffer, ref offset) * AccelerationScaling; AccelerationZ = ByteHandling.UnmarshalInt24(buffer, ref offset) * AccelerationScaling; // Extract the Angular Rates AngularRateX = ByteHandling.UnmarshalInt24(buffer, ref offset) * AngularRateScaling; AngularRateY = ByteHandling.UnmarshalInt24(buffer, ref offset) * AngularRateScaling; AngularRateZ = ByteHandling.UnmarshalInt24(buffer, ref offset) * AngularRateScaling; // Skip a bit for the nav status byte offset++; // Extract checksum 1 Checksum1 = CalculateChecksum(buffer, pkt_start + 1, 21) == buffer[offset]; offset++; // Batch B // -------- // Extract Latitude, Longitude and altitude Latitude = ByteHandling.UnmarshalDouble(buffer, ref offset); Longitude = ByteHandling.UnmarshalDouble(buffer, ref offset); Altitude = ByteHandling.UnmarshalSingle(buffer, ref offset); // Extract velocities NorthVelocity = ByteHandling.UnmarshalInt24(buffer, ref offset) * VeloityScaling; EastVelocity = ByteHandling.UnmarshalInt24(buffer, ref offset) * VeloityScaling; DownVelocity = ByteHandling.UnmarshalInt24(buffer, ref offset) * VeloityScaling; // Extract Heading, Pitch and Roll Heading = ByteHandling.UnmarshalInt24(buffer, ref offset) * OrientationScaling; Pitch = ByteHandling.UnmarshalInt24(buffer, ref offset) * OrientationScaling; Roll = ByteHandling.UnmarshalInt24(buffer, ref offset) * OrientationScaling; // Extract checksum 2 Checksum2 = CalculateChecksum(buffer, pkt_start + 1, 60) == buffer[offset]; offset++; // Batch S // -------- // Extract status channel (and status channel byte) byte statusChannelByte = buffer[offset++]; StatusChannel = StatusChannelFactory.Unmarshal(statusChannelByte, buffer, ref offset); // Unmarshalled OK, return true return(true); } } // Couldn't find packet, return false; return(false); }
/// <summary> /// Marshals this <see cref="NcomPacketA"/> into a byte array of length /// <see cref="NcomPacket.PacketLength"/>. /// </summary> /// <returns> /// A <see cref="byte"/> array of length equal to <see cref="NcomPacket.PacketLength"/>. /// </returns> public override byte[] Marshal() { // Call base method to get byte array to marshal into byte[] buffer = base.Marshal(); int offset = 1; // Batch A // -------- // Insert Time ByteHandling.Marshal(buffer, ref offset, (ushort)(Time % MaxTimeValue)); // Insert accelerations ByteHandling.MarshalInt24(buffer, ref offset, (int)(AccelerationX / AccelerationScaling)); ByteHandling.MarshalInt24(buffer, ref offset, (int)(AccelerationY / AccelerationScaling)); ByteHandling.MarshalInt24(buffer, ref offset, (int)(AccelerationZ / AccelerationScaling)); // Insert Angular Rates ByteHandling.MarshalInt24(buffer, ref offset, (int)(AngularRateX / AngularRateScaling)); ByteHandling.MarshalInt24(buffer, ref offset, (int)(AngularRateY / AngularRateScaling)); ByteHandling.MarshalInt24(buffer, ref offset, (int)(AngularRateZ / AngularRateScaling)); // Skip over nav. status offset++; // Calculate and insert Checksum 1 buffer[offset] = CalculateChecksum(buffer, 1, offset - 2); offset++; // Batch B // -------- // Insert Latitude, Longitude and altitude ByteHandling.Marshal(buffer, ref offset, Latitude); ByteHandling.Marshal(buffer, ref offset, Longitude); ByteHandling.Marshal(buffer, ref offset, Altitude); // Insert Velocities ByteHandling.MarshalInt24(buffer, ref offset, (int)(NorthVelocity / VeloityScaling)); ByteHandling.MarshalInt24(buffer, ref offset, (int)(EastVelocity / VeloityScaling)); ByteHandling.MarshalInt24(buffer, ref offset, (int)(DownVelocity / VeloityScaling)); // Insert Heading, Pitch and Roll ByteHandling.MarshalInt24(buffer, ref offset, (int)(Heading / OrientationScaling)); ByteHandling.MarshalInt24(buffer, ref offset, (int)(Pitch / OrientationScaling)); ByteHandling.MarshalInt24(buffer, ref offset, (int)(Roll / OrientationScaling)); // Calculate and insert Checksum 2 buffer[offset] = CalculateChecksum(buffer, 1, offset - 2); offset++; // Batch S // -------- // Insert Status Channel if (StatusChannel != null) { buffer[offset++] = StatusChannel.StatusChannelByte; StatusChannel.Marshal(buffer, ref offset); } else { buffer[offset++] = 0xFF; offset += StatusChannelLength; } // Calculate and insert Checksum 3 buffer[offset] = CalculateChecksum(buffer, 1, offset - 2); // Return the marshalled NCOM packet return(buffer); }