blob: 14d87d139d9a36006f078349a046b1623b1bb0da [file] [log] [blame]
/*
* Copyright (c) 2016 Audi AG
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.mdm.mdfsorter.mdf4;
import java.io.IOException;
import java.math.BigInteger;
import org.eclipse.mdm.mdfsorter.MDFParser;
/**
* The Channel Block.
*
* @author Christian Rechner, Tobias Leemann
*
*/
public class CNBLOCK extends MDF4GenBlock {
/** Data section */
// Channel type
// 0 = fixed length data channel channel value is contained in record.
// 1 = variable length data channel also denoted as "variable length signal
// data" (VLSD) channel
// 2 = master channel for all signals of this group
// 3 = virtual master channel
// 4 = synchronization channel
// 5 = maximum length data channel
// 6 = virtual data channel
// UINT8
private byte channelType;
// Sync type:
// 0 = None (to be used for normal data channels)
// 1 = Time (physical values must be seconds)
// 2 = Angle (physical values must be radians)
// 3 = Distance (physical values must be meters)
// 4 = Index (physical values must be zero-based index values)
// UINT8
private byte syncType;
// Channel data type of raw signal value
// 0 = unsigned integer (LE Byte order)
// 1 = unsigned integer (BE Byte order)
// 2 = signed integer (two’s complement) (LE Byte order)
// 3 = signed integer (two’s complement) (BE Byte order)
// 4 = IEEE 754 floating-point format (LE Byte order)
// 5 = IEEE 754 floating-point format (BE Byte order)
// 6 = String (SBC, standard ASCII encoded (ISO-8859-1 Latin), NULL
// terminated)
// 7 = String (UTF-8 encoded, NULL terminated)
// 8 = String (UTF-16 encoded LE Byte order, NULL terminated)
// 9 = String (UTF-16 encoded BE Byte order, NULL terminated)
// 10 = Byte Array with unknown content (e.g. structure)
// 11 = MIME sample (sample is Byte Array with MIME content-type specified
// in cn_md_unit)
// 12 = MIME stream (all samples of channel represent a stream with MIME
// content-type specified in cn_md_unit)
// 13 = CANopen date (Based on 7 Byte CANopen Date data structure, see Table
// 36)
// 14 = CANopen time (Based on 6 Byte CANopen Time data structure, see Table
// 37)
// UINT8
private byte dataType;
// Bit offset (0-7): first bit (=LSB) of signal value after Byte offset has
// been applied.
// If zero, the signal value is 1-Byte aligned. A value different to zero is
// only allowed for Integer data types
// (cn_data_type ≤ 3) and if the Integer signal value fits into 8 contiguous
// Bytes (cn_bit_count + cn_bit_offset ≤
// 64). For all other cases, cn_bit_offset must be zero.
// UINT8
private byte bitOffset;
// Offset to first Byte in the data record that contains bits of the signal
// value. The offset is applied to the
// plain record data, i.e. skipping the record ID.
// UINT32
private long byteOffset;
// Number of bits for signal value in record.
// UINT32
private long bitCount;
// The value contains the following bit flags (Bit 0 = LSB):
// Bit 0: All values invalid flag
// Bit 1: Invalidation bit valid flag
// Bit 2: Precision valid flag
// Bit 3: Value range valid flag
// Bit 4: Limit range valid flag
// Bit 5: Extended limit range valid flag
// Bit 6: Discrete value flag
// Bit 7: Calibration flag
// Bit 8: Calculated flag
// Bit 10: Bus event flag
// Bit 11: Monotonous flag
// Bit 12: Default X axis flag
// UINT32
private long flags;
// Position of invalidation bit.
// The invalidation bit can be used to specify if the signal value in the
// current record is valid or not.
// Note: the invalidation bit is optional and can only be used if the
// "invalidation bit valid" flag (bit 1) is set.
// UINT32
private long invalBitPos;
// Precision for display of floating point values.
// 0xFF means unrestricted precision (infinite).
// Any other value specifies the number of decimal places to use for display
// of floating point values.
// Only valid if "precision valid" flag (bit 2) is set
// UINT8
private byte precision;
// Length N of cn_at_reference list, i.e. number of attachments for this
// channel. Can be zero.
// UINT16
private int attachmentCount;
// Minimum signal value that occurred for this signal (raw value)
// Only valid if "value range valid" flag (bit 3) is set.
// REAL
private double valRangeMin;
// Maximum signal value that occurred for this signal (raw value)
// Only valid if "value range valid" flag (bit 3) is set.
// REAL
private double valRangeMax;
// Lower limit for this signal (physical value for numeric conversion rule,
// otherwise raw value)
// Only valid if "limit range valid" flag (bit 4) is set.
// REAL
private double limitMin;
// Upper limit for this signal (physical value for numeric conversion rule,
// otherwise raw value)
// Only valid if "limit range valid" flag (bit 4) is set.
// REAL
private double limitMax;
// Lower extended limit for this signal (physical value for numeric
// conversion rule, otherwise raw value)
// Only valid if "extended limit range valid" flag (bit 5) is set.
// If cn_limit_min is valid, cn_limit_min must be larger or equal to
// cn_limit_ext_min.
// REAL
private double limitExtMin;
// Upper extended limit for this signal (physical value for numeric
// conversion rule, otherwise raw value)
// Only valid if "extended limit range valid" flag (bit 5) is set.
// If cn_limit_max is valid, cn_limit_max must be less or equal to
// cn_limit_ext_max.
// REAL
private double limitExtMax;
/**
* Parse a HLBLOCK from an existing MDFGenBlock
*
* @param parent
* The already existing MDF Generic Block.
*/
public CNBLOCK(MDF4GenBlock parent) {
super(parent.getPos());
setLength(parent.getLength());
setLinkCount(parent.getLinkCount());
setId(parent.getId());
setLinks(parent.getLinks());
parent.setPrec(this);
}
public MDF4GenBlock getLnkCnNext() {
return links[0];
}
public MDF4GenBlock getLnkComposition() {
return links[1];
}
public MDF4GenBlock getLnkTxName() {
return links[2];
}
public MDF4GenBlock getLnkSiSource() {
return links[3];
}
public MDF4GenBlock getLnkCcConversion() {
return links[4];
}
public MDF4GenBlock getLnkData() {
return links[5];
}
public MDF4GenBlock getLnkMdUnit() {
return links[6];
}
public MDF4GenBlock getLnkMdComment() {
return links[7];
}
public MDF4GenBlock[] getLnkAtReference() {
MDF4GenBlock[] ret = new MDF4GenBlock[getAttachmentCount()];
System.arraycopy(links, 8, ret, 0, getAttachmentCount());
return ret;
}
public MDF4GenBlock[] getLnkDefaultX() {
if (getDefaultXFlag()) {
MDF4GenBlock[] ret = new MDF4GenBlock[3];
System.arraycopy(links, 8 + getAttachmentCount(), ret, 0, 3);
return ret;
} else {
return null;
}
}
public byte getChannelType() {
return channelType;
}
public byte getSyncType() {
return syncType;
}
public byte getDataType() {
return dataType;
}
public byte getBitOffset() {
return bitOffset;
}
public long getByteOffset() {
return byteOffset;
}
public long getBitCount() {
return bitCount;
}
public long getFlags() {
return flags;
}
public long getInvalBitPos() {
return invalBitPos;
}
public byte getPrecision() {
return precision;
}
public int getAttachmentCount() {
return attachmentCount;
}
public double getValRangeMin() {
return valRangeMin;
}
public double getValRangeMax() {
return valRangeMax;
}
public double getLimitMin() {
return limitMin;
}
public double getLimitMax() {
return limitMax;
}
public double getLimitExtMin() {
return limitExtMin;
}
public double getLimitExtMax() {
return limitExtMax;
}
private void setChannelType(byte channelType) {
this.channelType = channelType;
}
private void setSyncType(byte syncType) {
this.syncType = syncType;
}
private void setDataType(byte dataType) {
this.dataType = dataType;
}
private void setBitOffset(byte bitOffset) {
this.bitOffset = bitOffset;
}
private void setByteOffset(long byteOffset) {
this.byteOffset = byteOffset;
}
private void setBitCount(long bitCount) {
this.bitCount = bitCount;
}
private void setFlags(long flags) {
this.flags = flags;
}
private void setInvalBitPos(long invalBitPos) {
this.invalBitPos = invalBitPos;
}
private void setPrecision(byte precision) {
this.precision = precision;
}
private void setAttachmentCount(int attachmentCount) {
this.attachmentCount = attachmentCount;
}
private void setValRangeMin(double valRangeMin) {
this.valRangeMin = valRangeMin;
}
private void setValRangeMax(double valRangeMax) {
this.valRangeMax = valRangeMax;
}
private void setLimitMin(double limitMin) {
this.limitMin = limitMin;
}
private void setLimitMax(double limitMax) {
this.limitMax = limitMax;
}
private void setLimitExtMin(double limitExtMin) {
this.limitExtMin = limitExtMin;
}
private void setLimitExtMax(double limitExtMax) {
this.limitExtMax = limitExtMax;
}
/**
* Returns bit 12 of the flags ("default X"-flag).
*
* @return The "default X"-flag.
*/
public boolean getDefaultXFlag() {
return BigInteger.valueOf(flags).testBit(12);
}
@Override
public String toString() {
return "CNBLOCK [lnkCnNext=" + getLnkCnNext().getPos()
+ ", lnkComposition=" + getLnkComposition().getPos()
+ ", lnkTxName=" + getLnkTxName().getPos() + ", lnkSiSource="
+ getLnkSiSource().getPos() + ", lnkCcConversion="
+ getLnkComposition().getPos() + ", lnkData="
+ getLnkData().getPos() + ", lnkMdUnit="
+ getLnkMdUnit().getPos() + ", lnkMdComment="
+ getLnkMdComment().getPos() + ", lnkAtReference=" + "{"
+ getLnkAtReference().length + "}" + ", lnkDefaultX=" + "{"
+ getLnkDefaultX().length + "}" + ", channelType=" + channelType
+ ", syncType=" + syncType + ", dataType=" + dataType
+ ", bitOffset=" + bitOffset + ", byteOffset=" + byteOffset
+ ", bitCount=" + bitCount + ", flags=" + flags
+ ", invalBitPos=" + invalBitPos + ", precision=" + precision
+ ", attachmentCount=" + attachmentCount + ", valRangeMin="
+ valRangeMin + ", valRangeMax=" + valRangeMax + ", limitMin="
+ limitMin + ", limitMax=" + limitMax + ", limitExtMin="
+ limitExtMin + ", limitExtMax=" + limitExtMax + "]";
}
@Override
public void parse(byte[] content) throws IOException {
// UINT8: Channel type
setChannelType(content[0]);
// UINT8: Sync type
setSyncType(content[1]);
// UINT8: Channel data type of raw signal value
setDataType(content[2]);
// UINT8: Bit offset (0-7)
setBitOffset(content[3]);
// UINT32: Offset to first Byte in the data record that contains bits of
// the signal value.
setByteOffset(
MDF4Util.readUInt32(MDFParser.getDataBuffer(content, 4, 8)));
// UINT32: Number of bits for signal value in record.
setBitCount(
MDF4Util.readUInt32(MDFParser.getDataBuffer(content, 8, 12)));
// UINT32: Flags
setFlags(MDF4Util.readUInt32(MDFParser.getDataBuffer(content, 12, 16)));
// UINT32: Position of invalidation bit.
setInvalBitPos(
MDF4Util.readUInt32(MDFParser.getDataBuffer(content, 16, 20)));
// UINT8: Precision for display of floating point values.
setPrecision(content[20]);
// Skip 1 BYTE: Reserved
// UINT16: Length N of cn_at_reference list, i.e. number of attachments
// for this channel. Can be zero.
setAttachmentCount(
MDF4Util.readUInt16(MDFParser.getDataBuffer(content, 22, 24)));
// REAL: Minimum signal value that occurred for this signal (raw value)
setValRangeMin(
MDF4Util.readReal(MDFParser.getDataBuffer(content, 24, 32)));
// REAL: Maximum signal value that occurred for this signal (raw value)
setValRangeMax(
MDF4Util.readReal(MDFParser.getDataBuffer(content, 32, 40)));
// REAL: Lower limit for this signal (physical value for numeric
// conversion rule, otherwise raw value)
setLimitMin(
MDF4Util.readReal(MDFParser.getDataBuffer(content, 40, 48)));
// REAL: Upper limit for this signal (physical value for numeric
// conversion rule, otherwise raw value)
setLimitMax(
MDF4Util.readReal(MDFParser.getDataBuffer(content, 48, 56)));
// REAL: Lower extended limit for this signal (physical value for
// numeric conversion rule, otherwise raw value)
setLimitExtMin(
MDF4Util.readReal(MDFParser.getDataBuffer(content, 56, 64)));
// REAL: Upper extended limit for this signal (physical value for
// numeric conversion rule, otherwise raw value)
setLimitExtMax(
MDF4Util.readReal(MDFParser.getDataBuffer(content, 64, 72)));
}
}