blob: 252a8b447d13447c203fa70ac2feb9167846cb93 [file] [log] [blame]
/********************************************************************************
* Copyright (c) 2015-2018 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
package org.eclipse.mdm.openatfx.mdf.mdf4;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.SeekableByteChannel;
/**
* <p>
* THE SOURCE INFORMATION BLOCK <code>SIBLOCK<code>
* </p>
* The SIBLOCK describes the source of an acquisition mode or of a signal. The
* source information is also used to ensure a unique identification of a
* channel.
*
* @author Christian Rechner
*/
class SIBLOCK extends BLOCK {
public static String BLOCK_ID = "##SI";
/** Link section */
// Pointer to TXBLOCK with name (identification) of source (can be NIL).
// LINK
private long lnkTxName;
// Pointer to TXBLOCK with (tool-specific) path of source (can be NIL).
// LINK
private long lnkTxPath;
// Pointer to source comment and additional information (TXBLOCK or MDBLOCK)
// (can be NIL)
// LINK
private long lnkMdComment;
/** Data section */
// Source type: additional classification of source:
// 0 = OTHER source type does not fit into given categories or is unknown
// 1 = ECU source is an ECU
// 2 = BUS source is a bus (e.g. for bus monitoring)
// 3 = I/O source is an I/O device (e.g. analog I/O)
// 4 = TOOL source is a software tool (e.g. for tool generated
// signals/events)
// 5 = USER source is a user interaction/input
// (e.g. for user generated events)
// UINT8
private byte sourceType;
private String[] sourceTypes = { "OTHER", "ECU", "CAN", "BUS", "I/O", "TOOL", "USER" };
// Bus type: additional classification of used bus (should be 0 for si_type
// ≥ 3):
// 0 = NONE no bus
// 1 = OTHER bus type does not fit into given categories or is unknown
// 2 = CAN
// 3 = LIN
// 4 = MOST
// 5 = FLEXRAY
// 6 = K_LINE
// 7 = ETHERNET
// 8 = USB
// Vender defined bus types can be added starting with value 128.
// UINT8
private byte busType;
private String[] busTypes = { "NONE", "OTHER", "CAN", "LIN", "MOST", "FLEXRAY", "K_LINE", "ETHERNET", "USB" };
// Flags
// The value contains the following bit flags (Bit 0 = LSB):
// Bit 0: simulated source
// Source is only a simulation (can be hardware or software simulated)
// Cannot be set for si_type = 4 (TOOL).
// UINT8
private byte flags;
/**
* Constructor.
*
* @param sbc
* The byte channel pointing to the MDF file.
* @param pos
* The position of the block within the MDF file.
*/
private SIBLOCK(SeekableByteChannel sbc, long pos) {
super(sbc, pos);
}
private void setLnkTxName(long lnkTxName) {
this.lnkTxName = lnkTxName;
}
private void setLnkTxPath(long lnkTxPath) {
this.lnkTxPath = lnkTxPath;
}
private void setLnkMdComment(long lnkMdComment) {
this.lnkMdComment = lnkMdComment;
}
private void setSourceType(byte sourceType) {
this.sourceType = sourceType;
}
private void setBusType(byte busType) {
this.busType = busType;
}
private void setFlags(byte flags) {
this.flags = flags;
}
public long getLnkTxName() {
return lnkTxName;
}
public long getLnkTxPath() {
return lnkTxPath;
}
public long getLnkMdComment() {
return lnkMdComment;
}
public byte getSourceType() {
return sourceType;
}
public byte getBusType() {
return busType;
}
public byte getFlags() {
return flags;
}
public TXBLOCK getTxNameBlock() throws IOException {
if (lnkTxName > 0) {
return TXBLOCK.read(sbc, lnkTxName);
}
return null;
}
public TXBLOCK getTxPathBlock() throws IOException {
if (lnkTxPath > 0) {
return TXBLOCK.read(sbc, lnkTxPath);
}
return null;
}
public BLOCK getMdCommentBlock() throws IOException {
if (lnkMdComment > 0) {
String blockType = getBlockType(sbc, lnkMdComment);
// link points to a MDBLOCK
if (blockType.equals(MDBLOCK.BLOCK_ID)) {
return MDBLOCK.read(sbc, lnkMdComment);
}
// links points to TXBLOCK
else if (blockType.equals(TXBLOCK.BLOCK_ID)) {
return TXBLOCK.read(sbc, lnkMdComment);
}
// unknown
else {
throw new IOException("Unsupported block type for MdComment: " + blockType);
}
}
return null;
}
@Override
public String toString() {
return "SIBLOCK [lnkTxName=" + lnkTxName + ", lnkTxPath=" + lnkTxPath + ", lnkMdComment=" + lnkMdComment
+ ", sourceType=" + sourceType + ", busType=" + busType + ", flags=" + flags + "]";
}
/**
* Reads a SIBLOCK from the channel starting at current channel position.
*
* @param channel
* The channel to read from.
* @param pos
* The position within the channel.
* @return The block data.
* @throws IOException
* The exception.
*/
public static SIBLOCK read(SeekableByteChannel channel, long pos) throws IOException {
SIBLOCK block = new SIBLOCK(channel, pos);
// read block header
ByteBuffer bb = ByteBuffer.allocate(56);
bb.order(ByteOrder.LITTLE_ENDIAN);
channel.position(pos);
channel.read(bb);
bb.rewind();
// CHAR 4: Block type identifier
block.setId(MDF4Util.readCharsISO8859(bb, 4));
if (!block.getId().equals(BLOCK_ID)) {
throw new IOException("Wrong block type - expected '" + BLOCK_ID + "', found '" + block.getId() + "'");
}
// BYTE 4: Reserved used for 8-Byte alignment
bb.get(new byte[4]);
// UINT64: Length of block
block.setLength(MDF4Util.readUInt64(bb));
// UINT64: Number of links
block.setLinkCount(MDF4Util.readUInt64(bb));
// LINK: Pointer to TXBLOCK with name (identification) of source (can be
// NIL).
block.setLnkTxName(MDF4Util.readLink(bb));
// LINK: Pointer to TXBLOCK with (tool-specific) path of source (can be
// NIL).
block.setLnkTxPath(MDF4Util.readLink(bb));
// LINK: Pointer to source comment and additional information (TXBLOCK
// or MDBLOCK) (can be NIL).
block.setLnkMdComment(MDF4Util.readLink(bb));
// UINT8: Source type: additional classification of source:
block.setSourceType(MDF4Util.readUInt8(bb));
// UINT8: Bus type: additional classification of used bus (should be 0
// for si_type ≥ 3):
block.setBusType(MDF4Util.readUInt8(bb));
// UINT8: Flags
block.setFlags(MDF4Util.readUInt8(bb));
return block;
}
public String getSrcTypeString() {
if (sourceType < 0 || sourceType > 5) {
throw new IllegalArgumentException("Invalid source type.");
}
return sourceTypes[sourceType];
}
public String getBusTypeString() {
if (busType < 0 || busType > 8) {
return "OTHER";
}
return busTypes[busType];
}
}