| /********************************************************************************
|
| * 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]; |
| } |
| } |