001package jmri.jmrix.lenz.liusb;
002
003import jmri.jmrix.lenz.XNetPacketizer;
004import org.slf4j.Logger;
005import org.slf4j.LoggerFactory;
006
007/**
008 * This is an extention of the XNetPacketizer to handle the device specific
009 * requirements of the LIUSB.
010 * <p>
011 * In particular, LIUSBXNetPacketizer adds functions to add and remove the 0xFF
012 * 0xFE or 0xFF 0xFD bytes that appear prior to any message read in.
013 *
014 * @author Paul Bender Copyright (C) 2005
015 *
016 */
017public class LIUSBXNetPacketizer extends XNetPacketizer {
018
019    public LIUSBXNetPacketizer(jmri.jmrix.lenz.LenzCommandStation pCommandStation) {
020        super(pCommandStation);
021        log.debug("Loading LIUSB Extention to XNetPacketizer");
022    }
023
024    /**
025     * {@inheritDoc}
026     */
027    @Override
028    protected int addHeaderToOutput(byte[] msg, jmri.jmrix.AbstractMRMessage m) {
029        log.debug("Appending 0xFF 0xFE to start of outgoing message");
030        msg[0] = (byte) 0xFF;
031        msg[1] = (byte) 0xFE;
032        return 2;
033    }
034
035    /**
036     * {@inheritDoc}
037     */
038    @Override
039    protected int lengthOfByteStream(jmri.jmrix.AbstractMRMessage m) {
040        return m.getNumDataElements() + 2;
041    }
042
043    /**
044     * Get characters from the input source, and file a message.
045     * <p>
046     * Returns only when the message is complete.
047     * <p>
048     * Only used in the Receive thread.
049     *
050     * @param msg     message to fill
051     * @param istream character source.
052     * @throws java.io.IOException when presented by the input source.
053     */
054    @Override
055    protected void loadChars(jmri.jmrix.AbstractMRReply msg, java.io.DataInputStream istream) throws java.io.IOException {
056        int i;
057        byte lastbyte = (byte) 0xFF;
058        log.debug("loading characters from port");
059        for (i = 0; i < msg.maxSize(); i++) {
060            byte char1 = readByteProtected(istream);
061            // This is a test for the LIUSB device
062            while ((i == 0) && ((char1 & 0xF0) == 0xF0)) {
063                if ((char1 & 0xFF) != 0xF0 && (char1 & 0xFF) != 0xF2) {
064                    // save this so we can check for unsolicited
065                    // messages.
066                    lastbyte = char1;
067                    //  toss this byte and read the next one
068                    char1 = readByteProtected(istream);
069                }
070
071            }
072            // LIUSB messages are preceeded by 0xFF 0xFE if they are
073            // responses to messages we sent.  If they are unrequested
074            // information, they are preceeded by 0xFF 0xFD.
075            if (lastbyte == (byte) 0xFD) {
076                msg.setUnsolicited();
077            }
078            msg.setElement(i, char1 & 0xFF);
079            if (endOfMessage(msg)) {
080                break;
081            }
082        }
083    }
084
085    private static final Logger log = LoggerFactory.getLogger(LIUSBXNetPacketizer.class);
086
087}