001package jmri.jmrix.nce;
002
003
004/**
005 * Carries the reply to an NceMessage.
006 * <p>
007 * Some rudimentary support is provided for the "binary" option.
008 *
009 * @author Bob Jacobsen Copyright (C) 2001
010 * @author Daniel Boudreau Copyright (C) 2007
011 */
012public class NceReply extends jmri.jmrix.AbstractMRReply {
013
014    NceTrafficController tc;
015    private static final jmri.jmrix.nce.ncemon.NceMonBinary nceMon = new jmri.jmrix.nce.ncemon.NceMonBinary();
016
017    // create a new one
018    public NceReply(NceTrafficController tc) {
019        super();
020        this.tc = tc;
021    }
022
023    public NceReply(NceTrafficController tc, String s) {
024        super(s);
025        this.tc = tc;
026    }
027
028    public NceReply(NceTrafficController tc, NceReply l) {
029        super(l);
030        this.tc = tc;
031    }
032
033    @Override
034    protected int skipPrefix(int index) {
035        // start at index, passing any control characters at the start of the buffer
036        int len = "COMMAND: ".length();
037        if (getNumDataElements() >= index + len - 1
038                && 'C' == (char) getElement(index)
039                && 'O' == (char) getElement(index + 1)
040                && 'M' == (char) getElement(index + 2)
041                && 'M' == (char) getElement(index + 3)
042                && 'A' == (char) getElement(index + 4)
043                && 'N' == (char) getElement(index + 5)
044                && 'D' == (char) getElement(index + 6)
045                && ':' == (char) getElement(index + 7)
046                && ' ' == (char) getElement(index + 8)) {
047            index = index + "COMMAND: ".length();
048        }
049        return index;
050    }
051
052    @Override
053    public int value() {
054        if (isBinary()) {
055            return getElement(0) & 0xFF;  // avoid stupid sign extension
056        } else {
057            return super.value();
058        }
059    }
060
061    /**
062     * Extract poll values from binary reply
063     */
064    @Override
065    public int pollValue() {  // integer value of first two bytes
066        int first = 0xFF & ((byte) getElement(0));
067        int second = 0xFF & ((byte) getElement(1));
068
069        return first * 256 + second;
070    }
071
072    /**
073     * Examine message to see if it is an asynchronous sensor (AIU) state report
074     *
075     * @return true if message asynch sensor message Boudreau: Improved
076     *         detection to check three bytes and message length of exactly 3
077     *         KSC 24 Aug 2024 - seems to never match a reply
078     */
079    public boolean isSensorMessage() {
080        return getElement(0) == 0x61 && getElement(1) >= 0x30
081                && getElement(2) >= 0x41 && getElement(2) <= 0x6F
082                && getNumDataElements() == 3;
083    }
084
085    @Override
086    public boolean isUnsolicited() {
087// Boudreau: check for unsolicited AIU messages in pre 2006 EPROMs     
088        if (tc.getCommandOptions() >= NceTrafficController.OPTION_2006) {
089            return false;
090        }
091        if (isSensorMessage()) {
092            setUnsolicited();
093            return true;
094        } else {
095            return false;
096        }
097    }
098
099    /**
100     * {@inheritDoc}
101     */
102    @Override
103    public String toMonitorString() {
104        return nceMon.displayReply(this);
105    }
106
107}
108
109
110