001package jmri.jmrix.lenz.xntcp;
002
003import jmri.jmrix.lenz.XNetPacketizer;
004import org.slf4j.Logger;
005import org.slf4j.LoggerFactory;
006
007/**
008 * This is an extension of the XNetPacketizer to handle the device specific
009 * requirements of the XnTcp.
010 * <p>
011 * In particular, XnTcpXNetPacketizer counts the number of commands received.
012 *
013 * @author Giorgio Terdina Copyright (C) 2008-2011, based on LIUSB packetizer by
014 * Paul Bender, Copyright (C) 2005
015 *  GT - May 2011 - Removed calls to deprecated
016 * method "XnTcpAdapter.instance()"
017 *
018 */
019public class XnTcpXNetPacketizer extends XNetPacketizer {
020
021    public XnTcpXNetPacketizer(jmri.jmrix.lenz.LenzCommandStation pCommandStation) {
022        super(pCommandStation);
023        log.debug("Loading XnTcp Extension to XNetPacketizer");
024    }
025
026    /**
027     * Get characters from the input source, and fill a message.
028     * <p>
029     * Returns only when the message is complete.
030     * <p>
031     * Only used in the Receive thread.
032     *
033     * @param msg     message to fill
034     * @param istream character source.
035     * @throws java.io.IOException when presented by the input source.
036     */
037    @Override
038    protected void loadChars(jmri.jmrix.AbstractMRReply msg, java.io.DataInputStream istream) throws java.io.IOException {
039        int i, char1;
040        i = 0;
041        try {
042            // Make sure we don't overwrite output buffer
043            while (i < msg.maxSize()) {
044                // Read a byte
045                char1 = istream.read();
046                // Was the communication closed by the XpressNet/Tcp interface, or lost?
047                if (char1 < 0) {
048                    // We cannot communicate anymore!
049                    ((XnTcpAdapter) controller).xnTcpError();
050                    throw new java.io.EOFException("Lost communication with XnTcp interface");
051                }
052                // Store the byte.
053                msg.setElement(i++, (byte) char1 & 0xFF);
054                log.debug("XnTcpNetPacketizer: received {}", Integer.toHexString(char1 & 0xff));
055                // If the XpressNet packet is completed, exit the loop
056                if (endOfMessage(msg)) {
057                    break;
058                }
059            }
060            // Packet received
061            // Assume that the last packet sent was acknowledged, either by the Command Station,
062            // either by the interface itself.
063
064            ((XnTcpAdapter) controller).xnTcpSetPendingPackets(-1);
065            log.debug("XnTcpNetPacketizer: received end of packet");
066        } catch (java.io.InterruptedIOException ex) {
067        } catch (java.io.IOException ex) {
068            ((XnTcpAdapter) controller).xnTcpError();
069            throw ex;
070        }
071
072    }
073
074    private static final Logger log = LoggerFactory.getLogger(XnTcpXNetPacketizer.class);
075
076}