001package jmri.jmrix.oaktree;
002
003/**
004 * Contains the data payload of a serial packet.
005 * <p>
006 * Note that <i>only</i> the payload, not the header or trailer, nor the padding
007 * DLE characters are included. These are added during transmission.
008 *
009 * @author Bob Jacobsen Copyright (C) 2001,2003, 2006
010 */
011public class SerialMessage extends jmri.jmrix.AbstractMRMessage {
012    // is this logically an abstract class?
013
014    /**
015     * Suppress the default ctor, as the response length must always be
016     * specified.
017     */
018    @SuppressWarnings("unused")
019    private SerialMessage() {
020    }
021
022    public SerialMessage(int l) {
023        super(5);  // all OakTree messages are five bytes
024        setResponseLength(l);
025        setBinary(true);
026    }
027
028    // copy one
029    public SerialMessage(SerialMessage m, int l) {
030        super(m);
031        setResponseLength(l);
032        setBinary(true);
033    }
034
035    /**
036     * Interpret the String as the exact sequence to send,
037     * byte-for-byte.
038     * @param m message string.
039     * @param l response length.
040     */
041    public SerialMessage(String m, int l) {
042        super(m);
043        setResponseLength(l);
044        setBinary(true);
045    }
046
047    /**
048     * Interpret the byte array as a sequence of characters to send.
049     *
050     * @param a Array of bytes to send
051     * @param l response length.
052     */
053    public SerialMessage(byte[] a, int l) {
054        super(String.valueOf(a));
055        setResponseLength(l);
056        setBinary(true);
057    }
058
059    int responseLength = -1;  // -1 is an invalid value, indicating it hasn't been set
060
061    public void setResponseLength(int l) {
062        responseLength = l;
063    }
064
065    public int getResponseLength() {
066        return responseLength;
067    }
068
069    /**
070     * Override parent method to ensure that message always has valid error
071     * check byte.
072     */
073    @Override
074    public void setElement(int element, int value) {
075        super.setElement(element, value);
076        int ecb = getElement(0) ^ getElement(1) ^ getElement(2) ^ getElement(3);
077        super.setElement(4, ecb);
078    }
079
080    // static methods to recognize a message
081    public boolean isPoll() {
082        return getElement(1) == 48;
083    }
084
085    public boolean isXmt() {
086        return getElement(1) == 17;
087    }
088
089    public int getAddr() {
090        return getElement(0);
091    }
092
093    // static methods to return a formatted message
094    static public SerialMessage getPoll(int addr) {
095        // eventually this will have to include logic for reading 
096        // various bytes on the card, but our supported 
097        // cards don't require that yet
098        SerialMessage m = new SerialMessage(5);
099        m.setElement(0, addr);
100        m.setElement(1, 48);  // read processed data
101        m.setElement(2, 0);  // read first two bytes
102        m.setElement(3, 0);
103        m.setTimeout(SHORT_TIMEOUT);    // minumum reasonable timeout
104        return m;
105    }
106
107}