001package jmri.jmrix.marklin; 002 003/** 004 * Carries the reply to an MarklinMessage. 005 * 006 * @author Bob Jacobsen Copyright (C) 2001, 2008 007 * @author Kevin Dickerson Copyright (C) 2007 008 * 009 */ 010public class MarklinReply extends jmri.jmrix.AbstractMRReply { 011 012 // create a new one 013 public MarklinReply() { 014 super(); 015 } 016 017 public MarklinReply(String s) { 018 super(s); 019 } 020 021 public MarklinReply(MarklinReply l) { 022 super(l); 023 } 024 025 // create a new one from an array 026 public MarklinReply(int[] d) { 027 //this(header); 028 this(); 029 _nDataChars = d.length; 030 System.arraycopy(d, 0, _dataChars, 0, d.length); 031 } 032 033 //Maximum size of a reply packet is 13 bytes. 034 @Override 035 public int maxSize() { 036 return 13; 037 } 038 039 // no need to do anything 040 @Override 041 protected int skipPrefix(int index) { 042 return index; 043 } 044 045 @Override 046 public int value() { 047 if (isBinary()) { 048 return getElement(0); 049 } else { 050 return super.value(); 051 } 052 } 053 054 @Override // avoid stupid sign extension 055 public int getElement(int n) { 056 return super.getElement(n) & 0xff; 057 } 058 059 //An event message is Unsolicited 060 @Override 061 public boolean isUnsolicited() { 062 return !isResponse(); 063 } 064 065 /** 066 * {@inheritDoc} 067 */ 068 @Override 069 public String toString(){ 070 StringBuilder buf = new StringBuilder(); 071 buf.append("0x").append(Integer.toHexString(_dataChars[0])); 072 for (int i = 1; i < _nDataChars; i++) { 073 buf.append(", 0x").append(Integer.toHexString(_dataChars[i])); 074 } 075 return buf.toString(); 076 } 077 078 /** 079 * {@inheritDoc} 080 */ 081 @Override 082 public String toMonitorString(){ 083 // eventually, the MarklinMon class should probably be integrated here. 084 return jmri.jmrix.marklin.swing.monitor.MarklinMon.displayReply(this); 085 } 086 087 public boolean isResponse() { 088 return (getElement(1) & 0x01) == 0x01; 089 } 090 091 public int getCanDataLength() { 092 return getElement(4); 093 } 094 095 public int[] getCanData() { 096 int[] arr = new int[maxSize() - 5]; 097 for (int i = 5; i < maxSize(); i++) { 098 arr[i - 5] = getElement(i); 099 } 100 return arr; 101 } 102 103 public int[] getCanAddress() { 104 int[] arr = new int[4]; 105 for (int i = 5; i < 9; i++) { 106 arr[i - 5] = getElement(i); 107 } 108 return arr; 109 } 110 111 /** 112 * Get the 4-Byte Address. 113 * @return the value from CANADDRESSBYTE1 (hi) to CANADDRESSBYTE4 (low) 114 */ 115 public long getAddress() { 116 long addr = (getElement(MarklinConstants.CANADDRESSBYTE1)); 117 addr = (addr << 8) + (getElement(MarklinConstants.CANADDRESSBYTE2)); 118 addr = (addr << 8) + (getElement(MarklinConstants.CANADDRESSBYTE3)); 119 addr = (addr << 8) + (getElement(MarklinConstants.CANADDRESSBYTE4)); 120 return addr; 121 } 122 123 /** 124 * Sets the 4-byte address by splitting an integer into four bytes. 125 * @param address the 32-bit integer representing the full address 126 */ 127 public void setAddress(long address) { 128 setElement(MarklinConstants.CANADDRESSBYTE1, (byte) ((address >> 24) & 0xFF)); // hi 129 setElement(MarklinConstants.CANADDRESSBYTE2, (byte) ((address >> 16) & 0xFF)); 130 setElement(MarklinConstants.CANADDRESSBYTE3, (byte) ((address >> 8) & 0xFF)); 131 setElement(MarklinConstants.CANADDRESSBYTE4, (byte) (address & 0xFF)); // lo 132 } 133 134 public int getPriority() { 135 return (getElement(0) >> 4); 136 } 137 138 /** 139 * Get the Control Command. 140 * @return command, e.g. MarklinConstants.CMDHALTSYS 141 */ 142 public int getCommand() { 143 int result = getElement(0) << 7; 144 result = result + getElement(1) >> 1; 145 return result; 146 } 147 148 /** 149 * Set the Command value. 150 * @param command new value. 151 */ 152 public void setCommand(int command) { 153 // Update only the relevant bits in element0 (upper 7 bits) 154 int element0 = (getElement(0) & ~0x7F) | ((command >> 7) & 0x7F); 155 156 // Update only the relevant bits in element1 (lower 7 bits, shifted left) 157 int element1 = (getElement(1) & ~0xFE) | ((command & 0x7F) << 1); 158 159 // Set the updated elements 160 setElement(0, element0); 161 setElement(1, element1); 162 } 163 164 public int[] getHash() { 165 int[] arr = new int[2]; 166 arr[0] = getElement(2); 167 arr[1] = getElement(3); 168 return arr; 169 } 170}