Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 171 additions & 0 deletions src/org/openlcb/EventID.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,15 @@ public EventID(@NonNull String value) {
System.arraycopy(data, 0, this.contents, 0, BYTECOUNT);
}

// note long's 64th bit is a sign
@CheckReturnValue
public EventID(long value) {
this.contents = new byte[BYTECOUNT];
for (int index = 0; index < 8; index++) {
contents[index] = (byte)((value>>(8*(7-index))) & 0xFF);
}
}

byte[] contents;

@CheckReturnValue
Expand Down Expand Up @@ -117,4 +126,166 @@ public long toLong() {
}
return ret;
}

/**
* Take the eventID from a range, and return
* the lower flag bytes as a hex dotted string.
*/
public long rangeSuffix() {
// find the mask value
long eid = this.toLong();
long sampleBit = eid & 0x01;
long mask = 0L;
while ( (eid &0x01L) == sampleBit) {
mask = (mask <<1) | 0x01;
eid = eid >> 1;
}
return mask;
}


/**
* Decode well-known and specifically defined event IDs
* @return "" if nothing interesting about the event
*/
public String parse() {
String eid = this.toShortString().substring(0, 2);
switch (eid) {
case "00":
return reserved();
case "01":
return wellKnown();
case "09":
if (this.toShortString().startsWith("09.00.99.FF")) {
return trainSearch();
}
// deliberately falling through
//$FALL-THROUGH$
default:
return "";
}
}

protected String reserved() {
return "Reserved "+this.toShortString();
}

protected String wellKnown() {
String eid = this.toShortString();
switch (eid) {
case "01.00.00.00.00.00.FF.FF":
return "Emergency off";
case "01.00.00.00.00.00.FF.FE":
return "Clear Emergency Off";
case "01.00.00.00.00.00.FF.FD":
return "Emergency stop of all operations";
case "01.00.00.00.00.00.FF.FC":
return "Clear emergency stop of all operations";
case "01.00.00.00.00.00.FF.F8":
return "Node recorded a new log entry";
case "01.00.00.00.00.00.FF.F1":
return "Power supply brownout detected below minimum required by node";
case "01.00.00.00.00.00.FF.F0":
return "Power supply brownout detected below minimum required by standard";
case "01.00.00.00.00.00.FE.00":
return "Ident button combination pressed";
case "01.00.00.00.00.00.FD.01":
return "Link error code 1 – the specific meaning is link wire protocol specific";
case "01.00.00.00.00.00.FD.02":
return "Link error code 2";
case "01.00.00.00.00.00.FD.03":
return "Link error code 3";
case "01.00.00.00.00.00.FD.04":
return "Link error code 4";

case "01.01.00.00.00.00.02.01":
return "Duplicate Node ID Detected";
case "01.01.00.00.00.00.03.03":
return "This node is a Train";
case "01.01.00.00.00.00.03.04":
return "This node is a Train Control Proxy";
case "01.01.00.00.00.00.06.01":
return "Firmware Corrupted";
case "01.01.00.00.00.00.06.02":
return "Firmware Upgrade Request by Hardware Switch";

default:
// check for fastclock and DCC ranges
if (eid.startsWith("01.01.00.00.01")) {
return fastClock();
} else if (eid.startsWith("01.01.02")) {
return dccRange();
} else {
return "Well-Known "+eid;
}
}
}

protected String fastClock() {
String clockNum = this.toShortString().substring(16, 17);
byte[] contents = this.getContents();
int lowByte = contents[7]&0xFF;
int highByte = contents[6]&0xFF;
int highByteMasked = 0x7F&highByte;
int bothBytes = highByte*256+lowByte;
String function = "";

String set = ((0x80 & highByte) == 0x80) ? "Set " : "";

if ((highByte & 0xF0) == 0xC0) { // set rate
int rate = (highByte&0xF)*256+lowByte;
function = "Set rate "+(rate/4.);
} else if (bothBytes == 0xF000) { //
function = "Query";
} else if (bothBytes == 0xF001) { //
function = "Stop";
} else if (bothBytes == 0xF002) { //
function = "Start";
} else if (bothBytes == 0xF003) { //
function = "Date Rollover";
} else if (highByteMasked < 24) { // time
String lowString = "00"+Integer.toString(lowByte);
lowString = lowString.substring(lowString.length()-2);
function = set+"time "+highByteMasked+":"+lowString;
} else if (highByteMasked <= 0x2C) { // date
String lowString = "00"+Integer.toString(lowByte);
lowString = lowString.substring(lowString.length()-2);
function = set+"date "+(highByteMasked-0x20)+"/"+lowString;
} else if (highByteMasked < 0x40) { // year
int year = (highByteMasked*256+lowByte)-0x3000;
function = set+"year "+year;
} else {
function = "reserved";
}

return "Fast Clock "+clockNum+" "+function;
}

protected String dccRange() {
String eid = this.toShortString();
if (eid.startsWith("01.01.02.00.00.FF")) {
return "DCC Basic Acc Addr Activate "+(this.toLong()&0x7FFL);
} else if (eid.startsWith("01.01.02.00.00.FE")) {
return "DCC Basic Acc Addr Deactivate "+(this.toLong()&0x7FFL);
} else if (eid.startsWith("01.01.02.00.00.FD")) {
return "DCC Turnout Feedback On "+(this.toLong()&0x7FFL);
} else if (eid.startsWith("01.01.02.00.00.FC")) {
return "DCC Turnout Feedback Off "+(this.toLong()&0x7FFL);
} else if (eid.startsWith("01.01.02.00.00.FB")) {
return "DCC Sensor On "+(this.toLong()&0xFFFL);
} else if (eid.startsWith("01.01.02.00.00.FA")) {
return "DCC Sensor Off "+(this.toLong()&0xFFFL);
} else if (eid.startsWith("01.01.02.00.01")) {
return "DCC Extended Accessory "
+((this.toLong()>>8)&0x7FFL)
+" "+(this.toLong()&0xFF);
} else {
return "DCC Well-Known "+this;
}
}

protected String trainSearch() {
return "Train Search";
}

}
2 changes: 1 addition & 1 deletion src/org/openlcb/ProducerConsumerEventReportMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public byte[] getPayloadArray() {

@Override
public String toString() {
String retval = " Producer/Consumer Event Report "+eventID.toString();
String retval = super.toString() + " Producer/Consumer Event Report "+eventID.toString();

if ( getPayloadSize() > 0 ) {
retval = retval + " payload of "+getPayloadSize()+" : ";
Expand Down
2 changes: 2 additions & 0 deletions src/util/CollapsiblePanel.java
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ public void toggleSelection() {
contentPanel_.setVisible(selected);

validate();
javax.swing.JFrame top = (javax.swing.JFrame)getTopLevelAncestor();
if (top != null) top.pack();

headerPanel_.repaint();
}
Expand Down
52 changes: 52 additions & 0 deletions test/org/openlcb/EventIDTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,56 @@ public void testToLong() {
Assert.assertEquals(-2L, new EventID(new byte[]{(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xff,
(byte)0xff,(byte)0xff,(byte)0xff,(byte)0xfe}).toLong());
}

@Test
public void testFromLong() {
EventID eid;
eid = new EventID(0x12345678);
Assert.assertEquals(0x12345678L, eid.toLong());
}

@Test
public void testBoring() {
EventID eid = new EventID("02.02.59.00.00.00.00.00");
Assert.assertEquals("", eid.parse());
}

@Test
public void testDefault() {
EventID eid = new EventID("00.00.00.00.00.00.02.00");
Assert.assertEquals("Reserved 00.00.00.00.00.00.02.00", eid.parse());
}

@Test
public void testWellKnown() {
EventID eid = new EventID("01.00.00.00.00.00.FF.FE");
Assert.assertEquals("Clear Emergency Off", eid.parse());
}

@Test
public void testFastClock() {
EventID eid = new EventID("01.01.00.00.01.01.09.02");
Assert.assertEquals("Fast Clock 1 time 9:02", eid.parse());
eid = new EventID("01.01.00.00.01.01.09.32");
Assert.assertEquals("Fast Clock 1 time 9:50", eid.parse());
eid = new EventID("01.01.00.00.01.01.89.32");
Assert.assertEquals("Fast Clock 1 Set time 9:50", eid.parse());
eid = new EventID("01.01.00.00.01.01.F0.02");
Assert.assertEquals("Fast Clock 1 Start", eid.parse());
}

@Test
public void testRangeSuffix() {
EventID eid = new EventID("00.00.00.00.00.00.FF.FF");
Assert.assertEquals(0xFFFF, eid.rangeSuffix());
eid = new EventID("00.00.00.00.00.FF.00.00");
Assert.assertEquals(0xFFFF, eid.rangeSuffix());

eid = new EventID("00.00.00.00.00.FF.80.00");
Assert.assertEquals(0x7FFF, eid.rangeSuffix());

eid = new EventID("00.00.00.00.00.00.00.03");
Assert.assertEquals(0x03, eid.rangeSuffix());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public void testPayloadToString() {
ProducerConsumerEventReportMessage m2 = new ProducerConsumerEventReportMessage(
nodeID1, eventID1, payload1 );

Assert.assertEquals(" Producer/Consumer Event Report EventID:01.00.00.00.00.00.01.00 payload of 2 : 12.34", m2.toString());
Assert.assertEquals("01.02.03.04.05.06 Producer/Consumer Event Report EventID:01.00.00.00.00.00.01.00 payload of 2 : 12.34", m2.toString());
}

@Test
Expand Down
8 changes: 8 additions & 0 deletions test/org/openlcb/cdi/swing/CdiPanelDemo.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ static public void main(String[] args) {
fname = args[0];
System.out.println("Using input file " + fname);
}

// configure a L&F
try {
// Set cross-platform Java L&F (also called "Metal")
javax.swing.UIManager.setLookAndFeel(
javax.swing.UIManager.getCrossPlatformLookAndFeelClassName());
} catch (Exception e) {};

d.displayFile(fname);
}
}
Loading