001package jmri.jmrix.dcc4pc; 002 003import org.slf4j.Logger; 004import org.slf4j.LoggerFactory; 005 006/** 007 * Encodes a message to the DCC4PC Interface. 008 * <p> 009 * The {@link Dcc4PcReply} class handles the response from the command station. 010 * 011 * @author Bob Jacobsen Copyright (C) 2001 012 * @author Kevin Dickerson Copyright (C) 2012 013 * 014 */ 015public class Dcc4PcMessage extends jmri.jmrix.AbstractMRMessage { 016 017 public static final int MAXSIZE = 515; 018 019 // create a new one 020 public Dcc4PcMessage(int i) { 021 if (i < 1) { 022 log.error("invalid length in call to ctor"); 023 } 024 _nDataChars = i; 025 _dataChars = new int[i]; 026 setBinary(true); 027 setRetries(3); 028 } 029 030 /** 031 * Creates a new Dcc4PcMessage containing a byte array to represent a packet 032 * to output 033 * 034 * @param packet The contents of the packet 035 */ 036 public Dcc4PcMessage(byte[] packet) { 037 this((packet.length)); 038 int i = 0; // counter of byte in output message 039 int j; // counter of byte in input packet 040 setBinary(true); 041 // add each byte of the input message 042 for (j = 0; j < packet.length; j++) { 043 this.setElement(i, packet[i]); 044 i++; 045 } 046 setRetries(1); 047 } 048 049 // from String 050 public Dcc4PcMessage(String s) { 051 _nDataChars = s.length(); 052 _dataChars = new int[_nDataChars]; 053 for (int i = 0; i < _nDataChars; i++) { 054 _dataChars[i] = s.charAt(i); 055 } 056 setBinary(true); 057 setRetries(3); 058 } 059 060 // copy one 061 public Dcc4PcMessage(Dcc4PcMessage m) { 062 if (m == null) { 063 log.error("copy ctor of null message"); 064 return; 065 } 066 _nDataChars = m._nDataChars; 067 _dataChars = new int[_nDataChars]; 068 for (int i = 0; i < _nDataChars; i++) { 069 _dataChars[i] = m._dataChars[i]; 070 } 071 setBinary(true); 072 setRetries(1); 073 } 074 075 public void setForChildBoard(boolean boo) { 076 childBoard = boo; 077 } 078 079 boolean childBoard = false; 080 081 public boolean isForChildBoard() { 082 return childBoard; 083 } 084 085 /** {@inheritDoc} */ 086 @Override 087 public void setElement(int n, int v) { 088 _dataChars[n] = v; 089 } 090 091 /** {@inheritDoc} */ 092 @Override 093 public String toString() { 094 StringBuilder buf = new StringBuilder(); 095 buf.append("0x"); 096 buf.append(Integer.toHexString(0xFF & _dataChars[0])); 097 for (int i = 1; i < _nDataChars; i++) { 098 buf.append(".0x"); 099 buf.append(Integer.toHexString(0xff & _dataChars[i])); 100 //buf.append(", 0x" + Integer.toHexString(0xFF & _dataChars[i])); 101 } 102 return buf.toString(); 103 } 104 105 /** 106 * Get formatted message for direct output to stream - this is the final 107 * format of the message as a byte array 108 * 109 * @return the formatted message as a byte array 110 */ 111 public byte[] getFormattedMessage() { 112 int len = this.getNumDataElements(); 113 // space for carriage return if required 114 int cr = 0; 115 116 byte msg[] = new byte[len + cr]; 117 118 for (int i = 0; i < len; i++) { 119 msg[i] = (byte) this.getElement(i); 120 } 121 return msg; 122 } 123 124 //Not supported 125 static public Dcc4PcMessage getProgMode() { 126 Dcc4PcMessage m = new Dcc4PcMessage(1); 127 //m.setOpCode('+'); 128 return m; 129 } 130 131 //Not supported 132 static public Dcc4PcMessage getExitProgMode() { 133 Dcc4PcMessage m = new Dcc4PcMessage(1); 134 // m.setOpCode(' '); 135 return m; 136 } 137 138 boolean isResponse = false; 139 140 public boolean isGetResponse() { 141 return isResponse; 142 } 143 144 int board = -1; 145 146 public int getBoard(){ 147 return board; 148 } 149 150 int messageType = -1; 151 public int getMessageType(){ 152 return messageType; 153 } 154 155 static final int INFO = 0x00; 156 static final int DESC = 0x01; 157 static final int SERIAL = 0x02; 158 static final int CHILDENABLEDINPUTS = 0x07; 159 static final int CHILDRESET = 0x09; 160 static final int CHILDPOLL = 0x0a; 161 static final int RESPONSE = 0x0c; 162 163 static public Dcc4PcMessage getInfo(int address) { 164 Dcc4PcMessage m = new Dcc4PcMessage(new byte[]{(byte) 0x0b, (byte) address, (byte) INFO}); 165 m.childBoard = true; 166 m.board = address; 167 m.messageType = INFO; 168 m.setRetries(2); 169 return m; 170 } 171 172 static public Dcc4PcMessage getDescription(int address) { 173 Dcc4PcMessage m = new Dcc4PcMessage(new byte[]{(byte) 0x0b, (byte) address, (byte) DESC}); 174 m.childBoard = true; 175 m.board = address; 176 m.messageType = DESC; 177 return m; 178 } 179 180 static public Dcc4PcMessage getSerialNumber(int address) { 181 Dcc4PcMessage m = new Dcc4PcMessage(new byte[]{(byte) 0x0b, (byte) address, (byte) SERIAL}); 182 m.childBoard = true; 183 m.board = address; 184 m.messageType = SERIAL; 185 return m; 186 } 187 188 static public Dcc4PcMessage resetBoardData(int address) { 189 Dcc4PcMessage m = new Dcc4PcMessage(new byte[]{(byte) 0x0b, (byte) address, (byte) CHILDRESET}); 190 m.childBoard = true; 191 m.board = address; 192 m.messageType = CHILDRESET; 193 return m; 194 } 195 196 static public Dcc4PcMessage pollBoard(int address){ 197 Dcc4PcMessage m = new Dcc4PcMessage(new byte[]{(byte) 0x0b, (byte) address, (byte) CHILDPOLL}); 198 m.childBoard = true; 199 m.setTimeout(500); 200 m.board = address; 201 m.messageType = CHILDPOLL; 202 return m; 203 } 204 205 static public Dcc4PcMessage getEnabledInputs(int address) { 206 Dcc4PcMessage m = new Dcc4PcMessage(new byte[]{(byte) 0x0b, (byte) address, (byte) CHILDENABLEDINPUTS}); 207 m.childBoard = true; 208 m.board = address; 209 m.messageType = CHILDENABLEDINPUTS; 210 return m; 211 } 212 213 static public Dcc4PcMessage getInfo() { 214 Dcc4PcMessage m = new Dcc4PcMessage(new byte[]{(byte) INFO}); 215 m.messageType = INFO; 216 return m; 217 } 218 219 static public Dcc4PcMessage getResponse() { 220 Dcc4PcMessage m = new Dcc4PcMessage(new byte[]{(byte) RESPONSE}); 221 m.isResponse = true; 222 m.messageType = RESPONSE; 223 return m; 224 } 225 226 static public Dcc4PcMessage getDescription() { 227 Dcc4PcMessage m = new Dcc4PcMessage(new byte[]{(byte) DESC}); 228 m.messageType = DESC; 229 return m; 230 } 231 232 static public Dcc4PcMessage getSerialNumber() { 233 Dcc4PcMessage m = new Dcc4PcMessage(new byte[]{(byte) SERIAL}); 234 m.messageType = SERIAL; 235 return m; 236 } 237 238 private final static Logger log = LoggerFactory.getLogger(Dcc4PcMessage.class); 239}