001package jmri.jmrix.tmcc;
002
003import jmri.util.StringUtil;
004
005/**
006 * Contains the data payload of a TMCC serial packet.
007 * <p>
008 * Note that <i>only</i> the payload, not the header or trailer, nor the padding
009 * DLE characters are included. These are added during transmission.
010 *
011 * @author Bob Jacobsen Copyright (C) 2001,2003, 2006
012 */
013public class SerialMessage extends jmri.jmrix.AbstractMRMessage {
014    // is this logically an abstract class?
015
016    public SerialMessage() {
017        super(3);
018        setOpCode(0xFE);
019        setTimeout(100);
020    }
021
022    // copy one
023    public SerialMessage(SerialMessage m) {
024        super(m);
025        setTimeout(100);
026    }
027
028    /**
029     * This ctor interprets the String as the exact sequence to send,
030     * byte-for-byte.
031     *
032     * @param m string form of bytes to send
033     *
034     */
035    public SerialMessage(String m) {
036        super(m);
037        setTimeout(100);
038    }
039
040    /**
041     * This ctor interprets the byte array as a sequence of characters to send.
042     * @deprecated 5.13.5, unused, requires further development.
043     * @param a Array of bytes to send
044     */
045    @Deprecated( since="5.13.5", forRemoval=true)
046    public SerialMessage(byte[] a) {
047        // super(String.valueOf(a)); // Spotbug toString on array
048        // requires further development to produce correct values for hardware type.
049        super(StringUtil.hexStringFromBytes(a).replaceAll("\\s", ""));
050        setTimeout(100);
051    }
052
053    /**
054     * This ctor takes an int value for the 16 bit data content, with an
055     * optional leading byte.  If the value is greater than 0xFFFF,
056     * i.e. the upper byte of three is non-zero, the upper byte is
057     * used as the op code, otherwise 0xFE (TMCC 1) will be used.
058     *
059     * @param value The value stored in the content of the packet
060     */
061    public SerialMessage(int value) {
062        super(3);
063        if ( (value & 0xFF0000) != 0) {
064            setOpCode((value >> 16 ) & 0xFF);
065        } else {
066            setOpCode(0xFE);
067        }
068        putAsWord(value);
069        setTimeout(100);
070    }
071
072    @Override
073    public String toString() {
074        StringBuilder s = new StringBuilder("");
075        for (int i = 0; i < getNumDataElements(); i++) {
076            if (i != 0) {
077                s.append(" ");
078            }
079            s.append(StringUtil.twoHexFromInt(getElement(i)));
080        }
081        return s.toString();
082    }
083
084    public void putAsWord(int val) {
085        setElement(1, (val / 256) & 0xFF);
086        setElement(2, val & 0xFF);
087    }
088
089    public int getAsWord() {
090        return (getElement(1) & 0xFF) * 256 + (getElement(2) & 0xFF);
091    }
092}