001package jmri.jmrix.ieee802154;
002
003/**
004 * Contains the data payload of an IEEE 802.15.4 packet.
005 *
006 * @author Bob Jacobsen Copyright (C) 2001,2003, 2006, 2007, 2008 Converted to
007 * multiple connection
008 * @author kcameron Copyright (C) 2011 Modified for IEEE 802.15.4 connection
009 * @author Paul Bender Copyright (C) 2013
010 */
011public class IEEE802154Message extends jmri.jmrix.AbstractMRMessage {
012
013    /**
014     * Suppress the default ctor, as the length must always be specified
015     */
016    protected IEEE802154Message() {
017    }
018
019    public IEEE802154Message(int l) {
020        super(l);
021        setResponseLength(0);  // only polls require a response
022        setBinary(true);
023        setTimeout(5000);
024    }
025
026    /**
027     * This ctor interprets the String as the exact sequence to send,
028     * byte-for-byte.
029     * @param m msg to send
030     * @param l length of expected response (not used)
031     *
032     */
033    public IEEE802154Message(String m, int l) {
034        super(m);
035        //setResponseLength(l);
036        setBinary(true);
037        setTimeout(5000);
038        // gather bytes in result
039        byte b[] = jmri.util.StringUtil.bytesFromHexString(m);
040        if (b.length == 0) {
041            // no such thing as a zero-length message
042            _nDataChars = 0;
043            _dataChars = null;
044            return;
045        }
046        _nDataChars = b.length;
047        _dataChars = new int[_nDataChars];
048        for (int i = 0; i < b.length; i++) {
049            setElement(i, b[i]);
050        }
051    }
052
053    /**
054     * This ctor interprets the byte array as a sequence of characters to send.
055     *
056     * @param a Array of bytes to send
057     * @param l length of expected response
058     */
059    public IEEE802154Message(byte[] a, int l) {
060        super(String.valueOf(a));
061        setResponseLength(l);
062        setBinary(true);
063        setTimeout(5000);
064    }
065
066    /**
067     * Check whether the message has a valid parity IEEE 802.15.4 messages have
068     * a two byte parity.
069     * @return true if parity is valid
070     */
071    public boolean checkParity() {
072        int len = getNumDataElements();
073        int chksum = 0x0000;  /* the seed */
074
075        int loop;
076
077        for (loop = 0; loop < len - 1; loop = loop + 2) {  // calculate contents for data part
078            chksum ^= (getElement(loop) << 8);
079            chksum ^= getElement(loop + 1);
080        }
081        return ((chksum & 0xFFFF) == ((getElement(len - 2) << 8) + getElement(len - 1)));
082    }
083
084    public void setParity() {
085        int len = getNumDataElements();
086        int chksum = 0x00;  /* the seed */
087
088        int loop;
089
090        for (loop = 0; loop < len - 1; loop++) {  // calculate contents for data part
091            chksum ^= (getElement(loop) << 8);
092            chksum ^= getElement(loop + 1);
093        }
094        setElement(len - 1, chksum & 0xFF);
095        setElement(len - 2, ((chksum & 0xFF00) >> 8));
096    }
097
098    int responseLength = -1;  // -1 is an invalid value, indicating it hasn't been set
099
100    public void setResponseLength(int l) {
101        responseLength = l;
102    }
103
104    public int getResponseLength() {
105        return responseLength;
106    }
107
108}
109