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