You can subscribe to this list here.
| 2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(158) |
Dec
(8) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2010 |
Jan
(18) |
Feb
|
Mar
|
Apr
|
May
(122) |
Jun
(464) |
Jul
(514) |
Aug
(103) |
Sep
(121) |
Oct
(96) |
Nov
(9) |
Dec
(6) |
| 2011 |
Jan
(8) |
Feb
(14) |
Mar
(93) |
Apr
(14) |
May
(46) |
Jun
(89) |
Jul
(133) |
Aug
(48) |
Sep
(39) |
Oct
(4) |
Nov
(2) |
Dec
(34) |
| 2012 |
Jan
(102) |
Feb
(237) |
Mar
(130) |
Apr
(98) |
May
(197) |
Jun
(98) |
Jul
(99) |
Aug
(105) |
Sep
(106) |
Oct
(31) |
Nov
(33) |
Dec
(35) |
| 2013 |
Jan
(91) |
Feb
(70) |
Mar
(85) |
Apr
(82) |
May
(27) |
Jun
(7) |
Jul
(35) |
Aug
(15) |
Sep
(11) |
Oct
(38) |
Nov
(33) |
Dec
(24) |
| 2014 |
Jan
(24) |
Feb
(4) |
Mar
(17) |
Apr
(26) |
May
(30) |
Jun
(56) |
Jul
(62) |
Aug
(1) |
Sep
(1) |
Oct
(5) |
Nov
(6) |
Dec
(9) |
| 2015 |
Jan
(1) |
Feb
(239) |
Mar
(1) |
Apr
(1) |
May
(7) |
Jun
(6) |
Jul
(12) |
Aug
(17) |
Sep
(11) |
Oct
(5) |
Nov
(1) |
Dec
(17) |
| 2016 |
Jan
(73) |
Feb
(117) |
Mar
(3) |
Apr
|
May
|
Jun
|
Jul
(67) |
Aug
|
Sep
|
Oct
(8) |
Nov
|
Dec
|
|
From: <br...@us...> - 2016-07-14 17:26:27
|
Revision: 4196
http://sourceforge.net/p/openlcb/svn/4196
Author: bracz
Date: 2016-07-14 17:26:24 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Makes consist create and delete a bidirectional operation.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/implementations/throttle/TractionThrottle.java
Modified: trunk/prototypes/java/src/org/openlcb/implementations/throttle/TractionThrottle.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/implementations/throttle/TractionThrottle.java 2016-07-14 17:26:04 UTC (rev 4195)
+++ trunk/prototypes/java/src/org/openlcb/implementations/throttle/TractionThrottle.java 2016-07-14 17:26:24 UTC (rev 4196)
@@ -172,6 +172,9 @@
Message m = TractionControlRequestMessage.createConsistAttach(iface.getNodeId(),
trainNode.getNodeId(), newMember, flags);
iface.getOutputConnection().put(m, this);
+ m = TractionControlRequestMessage.createConsistAttach(iface.getNodeId(),
+ newMember, trainNode.getNodeId(), flags);
+ iface.getOutputConnection().put(m, this);
}
/** Removes a node from the consist handled by the current assigned node.
@@ -180,6 +183,9 @@
Message m = TractionControlRequestMessage.createConsistDetach(iface.getNodeId(),
trainNode.getNodeId(), member);
iface.getOutputConnection().put(m, this);
+ m = TractionControlRequestMessage.createConsistDetach(iface.getNodeId(),
+ member, trainNode.getNodeId());
+ iface.getOutputConnection().put(m, this);
}
/**
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:26:07
|
Revision: 4195
http://sourceforge.net/p/openlcb/svn/4195
Author: bracz
Date: 2016-07-14 17:26:04 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Fixes warning.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/implementations/throttle/TractionThrottle.java
Modified: trunk/prototypes/java/src/org/openlcb/implementations/throttle/TractionThrottle.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/implementations/throttle/TractionThrottle.java 2016-07-14 17:25:45 UTC (rev 4194)
+++ trunk/prototypes/java/src/org/openlcb/implementations/throttle/TractionThrottle.java 2016-07-14 17:26:04 UTC (rev 4195)
@@ -90,7 +90,7 @@
public void refresh() {
if (!getEnabled()) return;
querySpeed();
- // Refreshes functions after getting the definite promise from the node.
+ queryConsist();
for (FunctionInfo f : functions.values()) {
queryFunction(f.fn);
}
@@ -129,12 +129,8 @@
assigned = true;
setStatus("Enabled.");
setEnabled(true);
- querySpeed();
- queryConsist();
- // Refreshes functions after getting the definite promise from the node.
- for (FunctionInfo f : functions.values()) {
- queryFunction(f.fn);
- }
+ // Refreshes functions and other settings after getting the definite promise from the node.
+ refresh();
}
/**
@@ -336,7 +332,7 @@
public void update(Boolean aBoolean) {
if (!enabled) return;
Message m = TractionControlRequestMessage.createSetFn(iface.getNodeId(),
- trainNode.getNodeId(), fn, aBoolean.booleanValue() ? 1 : 0);
+ trainNode.getNodeId(), fn, aBoolean ? 1 : 0);
iface.getOutputConnection().put(m, TractionThrottle.this);
}
};
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:25:47
|
Revision: 4194
http://sourceforge.net/p/openlcb/svn/4194
Author: bracz
Date: 2016-07-14 17:25:45 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Improves the debugging of incorrectly attributed returned datagrams: takes the response space and address from the actual response for read replies instead of from the memo. This allows catching cases when the returned datagram is misattributed to a wrong memo. Still not clear why such a misattribution ever happens.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/implementations/MemoryConfigurationService.java
Added Paths:
-----------
trunk/prototypes/java/src/org/openlcb/implementations/DatagramUtils.java
Added: trunk/prototypes/java/src/org/openlcb/implementations/DatagramUtils.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/implementations/DatagramUtils.java (rev 0)
+++ trunk/prototypes/java/src/org/openlcb/implementations/DatagramUtils.java 2016-07-14 17:25:45 UTC (rev 4194)
@@ -0,0 +1,26 @@
+package org.openlcb.implementations;
+
+/**
+ * Created by bracz on 4/24/16.
+ */
+public class DatagramUtils {
+
+ static Long parseLong(int[] payload, int offset) {
+ long retval = 0;
+ retval |= payload[offset++] & 0xff;
+ retval <<= 8;
+ retval |= payload[offset++] & 0xff;
+ retval <<= 8;
+ retval |= payload[offset++] & 0xff;
+ retval <<= 8;
+ retval |= payload[offset++] & 0xff;
+ return retval;
+ }
+
+ static void renderLong(int[] payload, int offset, long value) {
+ payload[offset++] = (int) ((value >> 24) & 0xff);
+ payload[offset++] = (int) ((value >> 16) & 0xff);
+ payload[offset++] = (int) ((value >> 8) & 0xff);
+ payload[offset++] = (int) (value & 0xff);
+ }
+}
Modified: trunk/prototypes/java/src/org/openlcb/implementations/MemoryConfigurationService.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/implementations/MemoryConfigurationService.java 2016-07-14 17:25:27 UTC (rev 4193)
+++ trunk/prototypes/java/src/org/openlcb/implementations/MemoryConfigurationService.java 2016-07-14 17:25:45 UTC (rev 4194)
@@ -69,12 +69,14 @@
// error read reply, return zero length
content = new byte[0];
}
+ long retAddress = DatagramUtils.parseLong(data, 2);
+ int retSpace = spaceByte ? data[6] : (0xFD + (data[1] & 0x03));
McsReadMemo memo;
synchronized (this) {
memo = readMemo;
readMemo = null;
}
- memo.handleReadData(dest, memo.space, memo.address, content);
+ memo.handleReadData(dest, retSpace, retAddress, content);
synchronized (this) {
if (readMemo == null && !pendingReads.isEmpty()) {
readMemo = pendingReads.pop();
@@ -110,8 +112,7 @@
}
if (writeMemo != null && ((data[1] & 0xF0) == 0x10)) {
McsWriteMemo memo = writeMemo;
- long retAddress = (((long) data[2] & 0xFF) << 24) | (((long) data[3] & 0xFF)
- << 16) | (((long) data[4] & 0xFF) << 8) | ((long) data[5] & 0xFF);
+ long retAddress = DatagramUtils.parseLong(data, 2);
if (retAddress != memo.address) {
logger.warning("Spurious write response datagram. Requested address=" +
memo.address + " returned address=" + retAddress);
@@ -336,6 +337,8 @@
@Override
public void handleReply(int code) {
if (code == 0) {
+ // Read is successful, we're expecting an answer (read reply datagram) to come.
+ // We are not popping the next message to send yet.
memo.handleWriteReply(code);
return;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:25:30
|
Revision: 4193
http://sourceforge.net/p/openlcb/svn/4193
Author: bracz
Date: 2016-07-14 17:25:27 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Adds capability to flush caches such as inmemory XML caches for FDI. Helpful when the train node has been reconfigured and the available functions may have changed.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/implementations/throttle/RemoteTrainNode.java
trunk/prototypes/java/src/org/openlcb/implementations/throttle/TrainNodeCache.java
Modified: trunk/prototypes/java/src/org/openlcb/implementations/throttle/RemoteTrainNode.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/implementations/throttle/RemoteTrainNode.java 2016-07-14 17:25:06 UTC (rev 4192)
+++ trunk/prototypes/java/src/org/openlcb/implementations/throttle/RemoteTrainNode.java 2016-07-14 17:25:27 UTC (rev 4193)
@@ -50,11 +50,20 @@
if (fdiXml != null) { fdiXml = payload; }
}
+ public synchronized void flushCache() {
+ fdiRoot = null;
+ }
+
public synchronized Element getFdiXml() {
if (fdiRoot != null) return fdiRoot;
new CdiMemConfigReader(node, iface, MemoryConfigurationService.SPACE_TRACTION_FDI)
.startLoadReader(new CdiMemConfigReader.ReaderAccess() {
@Override
+ public void progressNotify(long bytesRead, long totalBytes) {
+
+ }
+
+ @Override
public void provideReader(Reader r) {
try {
fdiRoot = XmlHelper.parseXmlFromReader(r);//JdomCdiReader.getHeadFromReader(r);
Modified: trunk/prototypes/java/src/org/openlcb/implementations/throttle/TrainNodeCache.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/implementations/throttle/TrainNodeCache.java 2016-07-14 17:25:06 UTC (rev 4192)
+++ trunk/prototypes/java/src/org/openlcb/implementations/throttle/TrainNodeCache.java 2016-07-14 17:25:27 UTC (rev 4193)
@@ -45,4 +45,10 @@
return new RemoteTrainNode(id, iface);
}
+ public void flushCache() {
+ for (RemoteTrainNode remoteNode : getList()) {
+ remoteNode.flushCache();
+ }
+ }
+
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:25:10
|
Revision: 4192
http://sourceforge.net/p/openlcb/svn/4192
Author: bracz
Date: 2016-07-14 17:25:06 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Fixes infinite retries of failed datagram reads in the memory space cache. Previously when a null-length data payload was returned, the same datagram wa retried indefinitely.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/cdi/impl/MemorySpaceCache.java
Modified: trunk/prototypes/java/src/org/openlcb/cdi/impl/MemorySpaceCache.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/impl/MemorySpaceCache.java 2016-07-14 17:24:49 UTC (rev 4191)
+++ trunk/prototypes/java/src/org/openlcb/cdi/impl/MemorySpaceCache.java 2016-07-14 17:25:06 UTC (rev 4192)
@@ -184,6 +184,7 @@
if (count > 64) {
count = 64;
}
+ final int fcount = count;
connection.getMemoryConfigurationService().request(
new MemoryConfigurationService.McsReadMemo(remoteNodeID, space,
currentRangeNextOffset, count) {
@@ -208,11 +209,19 @@
" address=" + currentRangeNextOffset + " expectedspace=" +
MemorySpaceCache.this.space + " expectedcount=" + this.count);
}
- System.arraycopy(data, 0, currentRangeData, (int) (currentRangeNextOffset -
- nextRangeToLoad.start), data.length);
- notifyPartialRead(currentRangeNextOffset, currentRangeNextOffset + data
- .length);
- currentRangeNextOffset += data.length;
+ if (data.length == 0) {
+ logger.warning(String.format("Datagram read returned 0 bytes. " +
+ "Remote node %s, space %d, address 0x%x", dest.toString(),
+ space, address));
+ currentRangeNextOffset += fcount;
+ } else {
+ System.arraycopy(data, 0, currentRangeData, (int)
+ (currentRangeNextOffset -
+ nextRangeToLoad.start), data.length);
+ notifyPartialRead(currentRangeNextOffset, currentRangeNextOffset + data
+ .length);
+ currentRangeNextOffset += data.length;
+ }
loadRange();
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:24:51
|
Revision: 4191
http://sourceforge.net/p/openlcb/svn/4191
Author: bracz
Date: 2016-07-14 17:24:49 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Adds progress notification for the XML load processes.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java
trunk/prototypes/java/src/org/openlcb/cdi/jdom/CdiMemConfigReader.java
Modified: trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java 2016-07-14 17:24:28 UTC (rev 4190)
+++ trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java 2016-07-14 17:24:49 UTC (rev 4191)
@@ -15,6 +15,7 @@
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
+import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -52,7 +53,10 @@
private CdiContainer root = null;
private final Map<Integer, MemorySpaceCache> spaces = new HashMap<>();
private final Map<String, CdiEntry> variables = new HashMap<>();
+ // Last time the progressbar was updated from the load.
+ private long lastProgress;
+
/**
* Connects to a node, populates the cache by fetching and parsing the CDI.
* @param connection OpenLCB network.
@@ -73,6 +77,17 @@
.ReaderAccess() {
@Override
+ public void progressNotify(long bytesRead, long totalBytes) {
+ lastProgress = new Date().getTime();
+ if (totalBytes > 0) {
+ setState(String.format("Loading: %.2f%% complete", bytesRead * 100.0 /
+ totalBytes));
+ } else {
+ setState(String.format("Loading: %d bytes complete", bytesRead));
+ }
+ }
+
+ @Override
public void provideReader(Reader r) {
try {
cdiRep = new JdomCdiReader().getRep(XmlHelper.parseXmlFromReader(r));
@@ -212,8 +227,9 @@
}
private void setState(String state) {
+ String oldState = this.state;
this.state = state;
- firePropertyChange(UPDATE_STATE, null, this.state);
+ firePropertyChange(UPDATE_STATE, oldState, this.state);
}
public String getStatus() {
@@ -221,6 +237,16 @@
}
/**
+ * Checks that the representation is complete. If it is not, starts a new load of the
+ * representation.
+ */
+ public void restartIfNeeded() {
+ if (root == null && (lastProgress + 5000) < (new Date().getTime())) {
+ triggerFetchCdi();
+ }
+ }
+
+ /**
* Interface for all internal representation of nodes that have children.
*/
public interface CdiContainer {
Modified: trunk/prototypes/java/src/org/openlcb/cdi/jdom/CdiMemConfigReader.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/jdom/CdiMemConfigReader.java 2016-07-14 17:24:28 UTC (rev 4190)
+++ trunk/prototypes/java/src/org/openlcb/cdi/jdom/CdiMemConfigReader.java 2016-07-14 17:24:49 UTC (rev 4191)
@@ -55,7 +55,10 @@
}
void nextRequest() {
- MemoryConfigurationService.McsReadMemo memo =
+ if (retval != null) {
+ retval.progressNotify(buf.length(), -1);
+ }
+ MemoryConfigurationService.McsReadMemo memo =
new MemoryConfigurationService.McsReadMemo(node, space, nextAddress, LENGTH) {
public void handleReadData(NodeID dest, int space, long address, byte[] data) {
// handle return data, checking for null in string or zero-length reply
@@ -81,6 +84,7 @@
private void done() {
// done, pass back a reader based on the current buffer contents
if (retval != null) {
+ retval.progressNotify(buf.length(), buf.length());
System.out.print("Retrieved XML: \n");
System.out.print(buf);
retval.provideReader(new java.io.StringReader(new String(buf)));
@@ -88,6 +92,12 @@
}
public interface ReaderAccess {
+ /**
+ *
+ * @param bytesRead how many bytes we have fetched so far from the server
+ * @param totalBytes the total number of bytes to read, or -1 if not known
+ */
+ public void progressNotify(long bytesRead, long totalBytes);
public void provideReader(java.io.Reader r);
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:24:31
|
Revision: 4190
http://sourceforge.net/p/openlcb/svn/4190
Author: bracz
Date: 2016-07-14 17:24:28 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Switches the data type of the offset from int to long, because it is valid to have it above 2^31.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java
trunk/prototypes/java/src/org/openlcb/cdi/impl/MemorySpaceCache.java
trunk/prototypes/java/src/org/openlcb/cdi/impl/RangeCacheUtil.java
Modified: trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java 2016-07-14 17:24:12 UTC (rev 4189)
+++ trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java 2016-07-14 17:24:28 UTC (rev 4190)
@@ -178,10 +178,10 @@
* @param origin offset in the segment of the beginning of the group payload
* @return the number of bytes (one repeat of) this group covers in the address space
*/
- private int processGroup(String baseName, int segment, List<CdiRep.Item> items,
- List<CdiEntry> output, int origin) {
+ private long processGroup(String baseName, int segment, List<CdiRep.Item> items,
+ List<CdiEntry> output, long origin) {
if (items == null) return 0;
- int base = origin;
+ long base = origin;
for (int i = 0; i < items.size(); i++) {
CdiRep.Item it = (CdiRep.Item) items.get(i);
@@ -294,7 +294,7 @@
/// Memory space number.
public int space;
/// Address of the first byte of this item in the memory space.
- public int origin;
+ public long origin;
/// The number of bytes that this component takes in the configuration space.
public int size;
/// Internal key for this variable or group
@@ -354,7 +354,8 @@
}
this.origin = segment.getOrigin();
this.space = segment.getSpace();
- this.size = processGroup(key, this.space, segment.getItems(), this.items, this.origin);
+ this.size = (int)processGroup(key, this.space, segment.getItems(), this.items, this
+ .origin);
}
@Override
@@ -400,7 +401,7 @@
public final CdiRep.Group group;
public final List<CdiEntry> items;
- public GroupBase(String name, CdiRep.Group group, int segment, int origin) {
+ public GroupBase(String name, CdiRep.Group group, int segment, long origin) {
this.key = name;
this.space = segment;
this.origin = origin;
@@ -432,9 +433,9 @@
* already performed)
* @param index is the 1-based index of this repeat of the given group
*/
- GroupRep(String name, CdiRep.Group group, int segment, int origin, int index) {
+ GroupRep(String name, CdiRep.Group group, int segment, long origin, int index) {
super(name, group, segment, origin);
- size = processGroup(name, segment, group.getItems(), items, origin);
+ size = (int) processGroup(name, segment, group.getItems(), items, origin);
this.index = index;
}
// The 1-based index of this replica.
@@ -454,10 +455,11 @@
* @param origin is the address of this repeat in that memory space (all skips are
* already performed)
*/
- GroupEntry(String baseName, CdiRep.Group group, int segment, int origin) {
+ GroupEntry(String baseName, CdiRep.Group group, int segment, long origin) {
super(baseName, group, segment, origin);
if (group.getReplication() <= 1) {
- size = processGroup(baseName, segment, group.getItems(), this.items, this.origin);
+ size = (int) processGroup(baseName, segment, group.getItems(), this.items, this
+ .origin);
} else {
size = 0;
for (int i = 0; i < group.getReplication(); ++i) {
@@ -477,7 +479,7 @@
public class IntegerEntry extends CdiEntry {
public CdiRep.IntegerRep rep;
- IntegerEntry(String name, CdiRep.IntegerRep rep, int segment, int origin) {
+ IntegerEntry(String name, CdiRep.IntegerRep rep, int segment, long origin) {
this.key = name;
this.space = segment;
this.origin = origin;
@@ -531,7 +533,7 @@
public class EventEntry extends CdiEntry {
public CdiRep.EventID rep;
- EventEntry(String name, CdiRep.EventID rep, int segment, int origin) {
+ EventEntry(String name, CdiRep.EventID rep, int segment, long origin) {
this.key = name;
this.space = segment;
this.origin = origin;
@@ -570,7 +572,7 @@
public class StringEntry extends CdiEntry {
public CdiRep.StringRep rep;
- StringEntry(String name, CdiRep.StringRep rep, int segment, int origin) {
+ StringEntry(String name, CdiRep.StringRep rep, int segment, long origin) {
this.key = name;
this.space = segment;
this.origin = origin;
Modified: trunk/prototypes/java/src/org/openlcb/cdi/impl/MemorySpaceCache.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/impl/MemorySpaceCache.java 2016-07-14 17:24:12 UTC (rev 4189)
+++ trunk/prototypes/java/src/org/openlcb/cdi/impl/MemorySpaceCache.java 2016-07-14 17:24:28 UTC (rev 4190)
@@ -36,7 +36,7 @@
TreeMap<>();
java.beans.PropertyChangeSupport pcs = new java.beans.PropertyChangeSupport(this);
private Range nextRangeToLoad = null;
- private int currentRangeNextOffset;
+ private long currentRangeNextOffset;
private byte[] currentRangeData;
public MemorySpaceCache(OlcbInterface connection, NodeID remoteNode, int space) {
@@ -63,7 +63,7 @@
* @param start address of first byte to be cached (inclusive)
* @param end address of first byte after the cached region
*/
- public void addRangeToCache(int start, int end) {
+ public void addRangeToCache(long start, long end) {
ranges.addRange(start, end);
}
@@ -76,7 +76,7 @@
* exclusive)
* @param listener callback to invoke
*/
- public void addRangeListener(int start, int end, PropertyChangeListener listener) {
+ public void addRangeListener(long start, long end, PropertyChangeListener listener) {
synchronized (this) {
Range r = new Range(start, end);
ChangeEntry lt = dataChangeListeners.get(r);
@@ -96,7 +96,7 @@
* @param start offset (inclusive)
* @param end offset (exclusive)
*/
- private void notifyPartialRead(int start, int end) {
+ private void notifyPartialRead(long start, long end) {
PropertyChangeEvent ev = null;
for (Map.Entry<Range, ChangeEntry> e : dataChangeListeners.entrySet()) {
if (e.getKey().start < end && e.getKey().end > start) {
@@ -119,7 +119,7 @@
* @param start offset (inclusive)
* @param end offset (exclusive)
*/
- private void notifyAfterWrite(int start, int end) {
+ private void notifyAfterWrite(long start, long end) {
PropertyChangeEvent ev = null;
for (Map.Entry<Range, ChangeEntry> e : dataChangeListeners.entrySet()) {
if (e.getKey().start < end && e.getKey().end > start) {
@@ -173,10 +173,10 @@
private void loadRange() {
if (currentRangeNextOffset < 0) {
currentRangeNextOffset = nextRangeToLoad.start;
- currentRangeData = new byte[nextRangeToLoad.end - nextRangeToLoad.start];
+ currentRangeData = new byte[(int) (nextRangeToLoad.end - nextRangeToLoad.start)];
dataCache.put(nextRangeToLoad, currentRangeData);
}
- int count = nextRangeToLoad.end - currentRangeNextOffset;
+ int count = (int)(nextRangeToLoad.end - currentRangeNextOffset);
if (count <= 0) {
continueLoading();
return;
@@ -208,8 +208,8 @@
" address=" + currentRangeNextOffset + " expectedspace=" +
MemorySpaceCache.this.space + " expectedcount=" + this.count);
}
- System.arraycopy(data, 0, currentRangeData, currentRangeNextOffset -
- nextRangeToLoad.start, data.length);
+ System.arraycopy(data, 0, currentRangeData, (int) (currentRangeNextOffset -
+ nextRangeToLoad.start), data.length);
notifyPartialRead(currentRangeNextOffset, currentRangeNextOffset + data
.length);
currentRangeNextOffset += data.length;
@@ -219,7 +219,7 @@
);
}
- private Map.Entry<Range, byte[]> getCacheForRange(int offset, int len) {
+ private Map.Entry<Range, byte[]> getCacheForRange(long offset, int len) {
Range r = new Range(offset, Integer.MAX_VALUE);
Map.Entry<Range, byte[]> entry = dataCache.floorEntry(r);
if (entry == null) return null;
@@ -230,21 +230,22 @@
return entry;
}
- public byte[] read(int offset, int len) {
+ public byte[] read(long offset, int len) {
Map.Entry<Range, byte[]> entry = getCacheForRange(offset, len);
if (entry == null) return null;
byte[] ret = new byte[len];
- System.arraycopy(entry.getValue(), offset - entry.getKey().start, ret, 0, len);
+ System.arraycopy(entry.getValue(), (int) (offset - entry.getKey().start), ret, 0, len);
return ret;
}
- public void write(final int offset, byte[] data, final ConfigRepresentation.CdiEntry cdiEntry) {
+ public void write(final long offset, byte[] data, final ConfigRepresentation.CdiEntry
+ cdiEntry) {
int len = data.length;
Map.Entry<Range, byte[]> entry = getCacheForRange(offset, len);
if (entry != null && entry.getValue() != null) {
- System.arraycopy(data, 0, entry.getValue(), offset - entry.getKey().start, data.length);
+ System.arraycopy(data, 0, entry.getValue(), (int) (offset - entry.getKey().start), data.length);
}
- logger.finer("Writing to space " + space + " offset 0x" + Integer.toHexString(offset) +
+ logger.finer("Writing to space " + space + " offset 0x" + Long.toHexString(offset) +
" payload length " + data.length);
connection.getMemoryConfigurationService().request(
new MemoryConfigurationService.McsWriteMemo(remoteNodeID, space, offset, data) {
Modified: trunk/prototypes/java/src/org/openlcb/cdi/impl/RangeCacheUtil.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/impl/RangeCacheUtil.java 2016-07-14 17:24:12 UTC (rev 4189)
+++ trunk/prototypes/java/src/org/openlcb/cdi/impl/RangeCacheUtil.java 2016-07-14 17:24:28 UTC (rev 4190)
@@ -43,7 +43,7 @@
return new Range(Math.min(current.start, next.start), Math.max(current.end, next.end));
}
- public synchronized void addRange(int start, int end) {
+ public synchronized void addRange(long start, long end) {
addedRanges.add(new Range(start, end));
isSimplified = false;
}
@@ -82,11 +82,11 @@
*/
public static class Range implements Comparable<Range> {
/// Address of first byte included in the range.
- public final int start;
+ public final long start;
/// Address of first byte not included in the range.
- public final int end;
+ public final long end;
- public Range(int s, int e) {
+ public Range(long s, long e) {
start = s;
end = e;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:24:15
|
Revision: 4189
http://sourceforge.net/p/openlcb/svn/4189
Author: bracz
Date: 2016-07-14 17:24:12 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Saves constructor arguments to internal fields.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/StreamDataCompleteMessage.java
Modified: trunk/prototypes/java/src/org/openlcb/StreamDataCompleteMessage.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/StreamDataCompleteMessage.java 2016-07-14 17:23:53 UTC (rev 4188)
+++ trunk/prototypes/java/src/org/openlcb/StreamDataCompleteMessage.java 2016-07-14 17:24:12 UTC (rev 4189)
@@ -17,6 +17,8 @@
public StreamDataCompleteMessage(NodeID source, NodeID dest,
byte sourceStreamID, byte destStreamID) {
super(source, dest);
+ this.sourceStreamID = sourceStreamID;
+ this.destStreamID = destStreamID;
}
byte sourceStreamID;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:23:55
|
Revision: 4188
http://sourceforge.net/p/openlcb/svn/4188
Author: bracz
Date: 2016-07-14 17:23:53 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Fixes crashes on stream message parsing code.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/can/MessageBuilder.java
Modified: trunk/prototypes/java/src/org/openlcb/can/MessageBuilder.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/can/MessageBuilder.java 2016-07-14 17:23:35 UTC (rev 4187)
+++ trunk/prototypes/java/src/org/openlcb/can/MessageBuilder.java 2016-07-14 17:23:53 UTC (rev 4188)
@@ -259,7 +259,8 @@
return retlist;
// dph: add all stream messages reply and proceed.
case StreamInitiateRequest:
- retlist.add(new StreamInitiateRequestMessage(source,dest,content[2]<<8+content[3],content[4], content[5]));
+ retlist.add(new StreamInitiateRequestMessage(source,dest,content[2]<<8+content[3],content[4],
+ (content.length > 5 ? content[5] : -1)));
return retlist;
case StreamInitiateReply:
retlist.add(new StreamInitiateReplyMessage(source,dest,content[0]<<8+content[1],content[2], content[3]));
@@ -269,7 +270,8 @@
retlist.add(new StreamDataProceedMessage(source,dest,content[2], content[3]));
return retlist;
case StreamDataComplete:
- retlist.add(new StreamDataCompleteMessage(source,dest,content[2], content[3]));
+ retlist.add(new StreamDataCompleteMessage(source,dest,content.length > 2 ?
+ content[2] : -1, content.length > 3 ? content[3] : -1));
return retlist;
default:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:23:37
|
Revision: 4187
http://sourceforge.net/p/openlcb/svn/4187
Author: bracz
Date: 2016-07-14 17:23:35 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Adds an accessor to the currently selected nodeID.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/implementations/throttle/TractionThrottle.java
Modified: trunk/prototypes/java/src/org/openlcb/implementations/throttle/TractionThrottle.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/implementations/throttle/TractionThrottle.java 2016-07-14 17:23:15 UTC (rev 4186)
+++ trunk/prototypes/java/src/org/openlcb/implementations/throttle/TractionThrottle.java 2016-07-14 17:23:35 UTC (rev 4187)
@@ -16,6 +16,8 @@
import java.util.Map;
import java.util.logging.Logger;
+import javax.annotation.Nullable;
+
/**
* Traction protocol based implementation of the throttle. This differs from {@ref
* ThrottleImplementation} in that it uses the {@ref TractionControlRequest} messages for talking
@@ -72,13 +74,19 @@
}
public void start(RemoteTrainNode trainNode) {
- if (assigned && !trainNode.getNodeId().equals(trainNode.getNodeId())) {
+ if (assigned && !this.trainNode.getNodeId().equals(trainNode.getNodeId())) {
release();
}
this.trainNode = trainNode;
assign();
}
+ public @Nullable
+ NodeID getNodeId() {
+ if (trainNode == null) return null;
+ return trainNode.getNodeId();
+ }
+
public void refresh() {
if (!getEnabled()) return;
querySpeed();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:23:18
|
Revision: 4186
http://sourceforge.net/p/openlcb/svn/4186
Author: bracz
Date: 2016-07-14 17:23:15 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Adds documentation for the CdiRep.Map interface.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/cdi/CdiRep.java
Modified: trunk/prototypes/java/src/org/openlcb/cdi/CdiRep.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/CdiRep.java 2016-07-14 17:22:57 UTC (rev 4185)
+++ trunk/prototypes/java/src/org/openlcb/cdi/CdiRep.java 2016-07-14 17:23:15 UTC (rev 4186)
@@ -49,9 +49,32 @@
}
public static interface Map {
+ /**
+ * Converts stored values to visible values.
+ * @param key a network-stored value, usually a decimal rendered number.
+ * @return the user-visible string explanation that should be displayed.
+ */
public String getEntry(String key);
+
+ /**
+ * Converts visible values to stored values.
+ * @param entry the visible value that was selected by the user
+ * @return the (string representation) of the value to store to the node's memory space
+ * (usually a decimal formatted number).
+ */
public String getKey(String entry);
+
+ /**
+ * Gets valid values (returned array is parallel to @ref getValues() )
+ * @return a list of all valid stored values (usually a list of decimal formatted
+ * integers).
+ */
public java.util.List<String> getKeys();
+
+ /**
+ * Gets all user-visible string explanations (returned array is parallel to @ref getKeys() )
+ * @return a list of all user-visible values.
+ */
public java.util.List<String> getValues();
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:23:00
|
Revision: 4185
http://sourceforge.net/p/openlcb/svn/4185
Author: bracz
Date: 2016-07-14 17:22:57 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Shows the map values in the lastVisibleValue property of integer CdiEntry representations.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java
Modified: trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java 2016-07-14 17:22:40 UTC (rev 4184)
+++ trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java 2016-07-14 17:22:57 UTC (rev 4185)
@@ -493,6 +493,11 @@
@Override
protected void updateVisibleValue() {
lastVisibleValue = Long.toString(getValue());
+ CdiRep.Map map = rep.getMap();
+ if (map != null && map.getKeys().size() > 0) {
+ String value = map.getEntry(lastVisibleValue);
+ if (value != null) lastVisibleValue = value;
+ }
}
public long getValue() {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:22:43
|
Revision: 4184
http://sourceforge.net/p/openlcb/svn/4184
Author: bracz
Date: 2016-07-14 17:22:40 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Adds a string rendering of the last visible value for CDI entries, updated on every change notification.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java
Modified: trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java 2016-07-14 17:22:22 UTC (rev 4183)
+++ trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java 2016-07-14 17:22:40 UTC (rev 4184)
@@ -299,10 +299,14 @@
public int size;
/// Internal key for this variable or group
public String key;
+ /// String-rendered value of this entry. Populated for leaf entries.
+ public String lastVisibleValue = null;
public abstract CdiRep.Item getCdiItem();
+ protected void updateVisibleValue() {}
public void fireUpdate() {
+ updateVisibleValue();
firePropertyChange(UPDATE_ENTRY_DATA, null, null);
}
@@ -486,6 +490,11 @@
return rep;
}
+ @Override
+ protected void updateVisibleValue() {
+ lastVisibleValue = Long.toString(getValue());
+ }
+
public long getValue() {
MemorySpaceCache cache = getCacheForSpace(space);
byte[] b = cache.read(origin, size);
@@ -530,6 +539,11 @@
return rep;
}
+ @Override
+ protected void updateVisibleValue() {
+ lastVisibleValue = getValue().toString();
+ }
+
public EventID getValue() {
MemorySpaceCache cache = getCacheForSpace(space);
byte[] b = cache.read(origin, size);
@@ -564,6 +578,11 @@
return rep;
}
+ @Override
+ protected void updateVisibleValue() {
+ lastVisibleValue = getValue();
+ }
+
public String getValue() {
MemorySpaceCache cache = getCacheForSpace(space);
byte[] b = cache.read(origin, size);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:22:25
|
Revision: 4183
http://sourceforge.net/p/openlcb/svn/4183
Author: bracz
Date: 2016-07-14 17:22:22 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Fixes crash due to multiple calls to the onError callback.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/can/impl/OlcbConnection.java
Modified: trunk/prototypes/java/src/org/openlcb/can/impl/OlcbConnection.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/can/impl/OlcbConnection.java 2016-07-14 17:22:04 UTC (rev 4182)
+++ trunk/prototypes/java/src/org/openlcb/can/impl/OlcbConnection.java 2016-07-14 17:22:22 UTC (rev 4183)
@@ -62,13 +62,17 @@
private Runnable mOnError = new Runnable() {
@Override
public void run() {
- outputHub.removeEntry(output);
- listenerProxy.onDisconnect();
- shutdown();
+ synchronized(OlcbConnection.this) {
+ if (outputHub != null) {
+ outputHub.removeEntry(output);
+ }
+ listenerProxy.onDisconnect();
+ shutdown();
+ }
}
};
- private void connect() {
+ private synchronized void connect() {
this.inputHub = new CanFrameHub();
this.outputHub = new CanFrameHub();
listenerProxy.onConnectionPending();
@@ -102,7 +106,7 @@
lastConnection = this;
}
- public void shutdown() {
+ public synchronized void shutdown() {
if (inputHub != null) {
inputHub.clear();
inputHub = null;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:22:07
|
Revision: 4182
http://sourceforge.net/p/openlcb/svn/4182
Author: bracz
Date: 2016-07-14 17:22:04 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Proxies IOExceptions from the gridconnect reader and writer directly into the OlcbConnection class. The previous detection methods of IO errors did not work.
The listeners of the OlcbConnection will now get the onDisconnect notifications when the socket is closed.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/can/impl/GridConnectInput.java
trunk/prototypes/java/src/org/openlcb/can/impl/GridConnectOutput.java
trunk/prototypes/java/src/org/openlcb/can/impl/OlcbConnection.java
Modified: trunk/prototypes/java/src/org/openlcb/can/impl/GridConnectInput.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/can/impl/GridConnectInput.java 2016-07-14 17:21:44 UTC (rev 4181)
+++ trunk/prototypes/java/src/org/openlcb/can/impl/GridConnectInput.java 2016-07-14 17:22:04 UTC (rev 4182)
@@ -22,10 +22,19 @@
private ArrayList<Byte> data = new ArrayList<>();
private BufferedReader input;
private CanFrameListener listener;
+ private final Runnable onError;
- public GridConnectInput(BufferedReader input, CanFrameListener listener) {
+ /**
+ * Creates the gridconnect input parser. Starts the parsing thread.
+ *
+ * @param input the (buffered) socklet to read from
+ * @param listener the parsed CAN frames will be forwarded to this listener
+ * @param onError will be called when an IO error happens on the input thread. May be null.
+ */
+ public GridConnectInput(BufferedReader input, CanFrameListener listener, Runnable onError) {
this.input = input;
this.listener = listener;
+ this.onError = onError;
new Thread() {
public void run() {
threadBody();
@@ -106,6 +115,9 @@
} catch (IOException e1) {
logger.fine("Error closing from gridconnect port " + e1.toString());
}
+ if (onError != null) {
+ onError.run();
+ }
}
}
Modified: trunk/prototypes/java/src/org/openlcb/can/impl/GridConnectOutput.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/can/impl/GridConnectOutput.java 2016-07-14 17:21:44 UTC (rev 4181)
+++ trunk/prototypes/java/src/org/openlcb/can/impl/GridConnectOutput.java 2016-07-14 17:22:04 UTC (rev 4182)
@@ -19,9 +19,16 @@
private final static Logger logger = Logger.getLogger(TAG);
private BufferedOutputStream output;
+ private final Runnable onError;
- public GridConnectOutput(OutputStream output) {
+ /**
+ * Creates the object ussed for rendering CAN frames to GridConnect format.
+ * @param output the (raw) output socket to send the gridconnect data to.
+ * @param onError will be called when the output experiences an IO error. May be null.
+ */
+ public GridConnectOutput(OutputStream output, Runnable onError) {
this.output = new BufferedOutputStream(output);
+ this.onError = onError;
}
public static String format(CanFrame frame) {
@@ -60,6 +67,9 @@
} catch (IOException e1) {
logger.fine("Error closing gridconnect output: " + e1.toString());
}
+ if (onError != null) {
+ onError.run();
+ }
}
}
Modified: trunk/prototypes/java/src/org/openlcb/can/impl/OlcbConnection.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/can/impl/OlcbConnection.java 2016-07-14 17:21:44 UTC (rev 4181)
+++ trunk/prototypes/java/src/org/openlcb/can/impl/OlcbConnection.java 2016-07-14 17:22:04 UTC (rev 4182)
@@ -59,6 +59,15 @@
}.start();
}
+ private Runnable mOnError = new Runnable() {
+ @Override
+ public void run() {
+ outputHub.removeEntry(output);
+ listenerProxy.onDisconnect();
+ shutdown();
+ }
+ };
+
private void connect() {
this.inputHub = new CanFrameHub();
this.outputHub = new CanFrameHub();
@@ -77,8 +86,8 @@
listenerProxy.onDisconnect();
return;
}
- input = new GridConnectInput(reader, inputHub);
- output = new GridConnectOutput(outputStream);
+ input = new GridConnectInput(reader, inputHub, mOnError);
+ output = new GridConnectOutput(outputStream, mOnError);
outputHub.addEntry(output);
// Creates the actual OpenLCB objects and wires up with the interface.
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:21:47
|
Revision: 4181
http://sourceforge.net/p/openlcb/svn/4181
Author: bracz
Date: 2016-07-14 17:21:44 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Refactors Olcb Connection listeners to allow for more then one listener to be registered as well as allow for listeners to be unregistered.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/can/impl/OlcbConnection.java
Modified: trunk/prototypes/java/src/org/openlcb/can/impl/OlcbConnection.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/can/impl/OlcbConnection.java 2016-07-14 17:21:23 UTC (rev 4180)
+++ trunk/prototypes/java/src/org/openlcb/can/impl/OlcbConnection.java 2016-07-14 17:21:44 UTC (rev 4181)
@@ -27,7 +27,7 @@
// ConnectionManager.
public static OlcbConnection lastConnection = null;
private final NodeID nodeId;
- private final ConnectionListener connectionListener;
+ private final ListenerProxy listenerProxy;
private final Map<NodeID, ConfigRepresentation> nodeConfigs = new HashMap<>();
private String hostName;
private int portNumber;
@@ -44,7 +44,8 @@
hostName, int portNumber, ConnectionListener connectionListener) {
this.hostName = hostName;
this.portNumber = portNumber;
- this.connectionListener = connectionListener;
+ this.listenerProxy = new ListenerProxy();
+ this.listenerProxy.add(connectionListener);
this.nodeId = nodeId;
new Thread() {
public void run() {
@@ -61,8 +62,8 @@
private void connect() {
this.inputHub = new CanFrameHub();
this.outputHub = new CanFrameHub();
- connectionListener.onConnectionPending();
- connectionListener.onStatusChange("Connecting...");
+ listenerProxy.onConnectionPending();
+ listenerProxy.onStatusChange("Connecting...");
BufferedReader reader;
OutputStream outputStream;
try {
@@ -72,8 +73,8 @@
new InputStreamReader(socket.getInputStream()));
outputStream = socket.getOutputStream();
} catch (IOException e) {
- connectionListener.onStatusChange("Connection failed: " + e.toString());
- connectionListener.onDisconnect();
+ listenerProxy.onStatusChange("Connection failed: " + e.toString());
+ listenerProxy.onDisconnect();
return;
}
input = new GridConnectInput(reader, inputHub);
@@ -86,7 +87,7 @@
canInterface.addStartListener(new Connection.ConnectionListener() {
@Override
public void connectionActive(Connection c) {
- connectionListener.onConnect();
+ listenerProxy.onConnect();
}
});
lastConnection = this;
@@ -116,7 +117,18 @@
socket = null;
}
+ public void addConnectionListener(ConnectionListener l) {
+ listenerProxy.add(l);
+ }
/**
+ * Removes a listener. It is okay to call this from inside a connectionlistener callback.
+ * @param l listener to remove
+ */
+ public void removeConnectionListener(ConnectionListener l) {
+ listenerProxy.remove(l);
+ }
+
+ /**
* Creates a new or returns a cached CDI representation for the given node.
*/
public synchronized ConfigRepresentation getConfigForNode(NodeID remoteNode) {
@@ -166,6 +178,61 @@
void onConnectionPending();
}
+ /**
+ * Simple registry for connection listeners; proxies all calls to every single entry.
+ */
+ private class ListenerProxy implements ConnectionListener {
+ private List<ConnectionListener> entries = new ArrayList<>(3);
+
+ public synchronized void add(ConnectionListener l) {
+ entries.add(l);
+ }
+
+ /**
+ * Removes a listener. It is okay to call this from inside a connectionlistener callback.
+ * @param l listener to remove
+ */
+ public synchronized void remove(ConnectionListener l) {
+ entries.remove(l);
+ }
+
+ private synchronized ConnectionListener[] getEntries() {
+ ConnectionListener[] ar = new ConnectionListener[entries.size()];
+ return entries.toArray(ar);
+ }
+ @Override
+ public void onConnect() {
+ ConnectionListener[] ar = getEntries();
+ for (ConnectionListener l : ar) {
+ l.onConnect();
+ }
+ }
+
+ @Override
+ public void onDisconnect() {
+ ConnectionListener[] ar = getEntries();
+ for (ConnectionListener l : ar) {
+ l.onDisconnect();
+ }
+ }
+
+ @Override
+ public void onStatusChange(String status) {
+ ConnectionListener[] ar = getEntries();
+ for (ConnectionListener l : ar) {
+ l.onStatusChange(status);
+ }
+ }
+
+ @Override
+ public void onConnectionPending() {
+ ConnectionListener[] ar = getEntries();
+ for (ConnectionListener l : ar) {
+ l.onConnectionPending();
+ }
+ }
+ }
+
public class CanFrameHub implements CanFrameListener {
private List<CanFrameListener> entries = new ArrayList<>();
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:21:26
|
Revision: 4180
http://sourceforge.net/p/openlcb/svn/4180
Author: bracz
Date: 2016-07-14 17:21:23 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Adds the concept of "default value" to the VersionedValue object. Makes sure that getValue() always returns non-null, but it is possible to figure out if the object is still at the default value.
Changes BitEventPC to producer "unknown" if the value is still at the default, and send off an actual event at the first set() call.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/implementations/BitProducerConsumer.java
trunk/prototypes/java/src/org/openlcb/implementations/VersionedValue.java
trunk/prototypes/java/test/org/openlcb/implementations/BitProducerConsumerTest.java
Modified: trunk/prototypes/java/src/org/openlcb/implementations/BitProducerConsumer.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/implementations/BitProducerConsumer.java 2016-07-14 17:21:05 UTC (rev 4179)
+++ trunk/prototypes/java/src/org/openlcb/implementations/BitProducerConsumer.java 2016-07-14 17:21:23 UTC (rev 4180)
@@ -22,13 +22,26 @@
private final EventID eventOn;
private final EventID eventOff;
private final OlcbInterface iface;
- private VersionedValue<Boolean> value = null;
- private VersionedValueListener<Boolean> valueListener = null;
+ private final VersionedValue<Boolean> value;
+ private final VersionedValueListener<Boolean> valueListener;
- public BitProducerConsumer(OlcbInterface iface, EventID eventOn, EventID eventOff) {
+ public BitProducerConsumer(OlcbInterface iface, EventID eventOn, EventID eventOff, boolean
+ defaultValue) {
this.iface = iface;
this.eventOn = eventOn;
this.eventOff = eventOff;
+ value = new VersionedValue<>(defaultValue);
+ valueListener = new VersionedValueListener<Boolean>(value) {
+ @Override
+ public void update(Boolean newValue) {
+ Message msg = new ProducerConsumerEventReportMessage(BitProducerConsumer.this.iface
+ .getNodeId(),
+ newValue ? BitProducerConsumer.this.eventOn :
+ BitProducerConsumer.this.eventOff);
+ BitProducerConsumer.this.iface.getOutputConnection().put(msg, BitProducerConsumer
+ .this);
+ }
+ };
iface.registerMessageListener(this);
iface.getOutputConnection().registerStartNotification(new ConnectionListener() {
@Override
@@ -38,19 +51,22 @@
});
}
- public synchronized VersionedValue<Boolean> getValue(boolean defaultValue) {
- if(value == null) {
- setValueFromNetwork(defaultValue);
- }
+ public VersionedValue<Boolean> getValue() {
return value;
}
- public VersionedValue<Boolean> getValue() {
- return value;
+ /**
+ * @return true if we have not received any network state yet, thus the value is still at the
+ * default value passed in.
+ */
+ public boolean isValueAtDefault() {
+ return (value.getVersion() == value.DEFAULT_VERSION);
}
private EventState getOnEventState() {
- if (value == null) return EventState.Unknown;
+ if (isValueAtDefault()) {
+ return EventState.Unknown;
+ }
if (value.getLatestData()) return EventState.Valid;
return EventState.Invalid;
}
@@ -161,20 +177,6 @@
}
private void setValueFromNetwork(boolean isOn) {
- synchronized (this) {
- if (value == null) {
- value = new VersionedValue<>(isOn);
- valueListener = new VersionedValueListener<Boolean>(value) {
- @Override
- public void update(Boolean newValue) {
- Message msg = new ProducerConsumerEventReportMessage(iface.getNodeId(),
- newValue ? eventOn : eventOff);
- iface.getOutputConnection().put(msg, BitProducerConsumer.this);
- }
- };
- return;
- }
- }
valueListener.setFromOwner(isOn);
}
}
Modified: trunk/prototypes/java/src/org/openlcb/implementations/VersionedValue.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/implementations/VersionedValue.java 2016-07-14 17:21:05 UTC (rev 4179)
+++ trunk/prototypes/java/src/org/openlcb/implementations/VersionedValue.java 2016-07-14 17:21:23 UTC (rev 4180)
@@ -8,10 +8,11 @@
int version;
int nextVersion;
java.beans.PropertyChangeSupport pcs = new java.beans.PropertyChangeSupport(this);
+ public static int DEFAULT_VERSION = 1;
public VersionedValue(T t) {
- version = 1;
- nextVersion = 2;
+ version = DEFAULT_VERSION;
+ nextVersion = DEFAULT_VERSION + 1;
data = t;
}
@@ -35,14 +36,18 @@
boolean updated = false;
synchronized (this) {
if (atVersion <= version) return false;
+ int oldVersion = version;
version = atVersion;
if (nextVersion <= atVersion) {
nextVersion = atVersion + 1;
}
- if (data.equals(t)) {
+ if (data.equals(t) && oldVersion != DEFAULT_VERSION) {
return true;
}
old = data;
+ if (oldVersion == DEFAULT_VERSION) {
+ old = null;
+ }
data = t;
}
firePropertyChange("updated", old, t);
Modified: trunk/prototypes/java/test/org/openlcb/implementations/BitProducerConsumerTest.java
===================================================================
--- trunk/prototypes/java/test/org/openlcb/implementations/BitProducerConsumerTest.java 2016-07-14 17:21:05 UTC (rev 4179)
+++ trunk/prototypes/java/test/org/openlcb/implementations/BitProducerConsumerTest.java 2016-07-14 17:21:23 UTC (rev 4180)
@@ -82,9 +82,10 @@
}
public void helperInputSetClear(String frameOn, String frameOff) {
- assertNull(pc.getValue());
+ assertTrue(pc.isValueAtDefault());
+ assertFalse(pc.getValue().getLatestData());
sendFrame(frameOn);
- assertNotNull(pc.getValue());
+ assertFalse(pc.isValueAtDefault());
assertTrue(pc.getValue().getLatestData());
sendFrame(frameOff);
assertFalse(pc.getValue().getLatestData());
@@ -161,15 +162,21 @@
}
public void testGenerateEvents() throws Exception {
- VersionedValue<Boolean> v = pc.getValue(false);
+ VersionedValue<Boolean> v = pc.getValue();
sendFrameAndExpectResult( //
":X19914444N0504030201000708;",
- ":X19545333N0504030201000708;");
+ ":X19547333N0504030201000708;");
expectNoFrames();
v.set(false);
+ expectFrame(":X195B4333N0504030201000709;");
+
expectNoFrames();
+ sendFrameAndExpectResult( //
+ ":X19914444N0504030201000708;",
+ ":X19545333N0504030201000708;");
+ expectNoFrames();
v.set(true);
expectFrame(":X195B4333N0504030201000708;");
@@ -193,7 +200,7 @@
public void setUp() {
iface.fakeOutputConnection.history.clear();
aliasMap.insert(0x444, new NodeID(new byte[]{1,2,3,1,2,3}));
- pc = new BitProducerConsumer(iface, onEvent, offEvent);
+ pc = new BitProducerConsumer(iface, onEvent, offEvent, false);
expectFrame(":X19547333N0504030201000708;");
expectFrame(":X19547333N0504030201000709;");
expectFrame(":X194C7333N0504030201000708;");
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:21:07
|
Revision: 4179
http://sourceforge.net/p/openlcb/svn/4179
Author: bracz
Date: 2016-07-14 17:21:05 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Renames config backup utility.
Added Paths:
-----------
trunk/prototypes/java/src/org/openlcb/cdi/cmd/BackupConfig.java
Removed Paths:
-------------
trunk/prototypes/java/src/org/openlcb/cdi/cmd/SaveConfig.java
Copied: trunk/prototypes/java/src/org/openlcb/cdi/cmd/BackupConfig.java (from rev 4178, trunk/prototypes/java/src/org/openlcb/cdi/cmd/SaveConfig.java)
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/cmd/BackupConfig.java (rev 0)
+++ trunk/prototypes/java/src/org/openlcb/cdi/cmd/BackupConfig.java 2016-07-14 17:21:05 UTC (rev 4179)
@@ -0,0 +1,96 @@
+package org.openlcb.cdi.cmd;
+
+import org.openlcb.NodeID;
+import org.openlcb.Utilities;
+import org.openlcb.can.impl.OlcbConnection;
+import org.openlcb.cdi.impl.ConfigRepresentation;
+
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+/**
+ * Created by bracz on 4/9/16.
+ */
+public class BackupConfig {
+
+
+ static public void writeEntry(BufferedWriter outFile, String key, String value) {
+ try {
+ outFile.write(Util.escapeString(key));
+ outFile.write('=');
+ outFile.write(Util.escapeString(value));
+ outFile.write('\n');
+ } catch (IOException e1) {
+ e1.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ // Main entry point
+ static public void main(String[] args) {
+ if (args.length != 5) {
+ usage();
+ return;
+ }
+ System.out.println("arg0: " + args[0]);
+ NodeID localNode = new NodeID(args[0]);
+ final String host = args[1];
+ final int port = Integer.parseInt(args[2]);
+ final NodeID remoteNode = new NodeID(args[3]);
+ final String dstFile = args[4];
+
+ final OlcbConnection connection = Util.connect(localNode, host, port);
+ System.out.println("Fetching CDI.");
+ ConfigRepresentation repr = connection.getConfigForNode(remoteNode);
+ Util.waitForPropertyChange(repr, ConfigRepresentation.UPDATE_REP);
+ System.out.println("CDI fetch done. Waiting for caches.");
+ Util.waitForPropertyChange(repr, ConfigRepresentation.UPDATE_CACHE_COMPLETE);
+ System.out.println("Caches complete.");
+ BufferedWriter outFile = null;
+
+ try {
+ outFile = Files.newBufferedWriter(Paths.get(dstFile), Charset.forName("UTF-8"));
+ } catch (IOException e) {
+ System.err.println("Failed to create output file: " + e.toString());
+ System.exit(1);
+ }
+ final BufferedWriter finalOutFile = outFile;
+ System.out.println("Writing variables.");
+ repr.visit(new ConfigRepresentation.Visitor() {
+ @Override
+ public void visitString(ConfigRepresentation.StringEntry e) {
+ writeEntry(finalOutFile, e.key, e.getValue());
+ }
+
+ @Override
+ public void visitInt(ConfigRepresentation.IntegerEntry e) {
+ writeEntry(finalOutFile, e.key, Long.toString(e.getValue()));
+ }
+
+ @Override
+ public void visitEvent(ConfigRepresentation.EventEntry e) {
+ writeEntry(finalOutFile, e.key, Utilities.toHexDotsString(e.getValue
+ ().getContents()));
+ }
+ }
+ );
+ try {
+ outFile.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ System.out.println("Done.");
+ System.exit(0);
+ }
+
+ private static void usage() {
+ String usageString = "usage: saveconfig local_node_id hub_host hub_port dst_node_id " +
+ "dst_filename\n";
+ System.err.print(usageString);
+ }
+
+}
Deleted: trunk/prototypes/java/src/org/openlcb/cdi/cmd/SaveConfig.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/cmd/SaveConfig.java 2016-07-14 17:20:44 UTC (rev 4178)
+++ trunk/prototypes/java/src/org/openlcb/cdi/cmd/SaveConfig.java 2016-07-14 17:21:05 UTC (rev 4179)
@@ -1,96 +0,0 @@
-package org.openlcb.cdi.cmd;
-
-import org.openlcb.NodeID;
-import org.openlcb.Utilities;
-import org.openlcb.can.impl.OlcbConnection;
-import org.openlcb.cdi.impl.ConfigRepresentation;
-
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.nio.charset.Charset;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-
-/**
- * Created by bracz on 4/9/16.
- */
-public class SaveConfig {
-
-
- static public void writeEntry(BufferedWriter outFile, String key, String value) {
- try {
- outFile.write(Util.escapeString(key));
- outFile.write('=');
- outFile.write(Util.escapeString(value));
- outFile.write('\n');
- } catch (IOException e1) {
- e1.printStackTrace();
- System.exit(1);
- }
- }
-
- // Main entry point
- static public void main(String[] args) {
- if (args.length != 5) {
- usage();
- return;
- }
- System.out.println("arg0: " + args[0]);
- NodeID localNode = new NodeID(args[0]);
- final String host = args[1];
- final int port = Integer.parseInt(args[2]);
- final NodeID remoteNode = new NodeID(args[3]);
- final String dstFile = args[4];
-
- final OlcbConnection connection = Util.connect(localNode, host, port);
- System.out.println("Fetching CDI.");
- ConfigRepresentation repr = connection.getConfigForNode(remoteNode);
- Util.waitForPropertyChange(repr, ConfigRepresentation.UPDATE_REP);
- System.out.println("CDI fetch done. Waiting for caches.");
- Util.waitForPropertyChange(repr, ConfigRepresentation.UPDATE_CACHE_COMPLETE);
- System.out.println("Caches complete.");
- BufferedWriter outFile = null;
-
- try {
- outFile = Files.newBufferedWriter(Paths.get(dstFile), Charset.forName("UTF-8"));
- } catch (IOException e) {
- System.err.println("Failed to create output file: " + e.toString());
- System.exit(1);
- }
- final BufferedWriter finalOutFile = outFile;
- System.out.println("Writing variables.");
- repr.visit(new ConfigRepresentation.Visitor() {
- @Override
- public void visitString(ConfigRepresentation.StringEntry e) {
- writeEntry(finalOutFile, e.key, e.getValue());
- }
-
- @Override
- public void visitInt(ConfigRepresentation.IntegerEntry e) {
- writeEntry(finalOutFile, e.key, Long.toString(e.getValue()));
- }
-
- @Override
- public void visitEvent(ConfigRepresentation.EventEntry e) {
- writeEntry(finalOutFile, e.key, Utilities.toHexDotsString(e.getValue
- ().getContents()));
- }
- }
- );
- try {
- outFile.close();
- } catch (IOException e) {
- e.printStackTrace();
- System.exit(1);
- }
- System.out.println("Done.");
- System.exit(0);
- }
-
- private static void usage() {
- String usageString = "usage: saveconfig local_node_id hub_host hub_port dst_node_id " +
- "dst_filename\n";
- System.err.print(usageString);
- }
-
-}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:20:47
|
Revision: 4178
http://sourceforge.net/p/openlcb/svn/4178
Author: bracz
Date: 2016-07-14 17:20:44 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Adds a commandline utility for restoring an entire configuration space (by variable names written by SaveConfig) into a node.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/cdi/cmd/Util.java
Added Paths:
-----------
trunk/prototypes/java/src/org/openlcb/cdi/cmd/RestoreConfig.java
Added: trunk/prototypes/java/src/org/openlcb/cdi/cmd/RestoreConfig.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/cmd/RestoreConfig.java (rev 0)
+++ trunk/prototypes/java/src/org/openlcb/cdi/cmd/RestoreConfig.java 2016-07-14 17:20:44 UTC (rev 4178)
@@ -0,0 +1,93 @@
+package org.openlcb.cdi.cmd;
+
+import org.openlcb.EventID;
+import org.openlcb.NodeID;
+import org.openlcb.Utilities;
+import org.openlcb.can.impl.OlcbConnection;
+import org.openlcb.cdi.impl.ConfigRepresentation;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+/**
+ * Created by bracz on 4/9/16.
+ */
+public class RestoreConfig {
+ // Main entry point
+ static public void main(String[] args) {
+ if (args.length != 5) {
+ usage();
+ return;
+ }
+ System.out.println("arg0: " + args[0]);
+ NodeID localNode = new NodeID(args[0]);
+ final String host = args[1];
+ final int port = Integer.parseInt(args[2]);
+ final NodeID remoteNode = new NodeID(args[3]);
+ final String srcFileName = args[4];
+
+ final OlcbConnection connection = Util.connect(localNode, host, port);
+ System.out.println("Fetching CDI.");
+ ConfigRepresentation repr = connection.getConfigForNode(remoteNode);
+ Util.waitForPropertyChange(repr, ConfigRepresentation.UPDATE_REP);
+ System.out.println("CDI fetch done. Waiting for caches.");
+ Util.waitForPropertyChange(repr, ConfigRepresentation.UPDATE_CACHE_COMPLETE);
+ System.out.println("Caches complete.");
+ BufferedReader inFile = null;
+
+ try {
+ inFile = Files.newBufferedReader(Paths.get(srcFileName), Charset.forName("UTF-8"));
+ } catch (IOException e) {
+ System.err.println("Failed to create output file: " + e.toString());
+ System.exit(1);
+ }
+ System.out.println("Writing variables to the node:");
+ String line = null;
+ try {
+ while ((line = inFile.readLine()) != null) {
+ if(line.charAt(0) == '#') continue;
+ int pos = line.indexOf('=');
+ if (pos < 0) {
+ System.out.println("Failed to parse line: " + line);
+ continue;
+ }
+ String key = Util.unescapeString(line.substring(0, pos));
+ ConfigRepresentation.CdiEntry e = repr.getVariableForKey(key);
+ if (e == null) {
+ System.out.println("Variable not found: " + key);
+ continue;
+ }
+ String value = Util.unescapeString(line.substring(pos + 1));
+ if (e instanceof ConfigRepresentation.EventEntry) {
+ ((ConfigRepresentation.EventEntry) e).setValue(new EventID(value));
+ } else if (e instanceof ConfigRepresentation.IntegerEntry) {
+ ((ConfigRepresentation.IntegerEntry) e).setValue(Long.valueOf(value));
+ } else if (e instanceof ConfigRepresentation.StringEntry) {
+ ((ConfigRepresentation.StringEntry) e).setValue(value);
+ } else {
+ System.out.println("Unknown variable type: " + e.getClass().getName() + " for" +
+ " key: " + key);
+ continue;
+ }
+ Util.waitForPropertyChange(e, ConfigRepresentation.UPDATE_WRITE_COMPLETE);
+ System.out.print(e.key + "\n"); System.out.flush();
+ }
+ } catch (IOException x) {
+ System.err.println("Error reading input file: " + x.toString());
+ System.exit(1);
+ }
+ System.out.println("Done.");
+ System.exit(0);
+ }
+
+ private static void usage() {
+ String usageString = "usage: loadconfig local_node_id hub_host hub_port dst_node_id " +
+ "src_filename\n";
+ System.err.print(usageString);
+ }
+
+}
Modified: trunk/prototypes/java/src/org/openlcb/cdi/cmd/Util.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/cmd/Util.java 2016-07-14 17:20:27 UTC (rev 4177)
+++ trunk/prototypes/java/src/org/openlcb/cdi/cmd/Util.java 2016-07-14 17:20:44 UTC (rev 4178)
@@ -100,6 +100,9 @@
if (codePoint == "=".codePointAt(0)) {
mustEscape = true;
}
+ if (codePoint == "\\".codePointAt(0)) {
+ mustEscape = true;
+ }
// Replace invisible control characters and unused code points
switch (Character.getType(codePoint))
{
@@ -123,4 +126,21 @@
}
return newString.toString();
}
+
+ static public String unescapeString(String input) {
+ StringBuffer o = new StringBuffer(input.length());
+ int pos = 0;
+ while (pos < input.length()) {
+ if (input.charAt(pos) == '\\' && (pos + 5) < input.length() && input.charAt(pos+1)
+ == 'x') {
+ int codePoint = Integer.parseInt(input.substring(pos+2, pos+6), 16);
+ o.append(Character.toChars(codePoint));
+ pos += 6;
+ } else {
+ o.append(input.charAt(pos));
+ ++pos;
+ }
+ }
+ return o.toString();
+ }
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:20:30
|
Revision: 4177
http://sourceforge.net/p/openlcb/svn/4177
Author: bracz
Date: 2016-07-14 17:20:27 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Fixes bug in datagrtammeteringbuffer that caused various datagram-related messages to be delivered doubly to the service and application layer.
Adds implementation of delayed write reply datagrams to the memory config service.
Adds workaround for recognizing out of order write reply datagrams.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/implementations/DatagramMeteringBuffer.java
trunk/prototypes/java/src/org/openlcb/implementations/MemoryConfigurationService.java
Modified: trunk/prototypes/java/src/org/openlcb/implementations/DatagramMeteringBuffer.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/implementations/DatagramMeteringBuffer.java 2016-07-14 17:20:08 UTC (rev 4176)
+++ trunk/prototypes/java/src/org/openlcb/implementations/DatagramMeteringBuffer.java 2016-07-14 17:20:27 UTC (rev 4177)
@@ -70,7 +70,9 @@
*/
@Override
public void put(Message msg, Connection sender) {
- if (currentMemo == null) return;
+ if (currentMemo == null) {
+ return;
+ }
currentMemo.put(msg, sender);
}
}
@@ -117,6 +119,8 @@
DatagramRejectedMessage msg = new DatagramRejectedMessage(message.getDestNodeID(), message.getSourceNodeID(), 0x0100);
System.out.println("Never received reply for datagram "+(message != null ? message.toString() : " == null"));
handleDatagramRejected(msg, null);
+ // Inject message to upstream listener
+ toUpstream.put(msg, toUpstream);
}
/**
@@ -127,12 +131,12 @@
// check if this is from right source & to us
if ( ! (msg.getDestNodeID()!=null && msg.getSourceNodeID()!=null && msg.getDestNodeID().equals(message.getSourceNodeID()) && message.getDestNodeID().equals(msg.getSourceNodeID()) ) ) {
// not for us, just forward
- toUpstream.put(msg, toUpstream);
+ //toUpstream.put(msg, toUpstream);
return;
}
endTimeout();
// forward message upstream
- toUpstream.put(msg, toUpstream);
+ //toUpstream.put(msg, toUpstream);
// and allow sending another
new Thread(new Consumer(queue)).start();
@@ -146,7 +150,7 @@
// check if this is from right source & to us
if ( ! (msg.getDestNodeID()!=null && msg.getSourceNodeID()!=null && msg.getDestNodeID().equals(message.getSourceNodeID()) && message.getDestNodeID().equals(msg.getSourceNodeID()) ) ) {
// not for us, just forward
- toUpstream.put(msg, toUpstream);
+ //toUpstream.put(msg, toUpstream);
return;
}
endTimeout();
@@ -155,7 +159,7 @@
forwardDownstream();
} else {
// forward upstream to originator and let them sort it out
- toUpstream.put(msg, toUpstream);
+ //toUpstream.put(msg, toUpstream);
// and allow sending another
new Thread(new Consumer(queue)).start();
}
Modified: trunk/prototypes/java/src/org/openlcb/implementations/MemoryConfigurationService.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/implementations/MemoryConfigurationService.java 2016-07-14 17:20:08 UTC (rev 4176)
+++ trunk/prototypes/java/src/org/openlcb/implementations/MemoryConfigurationService.java 2016-07-14 17:20:27 UTC (rev 4177)
@@ -7,6 +7,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
+import java.util.logging.Logger;
/**
* Service for reading and writing via the Memory Configuration protocol
@@ -21,7 +22,7 @@
* @version $Revision: -1 $
*/
public class MemoryConfigurationService {
-
+ private static final Logger logger = Logger.getLogger("MemoryConfigurationService");
private static final int DATAGRAM_TYPE = 0x20;
public static final int SPACE_CDI = 0xFF;
@@ -51,7 +52,8 @@
//
// doesn't check for match of reply to memo, but eventually should.
@Override
- public void handleData(NodeID dest, int[] data, DatagramService.ReplyMemo service) {
+ public synchronized void handleData(NodeID dest, int[] data, DatagramService.ReplyMemo
+ service) {
//log System.out.println("OLCB: handleData");
service.acceptData(0);
if (readMemo != null) {
@@ -73,7 +75,7 @@
readMemo = null;
}
memo.handleReadData(dest, memo.space, memo.address, content);
- synchronized(this) {
+ synchronized (this) {
if (readMemo == null && !pendingReads.isEmpty()) {
readMemo = pendingReads.pop();
sendRead();
@@ -106,13 +108,25 @@
configMemo = null;
memo.handleConfigData(dest, commands, options, highSpace, lowSpace, "");
}
- if (writeMemo != null) {
- // needs code to handle delayed reply
- System.err.println("MemoryConfiguration Service: Code for delayed reply not " +
- "yet present"); //log
+ if (writeMemo != null && ((data[1] & 0xF0) == 0x10)) {
McsWriteMemo memo = writeMemo;
+ long retAddress = (((long) data[2] & 0xFF) << 24) | (((long) data[3] & 0xFF)
+ << 16) | (((long) data[4] & 0xFF) << 8) | ((long) data[5] & 0xFF);
+ if (retAddress != memo.address) {
+ logger.warning("Spurious write response datagram. Requested address=" +
+ memo.address + " returned address=" + retAddress);
+ return;
+ }
writeMemo = null;
- //memo.handleConfigData(dest, commands, options, highSpace, lowSpace,"");
+ boolean spaceByte = ((data[1] & 0x03) == 0);
+ boolean failed = (data[1] & 0x08) != 0;
+ int codeOffset = 6;
+ if (spaceByte) ++codeOffset;
+ int code = failed ? 0x1000 : 0;
+ if (data.length >= codeOffset + 2) {
+ code = (data[codeOffset] << 8) + data[codeOffset + 1];
+ }
+ memo.handleWriteReply(code);
}
// dph
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:20:11
|
Revision: 4176
http://sourceforge.net/p/openlcb/svn/4176
Author: bracz
Date: 2016-07-14 17:20:08 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Adds a beans event fire for when the memory config write is completed.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java
trunk/prototypes/java/src/org/openlcb/cdi/impl/MemorySpaceCache.java
Modified: trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java 2016-07-14 17:19:46 UTC (rev 4175)
+++ trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java 2016-07-14 17:20:08 UTC (rev 4176)
@@ -20,6 +20,10 @@
import java.util.Map;
import java.util.logging.Logger;
+import javax.annotation.Nullable;
+
+import edu.umd.cs.findbugs.annotations.NonNull;
+
/**
* Maintains a parsed cache of the CDI config of a remote node. Responsible for fetching the CDI,
* parsing the XML, identifying all variables with their correct offsets and creating useful
@@ -37,6 +41,8 @@
public static final String UPDATE_CACHE_COMPLETE = "UPDATE_CACHE_COMPLETE";
// Fired on the individual internal entries when they are changed.
public static final String UPDATE_ENTRY_DATA = "UPDATE_ENTRY_DATA";
+ // Fired on an CDI entry when the write method completes.
+ public static final String UPDATE_WRITE_COMPLETE = "PENDING_WRITE_COMPLETE";
private static final String TAG = "ConfigRepresentation";
private static final Logger logger = Logger.getLogger(TAG);
private final OlcbInterface connection;
@@ -45,6 +51,7 @@
private String state = "Uninitialized";
private CdiContainer root = null;
private final Map<Integer, MemorySpaceCache> spaces = new HashMap<>();
+ private final Map<String, CdiEntry> variables = new HashMap<>();
/**
* Connects to a node, populates the cache by fetching and parsing the CDI.
@@ -106,18 +113,20 @@
};
private void prefillCaches() {
+ variables.clear();
visit(new Visitor() {
@Override
public void visitLeaf(final CdiEntry e) {
+ variables.put(e.key, e);
MemorySpaceCache cache = getCacheForSpace(e.space);
cache.addRangeToCache(e.origin, e.origin + e.size);
cache.addRangeListener(e.origin, e.origin + e.size, new
PropertyChangeListener() {
- @Override
- public void propertyChange(PropertyChangeEvent event) {
- e.firePropertyChange(UPDATE_ENTRY_DATA, null, null);
- }
- });
+ @Override
+ public void propertyChange(PropertyChangeEvent event) {
+ e.fireUpdate();
+ }
+ });
}
}
);
@@ -137,6 +146,10 @@
return root;
}
+ public @Nullable CdiEntry getVariableForKey(@NonNull String key) {
+ return variables.get(key);
+ }
+
private synchronized MemorySpaceCache getCacheForSpace(int space) {
if (spaces.containsKey(space)) {
return spaces.get(space);
@@ -277,7 +290,7 @@
* Base class for all internal representations of the nodes (both variables as well as groups
* and segments).
*/
- public abstract class CdiEntry {
+ public abstract class CdiEntry extends DefaultPropertyListenerSupport {
/// Memory space number.
public int space;
/// Address of the first byte of this item in the memory space.
@@ -287,20 +300,15 @@
/// Internal key for this variable or group
public String key;
- java.beans.PropertyChangeSupport pcs = new java.beans.PropertyChangeSupport(this);
- public synchronized void addPropertyChangeListener(java.beans.PropertyChangeListener l) {
- pcs.addPropertyChangeListener(l);
- }
+ public abstract CdiRep.Item getCdiItem();
- public synchronized void removePropertyChangeListener(java.beans.PropertyChangeListener l) {
- pcs.removePropertyChangeListener(l);
+ public void fireUpdate() {
+ firePropertyChange(UPDATE_ENTRY_DATA, null, null);
}
- protected void firePropertyChange(String p, Object old, Object n) {
- pcs.firePropertyChange(p, old, n);
+ public void fireWriteComplete() {
+ firePropertyChange(UPDATE_WRITE_COMPLETE, null, null);
}
-
- public abstract CdiRep.Item getCdiItem();
}
public class Root implements CdiContainer {
@@ -499,7 +507,7 @@
b[i] = (byte)(value & 0xff);
value >>= 8;
}
- cache.write(origin, b);
+ cache.write(origin, b, this);
}
}
@@ -533,7 +541,7 @@
MemorySpaceCache cache = getCacheForSpace(space);
byte[] b = event.getContents();
if (b == null) return;
- cache.write(origin, b);
+ cache.write(origin, b, this);
}
}
@@ -577,7 +585,7 @@
f = value.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) { return; }
System.arraycopy(f, 0, b, 0, Math.min(f.length, b.length - 1));
- cache.write(this.origin, b);
+ cache.write(this.origin, b, this);
}
}
Modified: trunk/prototypes/java/src/org/openlcb/cdi/impl/MemorySpaceCache.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/impl/MemorySpaceCache.java 2016-07-14 17:19:46 UTC (rev 4175)
+++ trunk/prototypes/java/src/org/openlcb/cdi/impl/MemorySpaceCache.java 2016-07-14 17:20:08 UTC (rev 4176)
@@ -12,6 +12,7 @@
import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;
+import java.util.logging.Logger;
/**
* Maintains the connection to a specific remote node's specific memory space, and maintains a
@@ -20,11 +21,12 @@
* Created by bracz on 4/2/16.
*/
public class MemorySpaceCache {
- private static final String TAG = "MemorySpaceCache";
// This event will be fired when the cache is completely pre-filled.
public static final String UPDATE_LOADING_COMPLETE = "UPDATE_LOADING_COMPLETE";
// This event will be fired on the registered data listeners.
public static final String UPDATE_DATA = "UPDATE_DATA";
+ private static final String TAG = "MemorySpaceCache";
+ private static final Logger logger = Logger.getLogger(TAG);
private final OlcbInterface connection;
private final NodeID remoteNodeID;
private final int space;
@@ -236,14 +238,29 @@
return ret;
}
- public void write(int offset, byte[] data) {
+ public void write(final int offset, byte[] data, final ConfigRepresentation.CdiEntry cdiEntry) {
int len = data.length;
Map.Entry<Range, byte[]> entry = getCacheForRange(offset, len);
if (entry != null && entry.getValue() != null) {
System.arraycopy(data, 0, entry.getValue(), offset - entry.getKey().start, data.length);
}
+ logger.finer("Writing to space " + space + " offset 0x" + Integer.toHexString(offset) +
+ " payload length " + data.length);
connection.getMemoryConfigurationService().request(
- new MemoryConfigurationService.McsWriteMemo(remoteNodeID, space, offset, data));
+ new MemoryConfigurationService.McsWriteMemo(remoteNodeID, space, offset, data) {
+ @Override
+ public void handleWriteReply(int code) {
+ if (code != 0) {
+ logger.warning(String.format("Write failed (space %d address %d): " +
+ "%04x", space, offset, code));
+ } else {
+ logger.finer(String.format("Write complete (space %d address %d): " +
+ "%04x", space, offset, code));
+ }
+ cdiEntry.fireWriteComplete();
+ }
+ }
+ );
// @TODO: 4/2/16 Handle write errors and report to user somehow.
notifyAfterWrite(offset, offset + data.length);
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:19:49
|
Revision: 4175
http://sourceforge.net/p/openlcb/svn/4175
Author: bracz
Date: 2016-07-14 17:19:46 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Factors out common helpers from the command executable to a utility class.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/cdi/cmd/SaveConfig.java
Added Paths:
-----------
trunk/prototypes/java/src/org/openlcb/cdi/cmd/Util.java
Modified: trunk/prototypes/java/src/org/openlcb/cdi/cmd/SaveConfig.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/cmd/SaveConfig.java 2016-07-14 17:19:28 UTC (rev 4174)
+++ trunk/prototypes/java/src/org/openlcb/cdi/cmd/SaveConfig.java 2016-07-14 17:19:46 UTC (rev 4175)
@@ -1,13 +1,10 @@
package org.openlcb.cdi.cmd;
import org.openlcb.NodeID;
-import org.openlcb.PropertyListenerSupport;
import org.openlcb.Utilities;
import org.openlcb.can.impl.OlcbConnection;
import org.openlcb.cdi.impl.ConfigRepresentation;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.charset.Charset;
@@ -20,124 +17,11 @@
public class SaveConfig {
- static void waitForPropertyChange(PropertyListenerSupport tgt, final String propertyName) {
- final Object o = new Object();
- PropertyChangeListener l = new PropertyChangeListener() {
- @Override
- public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
- if (propertyChangeEvent.getPropertyName().equals(propertyName)) {
- synchronized(o) {
- o.notify();
- }
- }
- }
- };
- tgt.addPropertyChangeListener(l);
- try {
- synchronized(o) {
- o.wait();
- }
- } catch (InterruptedException e) {
- System.err.println("Interrupted while waiting for property notification " +
- propertyName + " on object of class " + tgt.getClass().getName());
- }
- tgt.removePropertyChangeListener(l);
- }
-
- static public OlcbConnection connect(final NodeID localNode, final String host, final int
- port) {
- class Success {
- private boolean ok = false;
-
- public synchronized void set(boolean isOk) {
- ok = isOk;
- this.notify();
- }
-
- public synchronized boolean get() {
- try {
- this.wait();
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- return ok;
- }
- }
- final Success s = new Success();
-
- OlcbConnection.ConnectionListener l = new OlcbConnection
- .ConnectionListener() {
- @Override
- public void onConnect() {
- System.out.println("Connected to " + host + ":" + port);
- s.set(true);
- }
-
- @Override
- public void onDisconnect() {
- System.out.println("Disconnected.");
- s.set(false);
- }
-
- @Override
- public void onStatusChange(String status) {
- System.out.println(status);
- }
-
- @Override
- public void onConnectionPending() {
- System.out.println("Connecting.");
- }
- };
-
- OlcbConnection connection = new OlcbConnection(localNode, host, port, l);
- if (s.get()) {
- return connection;
- } else {
- System.exit(1);
- return null;
- }
- }
-
- static public String escapeString(String myString) {
- StringBuilder newString = new StringBuilder(myString.length() + 5);
- for (int offset = 0; offset < myString.length();)
- {
- int codePoint = myString.codePointAt(offset);
- offset += Character.charCount(codePoint);
- boolean mustEscape = false;
- if (codePoint == "=".codePointAt(0)) {
- mustEscape = true;
- }
- // Replace invisible control characters and unused code points
- switch (Character.getType(codePoint))
- {
- case Character.CONTROL: // \p{Cc}
- case Character.FORMAT: // \p{Cf}
- case Character.PRIVATE_USE: // \p{Co}
- case Character.SURROGATE: // \p{Cs}
- case Character.UNASSIGNED: // \p{Cn}
- newString.append("\\x");
- newString.append(String.format("%04x", codePoint));
- break;
- default:
- if (mustEscape) {
- newString.append("\\x");
- newString.append(String.format("%04x", codePoint));
- } else {
- newString.append(Character.toChars(codePoint));
- }
- break;
- }
- }
- return newString.toString();
- }
-
static public void writeEntry(BufferedWriter outFile, String key, String value) {
try {
- outFile.write(escapeString(key));
+ outFile.write(Util.escapeString(key));
outFile.write('=');
- outFile.write(escapeString(value));
+ outFile.write(Util.escapeString(value));
outFile.write('\n');
} catch (IOException e1) {
e1.printStackTrace();
@@ -158,12 +42,12 @@
final NodeID remoteNode = new NodeID(args[3]);
final String dstFile = args[4];
- final OlcbConnection connection = connect(localNode, host, port);
+ final OlcbConnection connection = Util.connect(localNode, host, port);
System.out.println("Fetching CDI.");
ConfigRepresentation repr = connection.getConfigForNode(remoteNode);
- waitForPropertyChange(repr, ConfigRepresentation.UPDATE_REP);
+ Util.waitForPropertyChange(repr, ConfigRepresentation.UPDATE_REP);
System.out.println("CDI fetch done. Waiting for caches.");
- waitForPropertyChange(repr, ConfigRepresentation.UPDATE_CACHE_COMPLETE);
+ Util.waitForPropertyChange(repr, ConfigRepresentation.UPDATE_CACHE_COMPLETE);
System.out.println("Caches complete.");
BufferedWriter outFile = null;
Copied: trunk/prototypes/java/src/org/openlcb/cdi/cmd/Util.java (from rev 4174, trunk/prototypes/java/src/org/openlcb/cdi/cmd/SaveConfig.java)
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/cmd/Util.java (rev 0)
+++ trunk/prototypes/java/src/org/openlcb/cdi/cmd/Util.java 2016-07-14 17:19:46 UTC (rev 4175)
@@ -0,0 +1,126 @@
+package org.openlcb.cdi.cmd;
+
+import org.openlcb.NodeID;
+import org.openlcb.PropertyListenerSupport;
+import org.openlcb.can.impl.OlcbConnection;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+/**
+ * Created by bracz on 4/9/16.
+ */
+public class Util {
+ static void waitForPropertyChange(PropertyListenerSupport tgt, final String propertyName) {
+ final Object o = new Object();
+ PropertyChangeListener l = new PropertyChangeListener() {
+ @Override
+ public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
+ if (propertyChangeEvent.getPropertyName().equals(propertyName)) {
+ synchronized(o) {
+ o.notify();
+ }
+ }
+ }
+ };
+ tgt.addPropertyChangeListener(l);
+ try {
+ synchronized(o) {
+ o.wait();
+ }
+ } catch (InterruptedException e) {
+ System.err.println("Interrupted while waiting for property notification " +
+ propertyName + " on object of class " + tgt.getClass().getName());
+ }
+ tgt.removePropertyChangeListener(l);
+ }
+
+ static public OlcbConnection connect(final NodeID localNode, final String host, final int
+ port) {
+ class Success {
+ private boolean ok = false;
+
+ public synchronized void set(boolean isOk) {
+ ok = isOk;
+ this.notify();
+ }
+
+ public synchronized boolean get() {
+ try {
+ this.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return ok;
+ }
+ }
+ final Success s = new Success();
+
+ OlcbConnection.ConnectionListener l = new OlcbConnection
+ .ConnectionListener() {
+ @Override
+ public void onConnect() {
+ System.out.println("Connected to " + host + ":" + port);
+ s.set(true);
+ }
+
+ @Override
+ public void onDisconnect() {
+ System.out.println("Disconnected.");
+ s.set(false);
+ }
+
+ @Override
+ public void onStatusChange(String status) {
+ System.out.println(status);
+ }
+
+ @Override
+ public void onConnectionPending() {
+ System.out.println("Connecting.");
+ }
+ };
+
+ OlcbConnection connection = new OlcbConnection(localNode, host, port, l);
+ if (s.get()) {
+ return connection;
+ } else {
+ System.exit(1);
+ return null;
+ }
+ }
+
+ static public String escapeString(String myString) {
+ StringBuilder newString = new StringBuilder(myString.length() + 5);
+ for (int offset = 0; offset < myString.length();)
+ {
+ int codePoint = myString.codePointAt(offset);
+ offset += Character.charCount(codePoint);
+ boolean mustEscape = false;
+ if (codePoint == "=".codePointAt(0)) {
+ mustEscape = true;
+ }
+ // Replace invisible control characters and unused code points
+ switch (Character.getType(codePoint))
+ {
+ case Character.CONTROL: // \p{Cc}
+ case Character.FORMAT: // \p{Cf}
+ case Character.PRIVATE_USE: // \p{Co}
+ case Character.SURROGATE: // \p{Cs}
+ case Character.UNASSIGNED: // \p{Cn}
+ newString.append("\\x");
+ newString.append(String.format("%04x", codePoint));
+ break;
+ default:
+ if (mustEscape) {
+ newString.append("\\x");
+ newString.append(String.format("%04x", codePoint));
+ } else {
+ newString.append(Character.toChars(codePoint));
+ }
+ break;
+ }
+ }
+ return newString.toString();
+ }
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:19:30
|
Revision: 4174
http://sourceforge.net/p/openlcb/svn/4174
Author: bracz
Date: 2016-07-14 17:19:28 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Adds an escape option for CDI variable keys in the ConfigRepresentation which uses the index in the JDOM parent as key when a name is not present.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/cdi/CdiRep.java
trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java
trunk/prototypes/java/src/org/openlcb/cdi/jdom/JdomCdiRep.java
Modified: trunk/prototypes/java/src/org/openlcb/cdi/CdiRep.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/CdiRep.java 2016-07-14 17:19:10 UTC (rev 4173)
+++ trunk/prototypes/java/src/org/openlcb/cdi/CdiRep.java 2016-07-14 17:19:28 UTC (rev 4174)
@@ -31,6 +31,7 @@
public String getName();
public String getDescription();
public Map getMap();
+ public int getIndexInParent();
}
public static interface Item {
@@ -38,6 +39,7 @@
public String getDescription();
public Map getMap();
public int getOffset();
+ public int getIndexInParent();
}
public static interface Group extends Item {
Modified: trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java 2016-07-14 17:19:10 UTC (rev 4173)
+++ trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java 2016-07-14 17:19:28 UTC (rev 4174)
@@ -174,7 +174,11 @@
origin = origin + it.getOffset();
CdiEntry entry = null;
- String name = baseName + "." + it.getName();
+ String entryName = it.getName();
+ if (entryName == null) {
+ entryName = "child" + it.getIndexInParent();
+ }
+ String name = baseName + "." + entryName;
if (it instanceof CdiRep.Group) {
entry = new GroupEntry(name, (CdiRep.Group) it, segment, origin);
} else if (it instanceof CdiRep.IntegerRep) {
@@ -333,6 +337,9 @@
this.segment = segment;
this.items = new ArrayList<>();
this.key = getName();
+ if (key == null) {
+ key = "seg" + segment.getIndexInParent();
+ }
this.origin = segment.getOrigin();
this.space = segment.getSpace();
this.size = processGroup(key, this.space, segment.getItems(), this.items, this.origin);
@@ -367,6 +374,11 @@
public int getOffset() {
return segment.getOrigin();
}
+
+ @Override
+ public int getIndexInParent() {
+ return segment.getIndexInParent();
+ }
}
/**
Modified: trunk/prototypes/java/src/org/openlcb/cdi/jdom/JdomCdiRep.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/jdom/JdomCdiRep.java 2016-07-14 17:19:10 UTC (rev 4173)
+++ trunk/prototypes/java/src/org/openlcb/cdi/jdom/JdomCdiRep.java 2016-07-14 17:19:28 UTC (rev 4174)
@@ -104,7 +104,11 @@
}
return list;
}
-
+
+ public int getIndexInParent() {
+ return e.getParent().indexOf(e);
+ }
+
Nested(Element e) { this.e = e; }
Element e;
}
@@ -214,6 +218,12 @@
else return a.getIntValue();
} catch (org.jdom2.DataConversionException e) { return 0; }
}
+
+ @Override
+ public int getIndexInParent() {
+ return e.getParent().indexOf(e);
+ }
+
}
public static class Group extends Nested implements CdiRep.Group {
@@ -236,7 +246,7 @@
else return a.getIntValue();
} catch (org.jdom2.DataConversionException e1) { return 0; }
}
-
+
@Override
public String getRepName() {
Element d = e.getChild("repname");
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:19:12
|
Revision: 4173
http://sourceforge.net/p/openlcb/svn/4173
Author: bracz
Date: 2016-07-14 17:19:10 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Adds a commandline binary that dumps all configuration variables from a node.
Added Paths:
-----------
trunk/prototypes/java/src/org/openlcb/cdi/cmd/
trunk/prototypes/java/src/org/openlcb/cdi/cmd/SaveConfig.java
Added: trunk/prototypes/java/src/org/openlcb/cdi/cmd/SaveConfig.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/cmd/SaveConfig.java (rev 0)
+++ trunk/prototypes/java/src/org/openlcb/cdi/cmd/SaveConfig.java 2016-07-14 17:19:10 UTC (rev 4173)
@@ -0,0 +1,212 @@
+package org.openlcb.cdi.cmd;
+
+import org.openlcb.NodeID;
+import org.openlcb.PropertyListenerSupport;
+import org.openlcb.Utilities;
+import org.openlcb.can.impl.OlcbConnection;
+import org.openlcb.cdi.impl.ConfigRepresentation;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+/**
+ * Created by bracz on 4/9/16.
+ */
+public class SaveConfig {
+
+
+ static void waitForPropertyChange(PropertyListenerSupport tgt, final String propertyName) {
+ final Object o = new Object();
+ PropertyChangeListener l = new PropertyChangeListener() {
+ @Override
+ public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
+ if (propertyChangeEvent.getPropertyName().equals(propertyName)) {
+ synchronized(o) {
+ o.notify();
+ }
+ }
+ }
+ };
+ tgt.addPropertyChangeListener(l);
+ try {
+ synchronized(o) {
+ o.wait();
+ }
+ } catch (InterruptedException e) {
+ System.err.println("Interrupted while waiting for property notification " +
+ propertyName + " on object of class " + tgt.getClass().getName());
+ }
+ tgt.removePropertyChangeListener(l);
+ }
+
+ static public OlcbConnection connect(final NodeID localNode, final String host, final int
+ port) {
+ class Success {
+ private boolean ok = false;
+
+ public synchronized void set(boolean isOk) {
+ ok = isOk;
+ this.notify();
+ }
+
+ public synchronized boolean get() {
+ try {
+ this.wait();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return ok;
+ }
+ }
+ final Success s = new Success();
+
+ OlcbConnection.ConnectionListener l = new OlcbConnection
+ .ConnectionListener() {
+ @Override
+ public void onConnect() {
+ System.out.println("Connected to " + host + ":" + port);
+ s.set(true);
+ }
+
+ @Override
+ public void onDisconnect() {
+ System.out.println("Disconnected.");
+ s.set(false);
+ }
+
+ @Override
+ public void onStatusChange(String status) {
+ System.out.println(status);
+ }
+
+ @Override
+ public void onConnectionPending() {
+ System.out.println("Connecting.");
+ }
+ };
+
+ OlcbConnection connection = new OlcbConnection(localNode, host, port, l);
+ if (s.get()) {
+ return connection;
+ } else {
+ System.exit(1);
+ return null;
+ }
+ }
+
+ static public String escapeString(String myString) {
+ StringBuilder newString = new StringBuilder(myString.length() + 5);
+ for (int offset = 0; offset < myString.length();)
+ {
+ int codePoint = myString.codePointAt(offset);
+ offset += Character.charCount(codePoint);
+ boolean mustEscape = false;
+ if (codePoint == "=".codePointAt(0)) {
+ mustEscape = true;
+ }
+ // Replace invisible control characters and unused code points
+ switch (Character.getType(codePoint))
+ {
+ case Character.CONTROL: // \p{Cc}
+ case Character.FORMAT: // \p{Cf}
+ case Character.PRIVATE_USE: // \p{Co}
+ case Character.SURROGATE: // \p{Cs}
+ case Character.UNASSIGNED: // \p{Cn}
+ newString.append("\\x");
+ newString.append(String.format("%04x", codePoint));
+ break;
+ default:
+ if (mustEscape) {
+ newString.append("\\x");
+ newString.append(String.format("%04x", codePoint));
+ } else {
+ newString.append(Character.toChars(codePoint));
+ }
+ break;
+ }
+ }
+ return newString.toString();
+ }
+
+ static public void writeEntry(BufferedWriter outFile, String key, String value) {
+ try {
+ outFile.write(escapeString(key));
+ outFile.write('=');
+ outFile.write(escapeString(value));
+ outFile.write('\n');
+ } catch (IOException e1) {
+ e1.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ // Main entry point
+ static public void main(String[] args) {
+ if (args.length != 5) {
+ usage();
+ return;
+ }
+ System.out.println("arg0: " + args[0]);
+ NodeID localNode = new NodeID(args[0]);
+ final String host = args[1];
+ final int port = Integer.parseInt(args[2]);
+ final NodeID remoteNode = new NodeID(args[3]);
+ final String dstFile = args[4];
+
+ final OlcbConnection connection = connect(localNode, host, port);
+ System.out.println("Fetching CDI.");
+ ConfigRepresentation repr = connection.getConfigForNode(remoteNode);
+ waitForPropertyChange(repr, ConfigRepresentation.UPDATE_REP);
+ System.out.println("CDI fetch done. Waiting for caches.");
+ waitForPropertyChange(repr, ConfigRepresentation.UPDATE_CACHE_COMPLETE);
+ System.out.println("Caches complete.");
+ BufferedWriter outFile = null;
+
+ try {
+ outFile = Files.newBufferedWriter(Paths.get(dstFile), Charset.forName("UTF-8"));
+ } catch (IOException e) {
+ System.err.println("Failed to create output file: " + e.toString());
+ System.exit(1);
+ }
+ final BufferedWriter finalOutFile = outFile;
+ System.out.println("Writing variables.");
+ repr.visit(new ConfigRepresentation.Visitor() {
+ @Override
+ public void visitString(ConfigRepresentation.StringEntry e) {
+ writeEntry(finalOutFile, e.key, e.getValue());
+ }
+
+ @Override
+ public void visitInt(ConfigRepresentation.IntegerEntry e) {
+ writeEntry(finalOutFile, e.key, Long.toString(e.getValue()));
+ }
+
+ @Override
+ public void visitEvent(ConfigRepresentation.EventEntry e) {
+ writeEntry(finalOutFile, e.key, Utilities.toHexDotsString(e.getValue
+ ().getContents()));
+ }
+ }
+ );
+ try {
+ outFile.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ System.exit(1);
+ }
+ System.out.println("Done.");
+ System.exit(0);
+ }
+
+ private static void usage() {
+ String usageString = "usage: saveconfig local_node_id hub_host hub_port dst_node_id " +
+ "dst_filename\n";
+ System.err.print(usageString);
+ }
+
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-07-14 17:18:49
|
Revision: 4172
http://sourceforge.net/p/openlcb/svn/4172
Author: bracz
Date: 2016-07-14 17:18:47 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Adds a beans listener for the config representation cache update ready event.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java
trunk/prototypes/java/src/org/openlcb/cdi/impl/MemorySpaceCache.java
Modified: trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java 2016-07-14 17:18:26 UTC (rev 4171)
+++ trunk/prototypes/java/src/org/openlcb/cdi/impl/ConfigRepresentation.java 2016-07-14 17:18:47 UTC (rev 4172)
@@ -3,6 +3,7 @@
import org.openlcb.EventID;
import org.openlcb.NodeID;
import org.openlcb.OlcbInterface;
+import org.openlcb.DefaultPropertyListenerSupport;
import org.openlcb.cdi.CdiRep;
import org.openlcb.cdi.jdom.CdiMemConfigReader;
import org.openlcb.cdi.jdom.JdomCdiReader;
@@ -27,15 +28,19 @@
*
* Created by bracz on 3/29/16.
*/
-public class ConfigRepresentation {
+public class ConfigRepresentation extends DefaultPropertyListenerSupport {
+ // Fires when the loading state changes.
public static final String UPDATE_STATE = "UPDATE_STATE";
+ // Fired when the CDI is loaded and the representation is ready.
public static final String UPDATE_REP = "UPDATE_REP";
+ // Fired when all the caches have been pre-filled.
+ public static final String UPDATE_CACHE_COMPLETE = "UPDATE_CACHE_COMPLETE";
+ // Fired on the individual internal entries when they are changed.
public static final String UPDATE_ENTRY_DATA = "UPDATE_ENTRY_DATA";
private static final String TAG = "ConfigRepresentation";
private static final Logger logger = Logger.getLogger(TAG);
private final OlcbInterface connection;
private final NodeID remoteNodeID;
- java.beans.PropertyChangeSupport pcs = new java.beans.PropertyChangeSupport(this);
private CdiRep cdiRep;
private String state = "Uninitialized";
private CdiContainer root = null;
@@ -82,6 +87,24 @@
firePropertyChange(UPDATE_REP, null, root);
}
+ int pendingCacheFills = 0;
+ PropertyChangeListener prefillListener = new PropertyChangeListener() {
+ @Override
+ public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
+ if (propertyChangeEvent.getPropertyName().equals(MemorySpaceCache
+ .UPDATE_LOADING_COMPLETE)) {
+ synchronized (this) {
+ if (--pendingCacheFills == 0) {
+ firePropertyChange(UPDATE_CACHE_COMPLETE, null, null);
+ for (MemorySpaceCache sp : spaces.values()) {
+ sp.removePropertyChangeListener(prefillListener);
+ }
+ }
+ }
+ }
+ }
+ };
+
private void prefillCaches() {
visit(new Visitor() {
@Override
@@ -98,7 +121,9 @@
}
}
);
+ pendingCacheFills = spaces.size();
for (MemorySpaceCache sp : spaces.values()) {
+ sp.addPropertyChangeListener(prefillListener);
// This will send off the first read, then continue asynchronously.
sp.fillCache();
}
@@ -174,18 +199,6 @@
firePropertyChange(UPDATE_STATE, null, this.state);
}
- public synchronized void addPropertyChangeListener(java.beans.PropertyChangeListener l) {
- pcs.addPropertyChangeListener(l);
- }
-
- public synchronized void removePropertyChangeListener(java.beans.PropertyChangeListener l) {
- pcs.removePropertyChangeListener(l);
- }
-
- protected void firePropertyChange(String p, Object old, Object n) {
- pcs.firePropertyChange(p, old, n);
- }
-
public String getStatus() {
return state;
}
Modified: trunk/prototypes/java/src/org/openlcb/cdi/impl/MemorySpaceCache.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/cdi/impl/MemorySpaceCache.java 2016-07-14 17:18:26 UTC (rev 4171)
+++ trunk/prototypes/java/src/org/openlcb/cdi/impl/MemorySpaceCache.java 2016-07-14 17:18:47 UTC (rev 4172)
@@ -22,9 +22,9 @@
public class MemorySpaceCache {
private static final String TAG = "MemorySpaceCache";
// This event will be fired when the cache is completely pre-filled.
- private static final String UPDATE_LOADING_COMPLETE = "UPDATE_LOADING_COMPLETE";
+ public static final String UPDATE_LOADING_COMPLETE = "UPDATE_LOADING_COMPLETE";
// This event will be fired on the registered data listeners.
- private static final String UPDATE_DATA = "UPDATE_DATA";
+ public static final String UPDATE_DATA = "UPDATE_DATA";
private final OlcbInterface connection;
private final NodeID remoteNodeID;
private final int space;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|