001package jmri.jmrix.can; 002 003import javax.annotation.Nonnull; 004import jmri.jmrix.AbstractMRReply; 005 006/** 007 * Base class for replies in a CANbus based message/reply protocol. 008 * <p> 009 * It is expected that any CAN based system will be based upon basic CANbus 010 * concepts such as ID (standard or extended), Normal and RTR frames and a data 011 * field. 012 * <p> 013 * "header" refers to the full 11 or 29 bit header; which mode is separately set 014 * via the "extended" parameter 015 * <p> 016 * CBUS uses a 2-bit "Pri" field and 7-bit "ID" ("CAN ID") field, with separate 017 * accessors. 018 * 019 * @author Andrew Crosland Copyright (C) 2008 020 * @author Bob Jacobsen Copyright (C) 2008, 2009, 2010 021 */ 022public class CanReply extends AbstractMRReply implements CanMutableFrame { 023 024 /** 025 * Create a new CanReply 026 */ 027 public CanReply() { 028 _isExtended = false; 029 _isRtr = false; 030 _nDataChars = 8; 031 super.setBinary(true); 032 _dataChars = new int[8]; 033 } 034 035 /** 036 * Create a new CanReply of given data length 037 * @param i number of data bytes, 0-8 038 */ 039 public CanReply(int i) { 040 this(); 041 setNumDataElements((i <= 8) ? i : 8); 042 } 043 044 /** 045 * Create a new CanReply from an int array 046 * @param d array of CAN Frame data bytes, max 8 047 */ 048 public CanReply(int[] d) { 049 this(); 050 setData(d); 051 setNumDataElements((d.length <= 8) ? d.length : 8); 052 } 053 054 /** 055 * Create a new CanReply from an int array, with header 056 * @param d array of CAN Frame data bytes, max 8 057 * @param header the Frame header value 058 */ 059 public CanReply(int[] d, int header) { 060 this(); 061 setHeader(header); 062 setData(d); 063 setNumDataElements((d.length <= 8) ? d.length : 8); 064 } 065 066 /** 067 * Create a new CanReply from an existing CanReply 068 * @param m The existing CanReply 069 */ 070 public CanReply(@Nonnull CanReply m) { 071 this(); 072 _header = m.getHeader(); 073 _isExtended = m.isExtended(); 074 _isRtr = m.isRtr(); 075 super.setBinary(true); 076 setData(m.getData()); 077 setNumDataElements(m.getNumDataElements()); 078 } 079 080 /** 081 * Create a new CanReply from an existing CanMessage 082 * @param m The existing CanMessage 083 */ 084 public CanReply(@Nonnull CanMessage m) { 085 this(); 086 _header = m.getHeader(); 087 _isExtended = m.isExtended(); 088 _isRtr = m.isRtr(); 089 super.setBinary(true); 090 setData(java.util.Arrays.copyOf(m.getData(),m.getNumDataElements())); 091 setNumDataElements(m.getNumDataElements()); 092 } 093 094 /** 095 * Hash on the header 096 */ 097 @Override 098 public int hashCode() { 099 return _header; 100 } 101 102 /** 103 * Note that a CanMessage and a CanReply can be tested for equality 104 */ 105 @Override 106 @edu.umd.cs.findbugs.annotations.SuppressFBWarnings(value = "EQ_UNUSUAL", 107 justification = "Equality test done in CanFrame") 108 public boolean equals(Object a) { 109 return isEqual(a,this); 110 } 111 112 /** 113 * {@inheritDoc} 114 */ 115 @Override 116 protected int skipPrefix(int index) { 117 return index; 118 } 119 120 /** 121 * {@inheritDoc} 122 */ 123 @Override 124 public int getNumDataElements() { 125 return _nDataChars; 126 } 127 128 /** 129 * {@inheritDoc} 130 */ 131 @Override 132 public final void setNumDataElements(int n) { 133 _nDataChars = (n <= 8) ? n : 8; 134 } 135 136 /** 137 * {@inheritDoc} 138 */ 139 @Override 140 public int getElement(int n) { 141 return _dataChars[n]; 142 } 143 144 /** 145 * {@inheritDoc} 146 */ 147 @Override 148 public void setElement(int n, int v) { 149 _dataChars[n] = v; 150 } 151 152 /** 153 * Get the data byte array. 154 * @return the actual byte array, not a Copy Of 155 */ 156 public int[] getData() { 157 return _dataChars; 158 } 159 160 /** 161 * {@inheritDoc} 162 */ 163 @Override 164 public int getHeader() { 165 return _header; 166 } 167 168 /** 169 * {@inheritDoc} 170 */ 171 @Override 172 public final void setHeader(int h) { 173 _header = h; 174 } 175 176 /** 177 * {@inheritDoc} 178 */ 179 @Override 180 public boolean isExtended() { 181 return _isExtended; 182 } 183 184 /** 185 * {@inheritDoc} 186 */ 187 @Override 188 public void setExtended(boolean b) { 189 _isExtended = b; 190 } 191 192 /** 193 * {@inheritDoc} 194 */ 195 @Override 196 public boolean isRtr() { 197 return _isRtr; 198 } 199 200 /** 201 * {@inheritDoc} 202 */ 203 @Override 204 public void setRtr(boolean b) { 205 _isRtr = b; 206 } 207 208 /** 209 * {@inheritDoc} 210 * this format matches @CanMessage 211 */ 212 @Override 213 public String toString() { 214 return getToString(); 215 } 216 217 /** 218 * {@inheritDoc} 219 * this format matches @CanMessage 220 */ 221 @Override 222 public String toMonitorString() { 223 return monString(); 224 } 225 226 // contents (package access) 227 int _header; 228 boolean _isExtended; 229 boolean _isRtr; 230}