001package jmri.jmrix.maple; 002 003import jmri.util.StringUtil; 004import org.slf4j.Logger; 005import org.slf4j.LoggerFactory; 006 007/** 008 * Contains the data payload of a serial packet. 009 * <p> 010 * Note that <i>only</i> the payload, not the header or trailer, nor the padding 011 * DLE characters are included. These are added during transmission. 012 * 013 * @author Bob Jacobsen Copyright (C) 2001,2003 014 */ 015public class SerialMessage extends jmri.jmrix.AbstractMRMessage { 016 // is this logically an abstract class? 017 018 public SerialMessage() { 019 super(); 020 } 021 022 // create a new one 023 public SerialMessage(int i) { 024 super(i); 025 } 026 027 // copy one 028 public SerialMessage(SerialMessage m) { 029 super(m); 030 } 031 032 /** 033 * This ctor interprets the String as the exact sequence to send, 034 * byte-for-byte. 035 * @param m message string. 036 */ 037 public SerialMessage(String m) { 038 super(m); 039 } 040 041 /** 042 * This ctor interprets the byte array as a sequence of characters to send. 043 * @deprecated 5.13.5, unused, requires further development. 044 * @param a Array of bytes to send 045 */ 046 @Deprecated( since="5.13.5", forRemoval=true) 047 public SerialMessage(byte[] a) { 048 // super(String.valueOf(a)); // Spotbug toString on array 049 // requires further development to produce correct values for hardware type. 050 super(StringUtil.hexStringFromBytes(a).replaceAll("\\s", "")); 051 } 052 053 @Override 054 public String toString() { 055 StringBuilder s = new StringBuilder(""); 056 for (int i = 0; i < getNumDataElements(); i++) { 057 if (i != 0) { 058 s.append(" "); 059 } 060 s.append(StringUtil.twoHexFromInt(getElement(i))); 061 } 062 return s.toString(); 063 } 064 065 // control when reply is expected 066 private boolean _replyExpected = true; 067 068 protected void setNoReply() { 069 _replyExpected = false; 070 } 071 072 @Override 073 public boolean replyExpected() { 074 return _replyExpected; 075 } 076 077 // static methods to recognize a message 078 public boolean isPoll() { 079 return getElement(3) == 'R' && getElement(4) == 'C'; 080 } 081 082 public boolean isXmt() { 083 return getElement(3) == 'W' && getElement(4) == 'C'; 084 } 085 086 public boolean isInit() { 087 return (false); 088 } // initialization is not used in Maple 089 090 public int getUA() { 091 return ((getElement(1) - '0') * 10) + (getElement(2) - '0'); 092 } 093 094 public int getAddress() { 095 return (((getElement(5) - '0') * 1000) + ((getElement(6) - '0') * 100) + ((getElement(7) - '0') * 10) + (getElement(8) - '0')); 096 } 097 098 public int getNumItems() { 099 return ((getElement(9) - '0') * 10) + (getElement(10) - '0'); 100 } 101 102 // static methods to return a formatted message 103 104 static public SerialMessage getPoll(int UA, int startAdd, int count) { 105 if ((count <= 0) || (count > 99)) { 106 log.error("Illegal count in Maple poll message - {}", count); 107 return null; 108 } 109 SerialMessage m = new SerialMessage(14); 110 m.setElement(0, 02); 111 m.setElement(1, '0' + (UA / 10)); 112 m.setElement(2, '0' + (UA - ((UA / 10) * 10))); 113 m.setElement(3, 'R'); 114 m.setElement(4, 'C'); 115 m.setElement(5, '0' + (startAdd / 1000)); // read starting at 0001 116 m.setElement(6, '0' + ((startAdd - ((startAdd / 1000) * 1000)) / 100)); 117 m.setElement(7, '0' + ((startAdd - ((startAdd / 100) * 100)) / 10)); 118 m.setElement(8, '0' + (startAdd - ((startAdd / 10) * 10))); 119 m.setElement(9, '0' + (count / 10)); 120 m.setElement(10, '0' + (count - ((count / 10) * 10))); 121 m.setElement(11, 03); 122 123 m.setChecksum(12); 124 125 m.setTimeout(InputBits.getTimeoutTime()); 126 return m; 127 } 128 129 void setChecksum(int index) { 130 int sum = 0; 131 for (int i = 1; i < index; i++) { 132 sum += getElement(i); 133 } 134 sum = sum & 0xFF; 135 136 char firstChar; 137 int firstVal = (sum / 16) & 0xF; 138 if (firstVal > 9) { 139 firstChar = (char) ('A' - 10 + firstVal); 140 } else { 141 firstChar = (char) ('0' + firstVal); 142 } 143 setElement(index, firstChar); 144 145 char secondChar; 146 int secondVal = sum & 0xf; 147 if (secondVal > 9) { 148 secondChar = (char) ('A' - 10 + secondVal); 149 } else { 150 secondChar = (char) ('0' + secondVal); 151 } 152 setElement(index + 1, secondChar); 153 } 154 155// public int maxSize() { 156// return DEFAULTMAXSIZE; 157// } 158// static public final int DEFAULTMAXSIZE = 404; // Maple RR Request Docs page 9 159 160 private final static Logger log = LoggerFactory.getLogger(SerialMessage.class); 161 162}