|
From: <dph...@us...> - 2016-01-19 22:29:05
|
Revision: 4003
http://sourceforge.net/p/openlcb/svn/4003
Author: dpharris
Date: 2016-01-19 22:28:40 +0000 (Tue, 19 Jan 2016)
Log Message:
-----------
Loader trial code
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/DatagramMessage.java
trunk/prototypes/java/src/org/openlcb/StreamDataSendMessage.java
trunk/prototypes/java/src/org/openlcb/implementations/MemoryConfigurationService.java
trunk/prototypes/java/src/org/openlcb/implementations/StreamTransmitter.java
trunk/prototypes/java/test/org/openlcb/PackageTest.java
Added Paths:
-----------
trunk/prototypes/java/src/org/openlcb/LoaderClient.java
trunk/prototypes/java/test/org/openlcb/LoaderClientTest.java
trunk/prototypes/java/test/org/openlcb/README
Removed Paths:
-------------
trunk/prototypes/java/src/org/openlcb/LoaderClient.txt
Modified: trunk/prototypes/java/src/org/openlcb/DatagramMessage.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/DatagramMessage.java 2016-01-19 17:20:42 UTC (rev 4002)
+++ trunk/prototypes/java/src/org/openlcb/DatagramMessage.java 2016-01-19 22:28:40 UTC (rev 4003)
@@ -85,7 +85,7 @@
@Override
public String toString() {
StringBuilder value = new StringBuilder(super.toString());
- value.append(" Datagram: ");
+ value.append(" Datagram: ");
int n = getData().length;
boolean first = true;
Copied: trunk/prototypes/java/src/org/openlcb/LoaderClient.java (from rev 3979, trunk/prototypes/java/src/org/openlcb/LoaderClient.txt)
===================================================================
--- trunk/prototypes/java/src/org/openlcb/LoaderClient.java (rev 0)
+++ trunk/prototypes/java/src/org/openlcb/LoaderClient.java 2016-01-19 22:28:40 UTC (rev 4003)
@@ -0,0 +1,262 @@
+package org.openlcb;
+
+import org.openlcb.*;
+import org.openlcb.implementations.*;
+import org.openlcb.implementations.DatagramService.*;
+import org.openlcb.implementations.MemoryConfigurationService.*;
+import org.openlcb.implementations.StreamTransmitter.*;
+import org.openlcb.implementations.DatagramTransmitter.*;
+import org.openlcb.ProtocolIdentificationReplyMessage;
+import org.openlcb.StreamInitiateReplyMessage;
+
+//import org.slf4j.Logger;
+//import org.slf4j.LoggerFactory;
+
+//
+// LoaderClient.java
+//
+//
+// Created by David on 2015-12-29.
+//
+//
+
+//#include "LoaderClient.hpp"
+
+public class LoaderClient extends MessageDecoder {
+ enum State { IDLE, ABORT, FREEZE, INITCOMPL, PIP, SETUPSTREAM, STREAM, STREAMDATA, DG, UNFREEEZE, SUCCESS, FAIL };
+ Connection connection;
+ MemoryConfigurationService mcs;
+ DatagramService dcs;
+ MimicNodeStore store;
+
+ State state;
+ NodeID src;
+ NodeID dest;
+ int space;
+ long address;
+ byte[] content;
+ LoaderStatusReporter feedback;
+
+ public abstract class LoaderStatusReporter {
+ public abstract void onProgress(float percent);
+ public abstract void onDone(int errorCode, String errorString);
+ }
+
+ public LoaderClient(NodeID _src, NodeID _dest, int _space, long _address, byte[] _content, LoaderStatusReporter _feedback, Connection _connection, MemoryConfigurationService _mcs, DatagramService _dcs ) {
+ src = _src;
+ dest = _dest;
+ space = _space;
+ address = _address;
+ content = _content.clone();
+ // System.out.println("LoaderClient: content="+content);
+ feedback = _feedback;
+ connection = _connection;
+ //dcs = new DatagramService(src, connection);
+ //mcs = new MemoryConfigurationService(src, dcs);
+ dcs = _dcs;
+ mcs = _mcs;
+ }
+
+ /* Protocol:
+ ---> memconfig Freeze (DG)
+ (<--- DG ok) -- node may reboot, and not be able to garantee this
+ <--- InitComplete
+ ---> PIPRequest
+ <--- PIPReply
+ IF streams implemented then use one:
+ ---> memconfig write stream request (DG)
+ <--- DG ok
+ <--- memconfig write stream reply (DG)
+ ---> DG ok
+ ---> StreamInitRequest
+ <--- StreamInitReply
+ ---> StreamDataSend
+ ...
+ ---> StreamDataComplete
+ ELSE use datagrams:
+ ---> DatagramMessage
+ <--- DatagramAcknowledged
+ ...
+ ---> [stop sending data when run out of buffer]
+ <--- stream data proceed
+ ...
+ <--- DatagramAcknowledged
+ THEN:
+ ---> UnFreeze
+
+ */
+
+
+ public void doLoad() {
+ state = State.FREEZE;
+ sendFreeze(); // allow restarts
+ }
+
+ final int DG_OK = 0x0000; // double check these
+ final int DG_FAIL = 0x0100; // note that this value is used in DGMeteringBuffer to denote time-out
+ final int DG_RESEND = 0x0200;
+ void sendFreeze() {
+ // System.out.println("lSendFreeze ");
+ //DatagramTransmitter d0 = new DatagramTransmitter(src, dest, new int[]{0x20, 0xA1, space}, connection);
+
+ dcs.sendData(
+ new DatagramService.DatagramServiceTransmitMemo(dest, new int[]{0x20, 0xA1, space}) {
+ @Override
+ public void handleReply(int code) {
+ // System.out.println("Freeze handleReply: ");
+ if((state==State.FREEZE)) {
+ if(code==DG_OK) { state = State.INITCOMPL; } // DG ok
+ else if(code==DG_FAIL) { state = State.INITCOMPL; } // DG timed out, but ok timeouts
+ //else if((code&DG_RESEND)!=0) { state = State.FREEZE; } // resend ok, so start again
+ else state = State.FAIL; // Apparently this node doesn't handle DGs
+ } else state = State.FAIL;
+ }
+ });
+ }
+ @Override
+ public void handleInitializationComplete(InitializationCompleteMessage msg, Connection sender){
+ // System.out.println("lhandleInitializationComplete");
+ if (state == State.FREEZE && msg.getSourceNodeID().equals(dest)) { state = State.PIP; sendPipRequest(); }
+ if (state == State.INITCOMPL && msg.getSourceNodeID().equals(dest)) { state = State.PIP; sendPipRequest(); }
+ }
+ void sendPipRequest() {
+ // System.out.println("lSendPipRequest ");
+ Message msg = new ProtocolIdentificationRequestMessage(src, dest);
+ connection.put(msg, this);
+ //state = PIPREPLY;
+ }
+ @Override
+ public void handleProtocolIdentificationReply(ProtocolIdentificationReplyMessage msg, Connection sender){
+ // System.out.println("lhandleProtocolIdentificationReply");
+ int retries = 0;
+ if (state == State.PIP && msg.getSourceNodeID().equals(dest)) {
+ if((msg.getValue()&0x00200000)!=0) {
+ state=State.FAIL;
+ feedback.onDone(0, "Loader: Target node should not be in Operating state.");
+ }
+ else if((msg.getValue()&0x00100000)==0) {
+ state=State.FAIL; // not in FirmwareUpgrade Operating state
+ feedback.onDone(0, "Loader: Target node is not in Firmware Upgrade state.");
+ }
+ else if((msg.getValue()&0x20000000)!=0) {
+ state = State.SETUPSTREAM;
+ setupStream();
+ } else if((msg.getValue()&0x40000000)!=0) {
+ state = State.DG;
+ //feedback.onDone(0, "BollicksDG!?");
+ sendDGs();
+ } else {
+ state = State.FAIL;
+ feedback.onDone(0, "Loader: Target node does not support Streams nor Datagram!?");
+ }
+ }
+ }
+
+ int bufferSize; // chunk size
+ int startaddr;
+ int endaddr;
+ int totalmsgs;
+ int sentmsgs;
+ int location;
+ int nextIndex;
+ float progress;
+
+ byte destStreamID;
+ byte sourceStreamID = 4; // notional value
+
+ void setupStream() {
+ // System.out.println("lSetup Stream ");
+ bufferSize = 64;
+ state = State.STREAM;
+
+ mcs.request(new McsWriteStreamMemo(dest, space, address) {
+ @Override
+ public void handleWriteReply(int code) {
+ // System.out.println("Reply mcs.request McsWriteStreamMemo handleWriteReply: ");
+ sendStream();
+ }
+ });
+ }
+
+ void sendStream() {
+ // System.out.println("lSend Stream ");
+ StreamInitiateRequestMessage m = new StreamInitiateRequestMessage(src, dest, bufferSize, sourceStreamID, destStreamID);
+ connection.put(m, this);
+ }
+
+ void handleStreamDataCompleteMessage() {
+ // System.out.println("l>>>handleStreamDataCompleteMessage");
+ }
+
+ public void handleStreamInitiateReply(StreamInitiateReplyMessage msg, Connection sender){
+ // System.out.println("handleStreamInitiateReply ");
+ // pick up buffer size to use
+ if(state==State.STREAM && sourceStreamID==msg.getSourceStreamID()) {
+ this.bufferSize = msg.getBufferSize();
+ this.destStreamID = msg.getDestinationStreamID();
+ // init transfer
+ nextIndex = 0;
+ // send data
+ state=State.STREAMDATA;
+ // System.out.println("Stream proceed ");
+ sendStreamNext();
+ }
+ }
+ public void sendStreamNext() {
+ int size = Math.min(bufferSize, content.length-nextIndex);
+ byte[] data = new byte[size];
+ // copy the needed data
+ for (int i=0; i<size; i++) data[i] = content[nextIndex+i];
+ nextIndex = nextIndex+size;
+ // System.out.println("\nsendStreamNext: "+data);
+ Message m = new StreamDataSendMessage(src, dest, data, destStreamID);
+ connection.put(m, this);
+ // are we done?
+ if (nextIndex < content.length) return; // wait for Data Proceed message
+ // yes, say we're done
+ m = new StreamDataCompleteMessage(src, dest, sourceStreamID, destStreamID);
+ connection.put(m, this);
+ sendUnfreeze();
+ state = State.SUCCESS;
+ }
+ public void handleStreamDataProceed(StreamDataProceedMessage msg, Connection sender){
+ // System.out.println("handleStreamDataProceed");
+ sendStreamNext();
+ }
+
+ void sendDGs() {
+ // System.out.println("\nlsendDGs: ");
+ nextIndex = 0;
+ bufferSize = 8;
+ sendDGNext();
+ }
+ void sendDGNext() {
+ int size = Math.min(bufferSize, content.length-nextIndex);
+ // System.out.println("lbufferSize: "+bufferSize);
+ // System.out.println("lsize: "+size);
+ int[] data = new int[size];
+ // copy the needed data
+ for (int i=0; i<size; i++) data[i] = content[nextIndex+i];
+ nextIndex = nextIndex+size;
+ dcs.sendData(new DatagramService.DatagramServiceTransmitMemo(dest, data) {
+ @Override
+ public void handleReply(int code) {
+ // System.out.println("lDG handleReply");
+ sendDGNext();
+ }
+ });
+ // are we done?
+ if( nextIndex < content.length ) return;
+ sendUnfreeze();
+ state = State.SUCCESS;
+
+ }
+
+ void sendUnfreeze() {
+ // System.out.println("lsendUnfreeze");
+ dcs.sendData(new DatagramService.DatagramServiceTransmitMemo(dest, new int[]{0x20, 0xA0, space}) {
+ public void handleReply(int code) {
+ }
+ });
+ }
+}
\ No newline at end of file
Deleted: trunk/prototypes/java/src/org/openlcb/LoaderClient.txt
===================================================================
--- trunk/prototypes/java/src/org/openlcb/LoaderClient.txt 2016-01-19 17:20:42 UTC (rev 4002)
+++ trunk/prototypes/java/src/org/openlcb/LoaderClient.txt 2016-01-19 22:28:40 UTC (rev 4003)
@@ -1,275 +0,0 @@
-//
-// LoaderClient.java
-//
-//
-// Created by David on 2015-12-29.
-//
-//
-
-#include "LoaderClient.hpp"
-
-public class LoaderClient extends MessageDecoder {
- enum state = { IDLE, ABORT, FREEZE, INITCOMPL, PIP, SETUPSTREAM, STREAM, STREAMDATA, DG, UNFREEEZE, SUCCESS, FAIL };
- NodeID dest;
- int space;
- long address;
- byte[] content
- public abstract class LoaderStatusReporter {
- public abstract void onProgress(float percent);
- public abstract void onDone(int errorCode, String errorString);
- }
-
- public LoaderClient(NodeID _dest, int _space, long _address, MemoryContents inputContent, LoaderStatusReporter _feedback) {
- dest = _dest;
- space = _space;
- address = _address;
- feedback = _feedback;
- }
-
- /* Protocol:
- ---> memconfig Freeze (DG)
- (<--- DG ok) -- node may reboot, and not be able to garantee this
- <--- InitComplete
- ---> PIPRequest
- <--- PIPReply
- IF streams implemented then use one:
- ---> memconfig write stream request (DG)
- <--- DG ok
- <--- memconfig write stream reply (DG)
- ---> DG ok
- ---> StreamInitRequest
- <--- StreamInitReply
- ---> StreamDataSend
- ...
- ---> StreamDataComplete
- ELSE use datagrams:
- ---> DatagramMessage
- <--- DatagramAcknowledged
- ...
- ---> [stop sending data when run out of buffer]
- <--- stream data proceed
- ...
- <--- DatagramAcknowledged
- THEN:
- ---> UnFreeze
-
- */
-
-
- public boolean doLoad() {
- log.info("LoaderClient: Freeze reply");
- state = FREEZE;
- sendFreeze(); // allow restarts
- }
-
- final int DG_OK 0x000; // double check these
- final int DG_FAIL 0x100; // note that this value is used in DGMeteringBuffer to denote time-out
- final int DG_RESEND 0x200;
- void sendFreeze() {
- dcs.sendData(new DatagramService.DatagramServiceTransmitMemo(destNodeID(),{0x20, 0xA1, space}) {
- public void handleReply(int code) {
- // super handleReply(code); // is this needed?
- log.info("LoaderClient: Freeze reply");
- log.debug("LoaderClient: Start of handleFreezeReply "+code);
- if((state==FREEZE)) {
- if(code==DG_OK) { state = INITCOMPL; } // DG ok
- else if(code==DG_FAIL) { state = INITCOMPL; } // DG timed out, but ok timeouts
- else if(code&&DG_RESEND) { state = FREEZE; } // resend ok, so start again
- else state = FAIL; // Apparently this node doesn't handle DGs
- } else state = FAIL;
- }
- });
- }
- @Override
- public void handleInitializationComplete(InitializationCompleteMessage msg, Connection sender){
- log.debug("LoaderClient: handleInitializationComplete");
- if (state == INITCOMPL && msg.source().equals(destNodeID())) { state = PIP; sendPipRequest(); }
- }
- void sendPipRequest() {
- log.debug("LoaderClient: PIPRequestMessage");
- Message msg = new PIPRequestMessage(destNodeID());
- connection.put(msg, this);
- //state = PIPREPLY;
- }
- @Override
- public void handlePipReply(PipReplyMessage msg, Connection sender){
- log.debug("LoaderClient: handlePipReply");
- int retries = 0;
- if (state == PIP && msg.source().equals(destNodeID())) {
- if(msg.data[2]&0x20) {
- state=FAIL;
- onDone(FAIL, "Target node should not be in Operating state.");
- }
- else if(!(msg.data[2]&0x10)) {
- state=FAIL; // not in FirmwareUpgrade Operating state
- onDone(FAIL, "Target node is not in Firmware Upgrade state.");
- }
- else if(msg.data[0]&0x20) {
- state = SETUPSTREAM;
- setupStream();
- } else if(msg.data[0]&0x40) {
- state = DG;
- sendDG();
- } else {
- state = FAIL;
- onDone(FAIL, "Target node does not support Streams nor Datagram!?");
- }
- }
- }
- void setupStream() {
- log.debug("LoaderClient: MemConfigWriteStreamRequest");
- mcs.Write
-
-
- /*
- byte[] cmd = { 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, space }; // write stream altspace start(4) space
- dcs.sendData(new DatagramService.DatagramServiceTransmitMemo(destNodeID(), cmd) {
- public void handleReply(int code) {
- log.debug("LoaderClient: MemConfigWriteStreamRequest "+code);
- log.info("LoaderClient: MemConfigWriteStreamRequest reply");
- if((state==SETUPSTREAM)) {
- if(code==DG_OK) { state = INITCOMPL; } // DG ok
- else {
- state = FAIL;
- onDone(FAIL, "MemConfigWriteStreamRequest failed.");
- }
- } else {
- state = FAIL;
- onDone(FAIL, "We got lost 1.");
- }
- }
- });
- */
- }
-
- int bufferSize; // chunk size
- int startaddr;
- int endaddr;
- int totalmsgs;
- int sentmsgs;
- int location;
- float progress;
-
- int destStreamID;
- int sourceStreamID = 4; // notional value
- void sendStream() {
- log.debug("LoaderClient: sendStream");
- // not implemented yet
- state = FAIL;
- StreamInitRequestMessage m = new StreamInitRequestMessage(here, destNodeID(), bufferSize, sourceStreamID);
- connection.put(m, this);
- }
- public void handleStreamInitReply(StreamInitReplyMessage msg, Connection sender){
- log.debug("LoaderClient: handleStreamInitReply");
- // pick up buffer size to use
- if(state==STREAM && sourceStreamID==msg.getSourceStreamID) {
- this.bufferSize = msg.getBufferSize();
- this.destStreamID = msg.getDestStreamID();
- // init transfer
- nextIndex = 0;
- // send data
- state=STREAMDATA;
- sendStreamNext();
- }
- }
- public void sendStreamNext() {
- log.debug("LoaderClient: sendStreamNext");
- int size = Math.min(bufferSize, bytes.length-nextIndex);
- int[] data = new int[size];
- // copy the needed data
- for (int i=0; i<size; i++) data[i] = bytes[nextIndex+i];
- nextIndex = nextIndex+size;
- // send data
- log.debug("LoaderClient: StreamDataSendMessage");
- Message m = new StreamDataSendMessage(here, destNodeID(), data, destStreamID);
- connection.put(m, this);
- // are we done?
- if (nextIndex < bytes.length) return; // wait for Data Proceed message
- // yes, say we're done
- log.debug("LoaderClient: StreamDataCompleteMessage");
- m = new StreamDataCompleteMessage(here, far, sourceStreamID, destStreamID);
- connection.put(m, this);
- log.info(" LoaderClient: Streaming Download completed normally");
- state = SUCCESS;
- }
- public void handleStreamDataProceed(StreamDataProceedMessage msg, Connection sender){
- sendStreamNext();
- }
-
- void sendDGSequence() {
- log.debug("LoaderClient: sendDGSequence");
- bufferSize = 64;
- startaddr = 0x000000;
- endaddr = 0xFFFFFF;
- // fast scan to count messages to send for progress bar
- location = inputContent.nextContent(startaddr);
- totalmsgs = 0;
- sentmsgs = 0;
- do {
- // we're assuming that data is pretty dense,
- // so we can jump through in bufferSize-sized chunks
- location = location + bufferSize;
- totalmsgs++;
- // update to the next location for data
- int next = inputContent.nextContent(location);
- if (next < 0) { break; } // no data left
- location = next;
- } while (location <= endaddr);
- log.info("LoaderClient: Expect downloading to send {} write messages", totalmsgs);
-
- // Start write sequence:
- // find the initial location with data
- location = inputContent.nextContent(startaddr);
- sendDGNext();
- }
-
- sendDGNext() {
- log.debug("LoaderClient: sendDGNext");
- SwingUtilities.invokeLater(() -> {
- byte[] temp = new byte[bufferSize];
- int count;
- for (count = 0; count < bufferSize; count++) {
- if (!inputContent.locationInUse(location+count)) {
- break;
- }
- temp[count] = (byte)inputContent.getLocation(location+count);
- }
- byte[] data = new byte[count];
- System.arraycopy(temp, 0, data, 0, count);
- int addr = location; // next call back might be instantaneous
- location = location + count;
- log.debug("LoaderClient: DG Data");
- dcs.sendData(new DatagramService.DatagramServiceTransmitMemo(destNodeID(),new int[]{data}) {
- public void handleWriteReply(int code) {
- log.debug("LoaderClient: Start of DGNextReply "+code);
- progress = sentmsgs/totalmsgs*100;
- if ((++sentmsgs % 20) == 0) ; //updateGUI(state, progress); // callback for GUI
- if(state==DG && code==0x000) {
- location = inputContent.nextContent(location);
- if (location < 0) {
- log.info(" LoaderClient: Download completed normally");
- sendUnfreeze();
- state = SUCCESS;
- } else {
- log.debug(" LoaderClient: Continue to 0x{}", Integer.toHexString(location).toUpperCase());
- sendDGNext();
- }
- } else {
- // non-normal reply
- log.info(" LoaderClient: Done abnormal code:{}", code);
- state = FAIL;
- sendUnfreeze();
- }
- });
- }
- });
- }
- void sendUnfreeze() {
- log.debug("LoaderClient: sendUnfreeze");
- dcs.sendData(new DatagramService.DatagramServiceTransmitMemo(destNodeID(), {0x20, 0xA0, space}) {
- public void handleReply(int code) {
- log.info("LoaderClient: unfreeze reply");
- }
- });
- }
-}
\ No newline at end of file
Modified: trunk/prototypes/java/src/org/openlcb/StreamDataSendMessage.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/StreamDataSendMessage.java 2016-01-19 17:20:42 UTC (rev 4002)
+++ trunk/prototypes/java/src/org/openlcb/StreamDataSendMessage.java 2016-01-19 22:28:40 UTC (rev 4003)
@@ -47,8 +47,19 @@
}
public String toString() {
- return super.toString()
- +" StreamDataSend "+data;
+ StringBuilder value = new StringBuilder(super.toString());
+ value.append(" Stream: ");
+
+ int n = data.length;
+ if(n>16) n=16;
+ boolean first = true;
+ for (int i = 0; i<n; i++) {
+ if (!first) value.append(".");
+ value.append(Integer.toHexString((int)(data[i]&0xFF)).toUpperCase());
+ first = false;
+ }
+ if(data.length>16) value.append(" ...");
+ return new String(value);
}
public int getMTI() { return MTI_STREAM_DATA_SEND; }
Modified: trunk/prototypes/java/src/org/openlcb/implementations/MemoryConfigurationService.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/implementations/MemoryConfigurationService.java 2016-01-19 17:20:42 UTC (rev 4002)
+++ trunk/prototypes/java/src/org/openlcb/implementations/MemoryConfigurationService.java 2016-01-19 22:28:40 UTC (rev 4003)
@@ -86,6 +86,7 @@
//memo.handleConfigData(dest, commands, options, highSpace, lowSpace,"");
}
// dph
+
if (writeStreamMemo != null) {
// receive destinationStreamID
// figure out address space uses byte?
@@ -101,8 +102,9 @@
}
McsWriteStreamMemo memo = writeStreamMemo;
writeStreamMemo = null;
- memo.handleWriteStreamData(dest, memo.space, memo.address, content);
+ //memo.handleWriteStreamData(dest, memo.space, memo.address, content);
}
+
}
});
}
@@ -134,9 +136,11 @@
// dph
McsWriteStreamMemo writeStreamMemo;
public void request(McsWriteStreamMemo memo) {
- // forward as read Datagram
+ // forward as write Datagram
+ //System.out.println("writeStreamMemo: "+memo.dest+","+memo.space+","+memo.address);
+ // System.out.println("writeStreamMemo: "+memo.dest);
writeStreamMemo = memo;
- WriteDatagramMemo dg = new WriteDatagramMemo(memo.dest, memo.space, memo.address, memo.data, memo);
+ WriteStreamMemo dg = new WriteStreamMemo(memo.dest, memo.space, memo.address, memo);
downstream.sendData(dg);
}
@@ -206,6 +210,53 @@
}
@Immutable
+ @ThreadSafe
+ static public class McsWriteStreamMemo {
+ public McsWriteStreamMemo(NodeID dest, int space, long address) {
+ //super(dest, space, address);
+ this.address = address;
+ this.space = space;
+ this.dest = dest;
+ this.data = null;
+ }
+
+ //final int count;
+ final long address;
+ final int space;
+ final NodeID dest;
+ final byte[] data;
+
+ @Override
+ public boolean equals(Object o) {
+ if (o == null) return false;
+ if (! (o instanceof McsWriteMemo)) return false;
+ McsWriteMemo m = (McsWriteMemo) o;
+ if (this.dest != m.dest) return false;
+ if (this.space != m.space) return false;
+ if (this.address != m.address) return false;
+ return this.data.length == m.data.length;
+ }
+
+ @Override
+ public String toString() {
+ return "McsWriteStreamMemo: "+address;
+ }
+
+ @Override
+ public int hashCode() { return dest.hashCode()+space+((int)address)+data.length; }
+
+ /**
+ * Overload this for notification of failure reply
+ * @param code non-zero for error reply
+ */
+
+ public void handleReply(int code){}
+ public void handleWriteReply(int code){}
+ public void handleWriteStreamReply(int code) {}
+ }
+
+
+ @Immutable
@ThreadSafe
static public class ReadDatagramMemo extends DatagramService.DatagramServiceTransmitMemo {
ReadDatagramMemo(NodeID dest, int space, long address, int count, McsReadMemo memo) {
@@ -319,52 +370,45 @@
// need sourceStreamID
@Immutable
@ThreadSafe
- static public class McsWriteStreamMemo extends McsWriteMemo {
- public McsWriteStreamMemo(NodeID dest, int space, long address, byte[] data) {
- super( dest, space, address, data);
- this.address = address;
- this.space = space;
- this.dest = dest;
- this.data = data;
+ static public class WriteStreamMemo extends DatagramService.DatagramServiceTransmitMemo {
+// public WriteStreamMemo(NodeID dest, int space, long address, byte[] content, McsWriteMemo memo) {
+ public WriteStreamMemo(NodeID dest, int space, long address, McsWriteStreamMemo memo) {
+ super(dest);
+ this.space=space;
+ this.address = address;
+ boolean spaceByte = false;
+ if (space<0xFD) spaceByte = true;
+ this.data = new int[6+(spaceByte ? 1 : 0)+1];
+ this.data[0] = DATAGRAM_TYPE;
+ this.data[1] = 0x20;
+ if (space >= 0xFD) this.data[1] |= space&0x3;
+
+ this.data[2] = (int)(address>>24)&0xFF;
+ this.data[3] = (int)(address>>16)&0xFF;
+ this.data[4] = (int)(address>>8 )&0xFF;
+ this.data[5] = (int)(address )&0xFF;
+
+ if (spaceByte) {
+ this.data[6] = space;
+ this.data[7] = 0x04;
+ } else this.data[6] = 0x04; // srcStreamID???? why do we need this?
+
+
+ //for (int i = 0; i < content.length; i++)
+ // this.data[6+(spaceByte ? 1 : 0)+i] = content[i];
+
+ this.memo = memo;
}
-
- byte[] data;
- final long address;
- final int space;
- final NodeID dest;
-
- @Override
- public boolean equals(Object o) {
- if (o == null) return false;
- if (! (o instanceof McsWriteStreamMemo)) return false;
- McsWriteStreamMemo m = (McsWriteStreamMemo) o;
- if (this.dest != m.dest) return false;
- if (this.space != m.space) return false;
- if (this.address != m.address) return false;
- return this...
[truncated message content] |
|
From: <dph...@us...> - 2016-01-25 02:19:24
|
Revision: 4021
http://sourceforge.net/p/openlcb/svn/4021
Author: dpharris
Date: 2016-01-25 02:19:22 +0000 (Mon, 25 Jan 2016)
Log Message:
-----------
updated loader
Modified Paths:
--------------
trunk/prototypes/java/openlcb-demo.jar
trunk/prototypes/java/openlcb.jar
trunk/prototypes/java/src/org/openlcb/DatagramMessage.java
trunk/prototypes/java/src/org/openlcb/LoaderClient.java
trunk/prototypes/java/src/org/openlcb/ProtocolIdentificationReplyMessage.java
trunk/prototypes/java/src/org/openlcb/StreamDataSendMessage.java
trunk/prototypes/java/src/org/openlcb/can/MessageBuilder.java
trunk/prototypes/java/src/org/openlcb/implementations/StreamTransmitter.java
trunk/prototypes/java/test/org/openlcb/LoaderClientTest.java
trunk/prototypes/java/test/org/openlcb/implementations/StreamReceiverTest.java
trunk/prototypes/java/test/org/openlcb/implementations/StreamTransmitterTest.java
Modified: trunk/prototypes/java/openlcb-demo.jar
===================================================================
(Binary files differ)
Modified: trunk/prototypes/java/openlcb.jar
===================================================================
(Binary files differ)
Modified: trunk/prototypes/java/src/org/openlcb/DatagramMessage.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/DatagramMessage.java 2016-01-25 02:03:49 UTC (rev 4020)
+++ trunk/prototypes/java/src/org/openlcb/DatagramMessage.java 2016-01-25 02:19:22 UTC (rev 4021)
@@ -86,8 +86,8 @@
public String toString() {
StringBuilder value = new StringBuilder(super.toString());
value.append(" Datagram: ");
-
int n = getData().length;
+ value.append("("+n+") ");
boolean first = true;
for (int i = 0; i<n; i++) {
if (!first) value.append(".");
Modified: trunk/prototypes/java/src/org/openlcb/LoaderClient.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/LoaderClient.java 2016-01-25 02:03:49 UTC (rev 4020)
+++ trunk/prototypes/java/src/org/openlcb/LoaderClient.java 2016-01-25 02:19:22 UTC (rev 4021)
@@ -23,8 +23,9 @@
//#include "LoaderClient.hpp"
public class LoaderClient extends MessageDecoder {
- enum State { IDLE, ABORT, FREEZE, INITCOMPL, PIP, SETUPSTREAM, STREAM, STREAMDATA, DG, UNFREEEZE, SUCCESS, FAIL };
+ enum State { IDLE, ABORT, FREEZE, INITCOMPL, PIP, PIPREPLY, SETUPSTREAM, STREAM, STREAMDATA, DG, UNFREEEZE, SUCCESS, FAIL };
Connection connection;
+ Connection fromDownstream;
MemoryConfigurationService mcs;
DatagramService dcs;
MimicNodeStore store;
@@ -37,22 +38,14 @@
byte[] content;
LoaderStatusReporter feedback;
- public abstract class LoaderStatusReporter {
+ public static abstract class LoaderStatusReporter {
public abstract void onProgress(float percent);
public abstract void onDone(int errorCode, String errorString);
}
- public LoaderClient(NodeID _src, NodeID _dest, int _space, long _address, byte[] _content, LoaderStatusReporter _feedback, Connection _connection, MemoryConfigurationService _mcs, DatagramService _dcs ) {
- src = _src;
- dest = _dest;
- space = _space;
- address = _address;
- content = _content.clone();
- // System.out.println("LoaderClient: content="+content);
- feedback = _feedback;
+ public LoaderClient( Connection _connection, MemoryConfigurationService _mcs, DatagramService _dcs ) {
+ //System.out.println("LoaderClient init");
connection = _connection;
- //dcs = new DatagramService(src, connection);
- //mcs = new MemoryConfigurationService(src, dcs);
dcs = _dcs;
mcs = _mcs;
}
@@ -87,8 +80,14 @@
*/
- public void doLoad() {
- state = State.FREEZE;
+ public void doLoad(NodeID _src, NodeID _dest, int _space, long _address, byte[] _content, LoaderStatusReporter _feedback) {
+ src = _src;
+ dest = _dest;
+ space = _space;
+ address = _address;
+ content = _content;
+ state = State.IDLE;
+ feedback = _feedback;
sendFreeze(); // allow restarts
}
@@ -96,60 +95,65 @@
final int DG_FAIL = 0x0100; // note that this value is used in DGMeteringBuffer to denote time-out
final int DG_RESEND = 0x0200;
void sendFreeze() {
- // System.out.println("lSendFreeze ");
- //DatagramTransmitter d0 = new DatagramTransmitter(src, dest, new int[]{0x20, 0xA1, space}, connection);
-
+ // System.out.println("lSendFreeze ");
+ state = State.FREEZE;
+ // System.out.println("lsendFREEZE Enter: "+state);
dcs.sendData(
new DatagramService.DatagramServiceTransmitMemo(dest, new int[]{0x20, 0xA1, space}) {
@Override
public void handleReply(int code) {
- // System.out.println("Freeze handleReply: ");
- if((state==State.FREEZE)) {
- if(code==DG_OK) { state = State.INITCOMPL; } // DG ok
- else if(code==DG_FAIL) { state = State.INITCOMPL; } // DG timed out, but ok timeouts
- //else if((code&DG_RESEND)!=0) { state = State.FREEZE; } // resend ok, so start again
- else state = State.FAIL; // Apparently this node doesn't handle DGs
- } else state = State.FAIL;
+ // System.out.println("lFreeze handleReply: "+code);
+ //if((state==State.FREEZE)) {
+ // if(code==DG_OK) { state = State.INITCOMPL; } // DG ok
+ // else if(code==DG_FAIL) { state = State.INITCOMPL; } // DG timed out, but ok timeouts
+ // else state = State.FAIL; // Apparently this node doesn't handle DGs
+ //}
+ state = State.PIP;
+ sendPipRequest();
+ //System.out.println("lhandleFreeze Reply Exit: "+state);
}
});
}
- @Override
+ //@Override
public void handleInitializationComplete(InitializationCompleteMessage msg, Connection sender){
- // System.out.println("lhandleInitializationComplete");
- if (state == State.FREEZE && msg.getSourceNodeID().equals(dest)) { state = State.PIP; sendPipRequest(); }
- if (state == State.INITCOMPL && msg.getSourceNodeID().equals(dest)) { state = State.PIP; sendPipRequest(); }
+ //System.out.println("lhandleInitializationComplete state: "+state);
+// if (state == State.FREEZE && msg.getSourceNodeID().equals(dest)) { state = State.PIP; sendPipRequest(); }
+// if (state == State.INITCOMPL && msg.getSourceNodeID().equals(dest)) { state = State.PIP; sendPipRequest(); }
}
void sendPipRequest() {
- // System.out.println("lSendPipRequest ");
+ state = State.PIPREPLY;
+ //System.out.println("lSendPipRequest "+state);
Message msg = new ProtocolIdentificationRequestMessage(src, dest);
connection.put(msg, this);
- //state = PIPREPLY;
}
@Override
public void handleProtocolIdentificationReply(ProtocolIdentificationReplyMessage msg, Connection sender){
- // System.out.println("lhandleProtocolIdentificationReply");
- int retries = 0;
- if (state == State.PIP && msg.getSourceNodeID().equals(dest)) {
- if((msg.getValue()&0x00200000)!=0) {
+ //System.out.println("lhandleProtocolIdentificationReply Enter:"+state);
+ // System.out.println("lmsg.getSourceNodeID():"+msg.getSourceNodeID());
+ //System.out.println("lmsg.getValue():"+String.format("0x%12X",msg.getValue()));
+ if (state == State.PIPREPLY && msg.getSourceNodeID().equals(dest)) {
+ if((msg.getValue()&0x000010000000L)==0) {
state=State.FAIL;
- feedback.onDone(0, "Loader: Target node should not be in Operating state.");
+ feedback.onDone(0, "Loader: Target node does not support Firmware Upgrade Protocol.");
}
- else if((msg.getValue()&0x00100000)==0) {
- state=State.FAIL; // not in FirmwareUpgrade Operating state
- feedback.onDone(0, "Loader: Target node is not in Firmware Upgrade state.");
+ else if((msg.getValue()&0x000020000000L)==0) {
+ state=State.FAIL;
+ feedback.onDone(0, "Loader: Target node is not in Upgrade Operating state.");
}
- else if((msg.getValue()&0x20000000)!=0) {
+ else if((msg.getValue()&0x200000000000L)!=0) {
state = State.SETUPSTREAM;
+ //System.out.println("lStream ok:"+state);
setupStream();
- } else if((msg.getValue()&0x40000000)!=0) {
+ } else if((msg.getValue()&0x400000000000L)!=0) {
state = State.DG;
- //feedback.onDone(0, "BollicksDG!?");
+ //System.out.println("lDGs ok:"+state);
sendDGs();
} else {
state = State.FAIL;
- feedback.onDone(0, "Loader: Target node does not support Streams nor Datagram!?");
+ feedback.onDone(0, "Loader: Target node does not support Streams nor Datagrams!?");
}
}
+ //System.out.println("lhandleProtocolIdentificationReply Exit:"+state);
}
int bufferSize; // chunk size
@@ -163,7 +167,8 @@
byte destStreamID;
byte sourceStreamID = 4; // notional value
-
+
+// ============================= STREAMS ==============================================
void setupStream() {
// System.out.println("lSetup Stream ");
bufferSize = 64;
@@ -204,14 +209,15 @@
}
public void sendStreamNext() {
int size = Math.min(bufferSize, content.length-nextIndex);
- byte[] data = new byte[size];
+ int[] data = new int[size];
// copy the needed data
for (int i=0; i<size; i++) data[i] = content[nextIndex+i];
- nextIndex = nextIndex+size;
// System.out.println("\nsendStreamNext: "+data);
- Message m = new StreamDataSendMessage(src, dest, data, destStreamID);
+ Message m = new StreamDataSendMessage(src, dest, data);
connection.put(m, this);
// are we done?
+ nextIndex = nextIndex+size;
+ feedback.onProgress(100.0F * (float)nextIndex / (float)content.length);
if (nextIndex < content.length) return; // wait for Data Proceed message
// yes, say we're done
m = new StreamDataCompleteMessage(src, dest, sourceStreamID, destStreamID);
@@ -219,43 +225,62 @@
sendUnfreeze();
state = State.SUCCESS;
}
+ //public void sendStreamComplete() {
+ //connection.put(new StreamDataCompleteMessage(src, dest, sourceStreamID, destStreamID), this);
+ // sendUnfreeze();
+ //}
public void handleStreamDataProceed(StreamDataProceedMessage msg, Connection sender){
// System.out.println("handleStreamDataProceed");
sendStreamNext();
}
+
+// ============================= DATAGRAMS ==============================================
void sendDGs() {
- // System.out.println("\nlsendDGs: ");
+ //System.out.println("\nlsendDGs: ");
nextIndex = 0;
- bufferSize = 8;
+ bufferSize = 64;
sendDGNext();
}
void sendDGNext() {
int size = Math.min(bufferSize, content.length-nextIndex);
- // System.out.println("lbufferSize: "+bufferSize);
- // System.out.println("lsize: "+size);
- int[] data = new int[size];
- // copy the needed data
- for (int i=0; i<size; i++) data[i] = content[nextIndex+i];
- nextIndex = nextIndex+size;
- dcs.sendData(new DatagramService.DatagramServiceTransmitMemo(dest, data) {
+ //System.out.println("lsendDGNext Enter: "+state);
+ //System.out.println("content.length: "+content.length);
+ //System.out.println("nextIndex: "+nextIndex);
+ //System.out.println("lbufferSize: "+bufferSize);
+ //System.out.println("lsize: "+size);
+ byte[] data = new byte[size];
+ // copy the needed data
+ for (int i=0; i<size; i++) data[i] = content[nextIndex+i];
+
+ //System.out.println("lsendDGNext mcs.request(new McsWriteMemo: "+state);
+ mcs.request(new McsWriteMemo(dest, space, nextIndex, data) {
@Override
- public void handleReply(int code) {
- // System.out.println("lDG handleReply");
- sendDGNext();
+ public void handleWriteReply(int code) {
+ //System.out.println("Reply mcs.request McsWriteMemo handleWriteReply: "+code);
+ if(nextIndex<content.length) sendDGNext();
+ else {
+ sendUnfreeze();
+ state = State.SUCCESS;
+ }
}
});
- // are we done?
- if( nextIndex < content.length ) return;
- sendUnfreeze();
- state = State.SUCCESS;
-
+
+ feedback.onProgress(100.0F * (float)nextIndex / (float)content.length);
+
+ // are we done?
+ nextIndex = nextIndex+size;
+ return;
}
void sendUnfreeze() {
// System.out.println("lsendUnfreeze");
dcs.sendData(new DatagramService.DatagramServiceTransmitMemo(dest, new int[]{0x20, 0xA0, space}) {
+ @Override
public void handleReply(int code) {
+ System.out.println("lc-sendUnfreeze reply: "+state);
+ feedback.onProgress((float)100.0);
+ feedback.onDone(0,"Success");
}
});
}
Modified: trunk/prototypes/java/src/org/openlcb/ProtocolIdentificationReplyMessage.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/ProtocolIdentificationReplyMessage.java 2016-01-25 02:03:49 UTC (rev 4020)
+++ trunk/prototypes/java/src/org/openlcb/ProtocolIdentificationReplyMessage.java 2016-01-25 02:19:22 UTC (rev 4021)
@@ -52,7 +52,7 @@
@Override
public String toString() {
return super.toString()
- +" Protocol Identification Reply with value "+value;
+ +" Protocol Identification Reply with value "+String.format("0x%12X",value);
}
public int getMTI() { return MTI_PROTOCOL_IDENT_REPLY; }
Modified: trunk/prototypes/java/src/org/openlcb/StreamDataSendMessage.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/StreamDataSendMessage.java 2016-01-25 02:03:49 UTC (rev 4020)
+++ trunk/prototypes/java/src/org/openlcb/StreamDataSendMessage.java 2016-01-25 02:19:22 UTC (rev 4021)
@@ -14,17 +14,18 @@
@ThreadSafe
public class StreamDataSendMessage extends AddressedMessage {
- public StreamDataSendMessage(NodeID source, NodeID dest, byte[] data,
- byte destStreamID) {
+// public StreamDataSendMessage(NodeID source, NodeID dest, byte[] data,
+// byte destStreamID) {
+ public StreamDataSendMessage(NodeID source, NodeID dest, int[] data) {
super(source, dest);
this.data = data;
- this.destStreamID = destStreamID;
+ //this.destStreamID = destStreamID;
}
- byte[] data;
+ int[] data;
byte destStreamID;
byte getDestinationStreamID() { return destStreamID; }
- public byte[] getData() { return data; }
+ public int[] getData() { return data; }
/**
* Implement message-type-specific
* processing when this message
Modified: trunk/prototypes/java/src/org/openlcb/can/MessageBuilder.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/can/MessageBuilder.java 2016-01-25 02:03:49 UTC (rev 4020)
+++ trunk/prototypes/java/src/org/openlcb/can/MessageBuilder.java 2016-01-25 02:19:22 UTC (rev 4021)
@@ -378,7 +378,8 @@
for(int i=0; i<bufSize; i++) data[i] = list.get(i);
List<Message> retlist = new java.util.ArrayList<Message>();
NodeID dest = map.getNodeID( (f.getHeader() & 0x00FFF000) >> 12);
- retlist.add(new DatagramMessage(source, dest, data));
+ //retlist.add(new DatagramMessage(source, dest, data));
+ retlist.add(new StreamDataSendMessage(source, dest, data));
// make a new List and fill it with the rest of received data
list = new ArrayList<Integer>();
for (int i=n; i<f.getNumDataElements(); i++) list.add(f.getElement(i));
@@ -696,7 +697,7 @@
int size = Math.min(8, remains);
byte[] data = new byte[size];
for (int i = 0; i<size; i++) {
- data[i] = msg.getData()[j++];
+ data[i] = (byte)msg.getData()[j++];
}
OpenLcbCanFrame f = new OpenLcbCanFrame(0x00);
Modified: trunk/prototypes/java/src/org/openlcb/implementations/StreamTransmitter.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/implementations/StreamTransmitter.java 2016-01-25 02:03:49 UTC (rev 4020)
+++ trunk/prototypes/java/src/org/openlcb/implementations/StreamTransmitter.java 2016-01-25 02:19:22 UTC (rev 4021)
@@ -15,7 +15,7 @@
*/
public class StreamTransmitter extends MessageDecoder {
- public StreamTransmitter(NodeID here, NodeID far, int bufferSize, byte[] bytes, Connection c) {
+ public StreamTransmitter(NodeID here, NodeID far, int bufferSize, int[] bytes, Connection c) {
//System.out.println("StreamTransmitter");
this.here = here;
this.far = far;
@@ -31,7 +31,7 @@
NodeID here;
NodeID far;
int bufferSize;
- byte[] bytes;
+ int[] bytes;
Connection connection;
int nextIndex;
@@ -57,14 +57,14 @@
void sendNext() {
//System.out.println("StreamTransmitter sendNext");
int size = Math.min(bufferSize, bytes.length-nextIndex);
- byte[] data = new byte[size];
+ int[] data = new int[size];
// copy the needed data
for (int i = 0; i<size; i++)
data[i] = bytes[nextIndex+i];
nextIndex = nextIndex+size;
// send data
- Message m = new StreamDataSendMessage(here, far, data, destStreamID);
+ Message m = new StreamDataSendMessage(here, far, data);
connection.put(m, this);
// are we done?
Modified: trunk/prototypes/java/test/org/openlcb/LoaderClientTest.java
===================================================================
--- trunk/prototypes/java/test/org/openlcb/LoaderClientTest.java 2016-01-25 02:03:49 UTC (rev 4020)
+++ trunk/prototypes/java/test/org/openlcb/LoaderClientTest.java 2016-01-25 02:19:22 UTC (rev 4021)
@@ -3,7 +3,7 @@
import org.openlcb.*;
import org.openlcb.implementations.*;
import org.openlcb.LoaderClient;
-//import org.openlcb.DatagramAcknowledged;
+import org.openlcb.LoaderClient.LoaderStatusReporter;
import junit.framework.Assert;
import junit.framework.Test;
@@ -99,69 +99,156 @@
---> UnFreeze
*/
+
+ //public void testFake() {}
+ public void testLoaderClientDGPIPFail1() {
+ data =new byte[80];
+ LoaderClient xmt = new LoaderClient(testConnection, mcs, dcs);
+ xmt.doLoad(hereID,farID, 0xEF, 0, data, new LoaderStatusReporter() {
+ public void onProgress(float percent) {
+ System.out.println("onProcess:"+percent);
+ }
+ public void onDone(int errorCode, String errorString) {
+ System.out.println("onDone:"+errorCode+": "+errorString);
+ }
+ });
+ System.out.println("LC1 Expect 'Not supported' error.");
+ Assert.assertEquals("Freeze", 1, messagesReceived.size());
+ Assert.assertTrue(messagesReceived.get(0).equals(new DatagramMessage(hereID,farID,new int[]{0x20, 0xA1, 0xEF})));
+ messagesReceived.clear();
+ dcs.put(new DatagramAcknowledgedMessage(farID,hereID), null);
+ xmt.put(new InitializationCompleteMessage(farID), null);
+ Assert.assertEquals("PIPRequest", 1, messagesReceived.size());
+ Assert.assertTrue(messagesReceived.get(0).equals(new ProtocolIdentificationRequestMessage(hereID,farID)));
+ messagesReceived.clear();
+ xmt.put(new ProtocolIdentificationReplyMessage(farID,hereID,0x400000000000L), null);
+ }
+
+
+ public void testLoaderClientDGPIPFail2() {
+ data =new byte[80];
+ LoaderClient xmt = new LoaderClient(testConnection, mcs, dcs);
+ xmt.doLoad(hereID,farID, 0xEF, 0, data, new LoaderStatusReporter() {
+ public void onProgress(float percent) {
+ System.out.println("onProcess:"+percent);
+ }
+ public void onDone(int errorCode, String errorString) {
+ System.out.println("onDone:"+errorCode+": "+errorString);
+ }
+ });
+ System.out.println("LC2 Expect 'Not in Upgrade state' error.");
+ Assert.assertEquals("Freeze", 1, messagesReceived.size());
+ Assert.assertTrue(messagesReceived.get(0).equals(new DatagramMessage(hereID,farID,new int[]{0x20, 0xA1, 0xEF})));
+ messagesReceived.clear();
+ dcs.put(new DatagramAcknowledgedMessage(farID,hereID), null);
+ xmt.put(new InitializationCompleteMessage(farID), null);
+ Assert.assertEquals("PIPRequest", 1, messagesReceived.size());
+ Assert.assertTrue(messagesReceived.get(0).equals(new ProtocolIdentificationRequestMessage(hereID,farID)));
+ messagesReceived.clear();
+ xmt.put(new ProtocolIdentificationReplyMessage(farID,hereID,0x000010000000L), null);
+ }
+
+
+ public void testLoaderClientDGPIPFail3() {
+ data =new byte[80];
+ LoaderClient xmt = new LoaderClient(testConnection, mcs, dcs);
+ xmt.doLoad(hereID,farID, 0xEF, 0, data, new LoaderStatusReporter() {
+ public void onProgress(float percent) {
+ System.out.println("onProcess:"+percent);
+ }
+ public void onDone(int errorCode, String errorString) {
+ System.out.println("onDone:"+errorCode+": "+errorString);
+ }
+ });
+ System.out.println("LC3 Expect 'Node does not support DGs/Streams.' error.");
+ Assert.assertEquals("Freeze", 1, messagesReceived.size());
+ Assert.assertTrue(messagesReceived.get(0).equals(new DatagramMessage(hereID,farID,new int[]{0x20, 0xA1, 0xEF})));
+ messagesReceived.clear();
+ dcs.put(new DatagramAcknowledgedMessage(farID,hereID), null);
+ xmt.put(new InitializationCompleteMessage(farID), null);
+ Assert.assertEquals("PIPRequest", 1, messagesReceived.size());
+ Assert.assertTrue(messagesReceived.get(0).equals(new ProtocolIdentificationRequestMessage(hereID,farID)));
+ messagesReceived.clear();
+ xmt.put(new ProtocolIdentificationReplyMessage(farID,hereID,0x000030000000L), null);
+ }
+
+
public void testLoaderClientDG() {
- reporter = null;
-
- data =new byte[]{1,2,3,4,5,6,7,8,9,10};
- LoaderClient xmt = new LoaderClient( hereID,farID, 45, 0, data, reporter, testConnection, mcs, dcs);
- xmt.doLoad();
+ data =new byte[80];
+ LoaderClient xmt = new LoaderClient(testConnection, mcs, dcs);
+ xmt.doLoad(hereID,farID, 0xEF, 0, data, new LoaderStatusReporter() {
+ public void onProgress(float percent) {
+ //System.out.println("onProcess:"+percent);
+ }
+ public void onDone(int errorCode, String errorString) {
+ System.out.println("onDone:"+errorCode+": "+errorString);
+ }
+ });
// Freeze
Assert.assertEquals("Freeze", 1, messagesReceived.size());
- // System.out.println("testLoaderClientDG freeze");
- Assert.assertTrue(messagesReceived.get(0).equals(new DatagramMessage(hereID,farID,new int[]{0x20, 0xA1, 45})));
+ //System.out.println("testLoaderClientDG freeze");
+ Assert.assertTrue(messagesReceived.get(0).equals(new DatagramMessage(hereID,farID,new int[]{0x20, 0xA1, 0xEF})));
messagesReceived.clear();
dcs.put(new DatagramAcknowledgedMessage(farID,hereID), null);
xmt.put(new InitializationCompleteMessage(farID), null);
// PIPRequest
Assert.assertEquals("PIPRequest", 1, messagesReceived.size());
//System.out.println("testLoaderClientDG PIPRequest");
- Assert.assertTrue(messagesReceived.get(0).equals(new ProtocolIdentificationRequestMessage(hereID,farID))); // DGs ok
+ Assert.assertTrue(messagesReceived.get(0).equals(new ProtocolIdentificationRequestMessage(hereID,farID)));
+ // DGs ok
messagesReceived.clear();
- xmt.put(new ProtocolIdentificationReplyMessage(farID,hereID,0x40100000), null);
+ xmt.put(new ProtocolIdentificationReplyMessage(farID,hereID,0x400030000000L), null);
// First DG
Assert.assertEquals("first DG", 1, messagesReceived.size());
//System.out.println("testLoaderClientDG first DG "+messagesReceived.size());
//System.out.println("Msg0: "+(messagesReceived.get(0) != null ? messagesReceived.get(0).toString() : " == null"));
- Assert.assertTrue(messagesReceived.get(0).equals(new DatagramMessage(hereID,farID,new byte[]{1,2,3,4,5,6,7,8}))); // DGs ok
+ int[] data = new int[71];
+ data[0]=0x20; data[1]=0; data[2]=0; data[3]=0; data[4]=0; data[5]=0; data[6]=0xEF;
+ for(int i=7;i<71;i++) data[i]=0;
+ Assert.assertTrue(messagesReceived.get(0).equals(new DatagramMessage(hereID,farID,data))); // DG ok
messagesReceived.clear();
dcs.put(new DatagramAcknowledgedMessage(farID,hereID),null);
// Second DG
- Assert.assertEquals("second DG", 2, messagesReceived.size());
+ Assert.assertEquals("second DG", 1, messagesReceived.size());
//System.out.println("DG2: "+(messagesReceived.get(0) != null ? messagesReceived.get(0).toString() : " == null"));
- //System.out.println("Unfreeze: "+(messagesReceived.get(1) != null ? messagesReceived.get(1).toString() : " == null"));
- Assert.assertTrue(messagesReceived.get(0).equals(new DatagramMessage(hereID,farID,new byte[]{9,10}))); // DGs ok
- xmt.put(new DatagramAcknowledgedMessage(farID,hereID),null);
+ data = new int[7+16];
+ data[0]=0x20; data[1]=0; data[2]=0; data[3]=0; data[4]=0; data[5]=0x40; data[6]=0xEF;
+ for(int i=7;i<(7+16);i++) data[i]=0;
+ Assert.assertTrue(messagesReceived.get(0).equals(new DatagramMessage(hereID,farID,data))); // DG ok
+ messagesReceived.clear();
+ dcs.put(new DatagramAcknowledgedMessage(farID,hereID),null);
// Unfreeze
- Assert.assertTrue(messagesReceived.get(1).equals(new DatagramMessage(hereID,farID,new int[]{0x20, 0xA0, 45})));
+ Assert.assertEquals("Unfreeze", 1, messagesReceived.size());
+ //System.out.println("Msg0: "+(messagesReceived.get(0) != null ? messagesReceived.get(0).toString() : " == null"));
+ Assert.assertTrue(messagesReceived.get(0).equals(new DatagramMessage(hereID,farID,new int[]{0x20, 0xA0, 0xEF})));
}
-
+
public void testLoaderClientStream() {
-
- reporter = null;
- //new LoaderClient.LoaderStatusReporter
- //(
- // void onProgress(float percent){};
- // void onDone(int errorCode, String errorString){};
- //);
data = new byte[]{'a','b','c','d','e','f','g','h','i','j'};
- LoaderClient xmt = new LoaderClient( hereID,farID, 45, 0, data, reporter, testConnection, mcs, dcs);
- xmt.doLoad();
+ LoaderClient xmt = new LoaderClient(testConnection, mcs, dcs);
+ xmt.doLoad(hereID,farID, 45, 0, data, new LoaderStatusReporter() {
+ public void onProgress(float percent) {
+ //System.out.println("onProcess:"+percent);
+ }
+ public void onDone(int errorCode, String errorString) {
+ System.out.println("onDone:"+errorCode+": "+errorString);
+ }
+ });
// Freeze
Assert.assertEquals("Freeze", 1, messagesReceived.size());
Assert.assertTrue(messagesReceived.get(0).equals(new DatagramMessage(hereID,farID,new int[]{0x20, 0xA1, 45})));
messagesReceived.clear();
dcs.put(new DatagramAcknowledgedMessage(farID,hereID), null);
- messagesReceived.clear();
+ //messagesReceived.clear();
xmt.put(new Initializat...
[truncated message content] |
|
From: <br...@us...> - 2016-01-25 17:21:51
|
Revision: 4022
http://sourceforge.net/p/openlcb/svn/4022
Author: bracz
Date: 2016-01-25 17:21:48 +0000 (Mon, 25 Jan 2016)
Log Message:
-----------
Removes code for testing Firmware Upgrade Operational state from the loader, because at that point the client must be in upgrade state, not operational state.
Modified Paths:
--------------
trunk/prototypes/java/openlcb-demo.jar
trunk/prototypes/java/openlcb.jar
trunk/prototypes/java/src/org/openlcb/LoaderClient.java
Modified: trunk/prototypes/java/openlcb-demo.jar
===================================================================
(Binary files differ)
Modified: trunk/prototypes/java/openlcb.jar
===================================================================
(Binary files differ)
Modified: trunk/prototypes/java/src/org/openlcb/LoaderClient.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/LoaderClient.java 2016-01-25 02:19:22 UTC (rev 4021)
+++ trunk/prototypes/java/src/org/openlcb/LoaderClient.java 2016-01-25 17:21:48 UTC (rev 4022)
@@ -134,12 +134,8 @@
if (state == State.PIPREPLY && msg.getSourceNodeID().equals(dest)) {
if((msg.getValue()&0x000010000000L)==0) {
state=State.FAIL;
- feedback.onDone(0, "Loader: Target node does not support Firmware Upgrade Protocol.");
+ feedback.onDone(0, "Loader: Target node is not in Upgrade state.");
}
- else if((msg.getValue()&0x000020000000L)==0) {
- state=State.FAIL;
- feedback.onDone(0, "Loader: Target node is not in Upgrade Operating state.");
- }
else if((msg.getValue()&0x200000000000L)!=0) {
state = State.SETUPSTREAM;
//System.out.println("lStream ok:"+state);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <dph...@us...> - 2016-01-26 00:38:20
|
Revision: 4023
http://sourceforge.net/p/openlcb/svn/4023
Author: dpharris
Date: 2016-01-26 00:38:18 +0000 (Tue, 26 Jan 2016)
Log Message:
-----------
Add 3s delay, fixed Progress-Bar
Modified Paths:
--------------
trunk/prototypes/java/openlcb-demo.jar
trunk/prototypes/java/openlcb.jar
trunk/prototypes/java/src/org/openlcb/LoaderClient.java
trunk/prototypes/java/src/org/openlcb/implementations/DatagramMeteringBuffer.java
Modified: trunk/prototypes/java/openlcb-demo.jar
===================================================================
(Binary files differ)
Modified: trunk/prototypes/java/openlcb.jar
===================================================================
(Binary files differ)
Modified: trunk/prototypes/java/src/org/openlcb/LoaderClient.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/LoaderClient.java 2016-01-25 17:21:48 UTC (rev 4022)
+++ trunk/prototypes/java/src/org/openlcb/LoaderClient.java 2016-01-26 00:38:18 UTC (rev 4023)
@@ -8,6 +8,8 @@
import org.openlcb.implementations.DatagramTransmitter.*;
import org.openlcb.ProtocolIdentificationReplyMessage;
import org.openlcb.StreamInitiateReplyMessage;
+import java.util.Timer;
+import java.util.TimerTask;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
@@ -29,6 +31,7 @@
MemoryConfigurationService mcs;
DatagramService dcs;
MimicNodeStore store;
+ String errorString;
State state;
NodeID src;
@@ -110,10 +113,34 @@
//}
state = State.PIP;
sendPipRequest();
+ startTimeout(3000);
//System.out.println("lhandleFreeze Reply Exit: "+state);
}
});
}
+ Timer timer;
+ void startTimeout(int period) {
+ timer = new Timer();
+ TimerTask task = new TimerTask(){
+ public void run(){
+ timerExpired();
+ }
+ };
+ timer.schedule(task, period);
+ }
+ void endTimeout() {
+ if (timer != null) timer.cancel();
+ else {
+ state = State.FAIL;
+
+ }
+ }
+ void timerExpired() {
+ state = State.FAIL;
+ errorString = "Timed out";
+ sendUnfreeze();
+ }
+
//@Override
public void handleInitializationComplete(InitializationCompleteMessage msg, Connection sender){
//System.out.println("lhandleInitializationComplete state: "+state);
@@ -131,10 +158,11 @@
//System.out.println("lhandleProtocolIdentificationReply Enter:"+state);
// System.out.println("lmsg.getSourceNodeID():"+msg.getSourceNodeID());
//System.out.println("lmsg.getValue():"+String.format("0x%12X",msg.getValue()));
+ endTimeout();
if (state == State.PIPREPLY && msg.getSourceNodeID().equals(dest)) {
if((msg.getValue()&0x000010000000L)==0) {
state=State.FAIL;
- feedback.onDone(0, "Loader: Target node is not in Upgrade state.");
+ errorString = "Target not in Upgrade state.";
}
else if((msg.getValue()&0x200000000000L)!=0) {
state = State.SETUPSTREAM;
@@ -146,7 +174,7 @@
sendDGs();
} else {
state = State.FAIL;
- feedback.onDone(0, "Loader: Target node does not support Streams nor Datagrams!?");
+ errorString = "Target has no Streams nor Datagrams!";
}
}
//System.out.println("lhandleProtocolIdentificationReply Exit:"+state);
@@ -160,7 +188,8 @@
int location;
int nextIndex;
float progress;
-
+ float replyCount;
+ float expectedTransactions;
byte destStreamID;
byte sourceStreamID = 4; // notional value
@@ -236,6 +265,8 @@
//System.out.println("\nlsendDGs: ");
nextIndex = 0;
bufferSize = 64;
+ replyCount = 0;
+ expectedTransactions = content.length / bufferSize;
sendDGNext();
}
void sendDGNext() {
@@ -256,18 +287,31 @@
//System.out.println("Reply mcs.request McsWriteMemo handleWriteReply: "+code);
if(nextIndex<content.length) sendDGNext();
else {
- sendUnfreeze();
- state = State.SUCCESS;
+ //sendUnfreeze();
+ //state = State.SUCCESS;
}
}
});
- feedback.onProgress(100.0F * (float)nextIndex / (float)content.length);
+ //feedback.onProgress(100.0F * (float)nextIndex / (float)content.length);
// are we done?
nextIndex = nextIndex+size;
return;
}
+ public void handleDatagramAcknowledged(DatagramAcknowledgedMessage msg, Connection sender) {
+ //System.out.println("Reply mcs.requesthandleDatagramAcknowledged ");
+ if(state == State.DG && msg.getSourceNodeID().equals(dest)) {
+ replyCount++;
+ float p = 100.0F * replyCount / expectedTransactions;
+ feedback.onProgress(p);
+ if( p > 100.0F*(expectedTransactions-1)/expectedTransactions ) state=state.UNFREEEZE;
+ }
+ if(state == State.UNFREEEZE && msg.getSourceNodeID().equals(dest)) {
+ sendUnfreeze();
+ state = State.SUCCESS;
+ }
+ }
void sendUnfreeze() {
// System.out.println("lsendUnfreeze");
@@ -275,8 +319,15 @@
@Override
public void handleReply(int code) {
System.out.println("lc-sendUnfreeze reply: "+state);
- feedback.onProgress((float)100.0);
- feedback.onDone(0,"Success");
+ if(state == State.SUCCESS) {
+ // if(state == State.SUCCESS && msg.getSourceNodeID().equals(dest)) {
+ feedback.onProgress((float)100.0);
+ feedback.onDone(0,"Download Completed");
+ }
+ else {
+ //feedback.onProgress((float)0.0);
+ feedback.onDone(0,"Download Failed - "+errorString);
+ }
}
});
}
Modified: trunk/prototypes/java/src/org/openlcb/implementations/DatagramMeteringBuffer.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/implementations/DatagramMeteringBuffer.java 2016-01-25 17:21:48 UTC (rev 4022)
+++ trunk/prototypes/java/src/org/openlcb/implementations/DatagramMeteringBuffer.java 2016-01-26 00:38:18 UTC (rev 4023)
@@ -29,7 +29,8 @@
*/
public class DatagramMeteringBuffer extends MessageDecoder {
- final static int TIMEOUT = 700;
+ //final static int TIMEOUT = 700;
+ final static int TIMEOUT = 3000;
public DatagramMeteringBuffer(Connection toDownstream) {
this.toDownstream = toDownstream;
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:11:56
|
Revision: 4152
http://sourceforge.net/p/openlcb/svn/4152
Author: bracz
Date: 2016-07-14 17:11:53 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Adds the ability to the RemoteTrainNode to retrieve and cache the FDI information.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/implementations/throttle/RemoteTrainNode.java
trunk/prototypes/java/src/org/openlcb/implementations/throttle/TrainNodeCache.java
trunk/prototypes/java/test/org/openlcb/implementations/throttle/RemoteTrainNodeTest.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:11:32 UTC (rev 4151)
+++ trunk/prototypes/java/src/org/openlcb/implementations/throttle/RemoteTrainNode.java 2016-07-14 17:11:53 UTC (rev 4152)
@@ -2,23 +2,104 @@
import net.jcip.annotations.Immutable;
import net.jcip.annotations.ThreadSafe;
-import org.openlcb.*;
+import org.jdom2.Document;
+import org.jdom2.Element;
+import org.jdom2.JDOMException;
+import org.jdom2.input.SAXBuilder;
+import org.openlcb.NodeID;
+import org.openlcb.OlcbInterface;
+import org.openlcb.cdi.jdom.CdiMemConfigReader;
+import org.openlcb.cdi.jdom.JdomCdiReader;
+import org.openlcb.implementations.MemoryConfigurationService;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.util.logging.Logger;
+
/**
* Represents local view about a remote Train Node, a node that implements the Traction protocol.
*
- *
- * @author Bob Jacobsen Copyright 2012
+ * @author Bob Jacobsen Copyright 2012
* @version $Revision$
*/
@Immutable
@ThreadSafe
public class RemoteTrainNode {
- public RemoteTrainNode(NodeID node) {
+ public static final String UPDATE_PROP_FDI = "fdi";
+ private static Logger logger = Logger.getLogger(new Object() {
+ }.getClass().getSuperclass()
+ .getName());
+ private final OlcbInterface iface;
+ java.beans.PropertyChangeSupport pcs = new java.beans.PropertyChangeSupport(this);
+ private Element fdiRoot;
+ private NodeID node;
+ private String fdiXml = null;
+
+ public RemoteTrainNode(NodeID node, OlcbInterface iface) {
this.node = node;
- }
- NodeID node;
-
- public NodeID getNodeId() { return node; }
+ this.iface = iface;
+ }
+
+ private static Element parseXmlFromReader(Reader r) throws Exception {
+ SAXBuilder builder = new SAXBuilder(false);
+
+ // parse namespaces, including the noNamespaceSchema
+ builder.setFeature("http://xml.org/sax/features/namespaces", true);
+
+ Document doc;
+ try {
+ doc = builder.build(r);
+ return doc.getRootElement();
+ } catch (JDOMException | IOException e) {
+ System.err.println("Could not create Document: " + e);
+ throw e;
+ }
+ }
+
+ public NodeID getNodeId() {
+ return node;
+ }
+
+ public boolean hasFdiXml() {
+ return fdiXml != null;
+ }
+
+ public synchronized void setFdiXmlCached(String payload) {
+ if (fdiXml != null) { fdiXml = payload; }
+ }
+
+ public synchronized Element getFdiXml() {
+ if (fdiRoot != null) return fdiRoot;
+ new CdiMemConfigReader(node, iface, MemoryConfigurationService.SPACE_TRACTION_FDI)
+ .startLoadReader(new CdiMemConfigReader.ReaderAccess() {
+ @Override
+ public void provideReader(Reader r) {
+ try {
+ fdiRoot = parseXmlFromReader(r);//JdomCdiReader.getHeadFromReader(r);
+ } catch (Exception e) {
+ logger.warning("Unable to parse returned FDI from train " + node
+ .toString());
+ e.printStackTrace();
+ //throw new RuntimeException(e);
+ return;
+ }
+ firePropertyChange(UPDATE_PROP_FDI, null, fdiRoot);
+ }
+ });
+ return null;
+ }
+
+ 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);
+ }
}
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:11:32 UTC (rev 4151)
+++ trunk/prototypes/java/src/org/openlcb/implementations/throttle/TrainNodeCache.java 2016-07-14 17:11:53 UTC (rev 4152)
@@ -42,7 +42,7 @@
memo.getSimpleNodeIdent();
memo.getProtocolIdentification();
}
- return new RemoteTrainNode(id);
+ return new RemoteTrainNode(id, iface);
}
}
Modified: trunk/prototypes/java/test/org/openlcb/implementations/throttle/RemoteTrainNodeTest.java
===================================================================
--- trunk/prototypes/java/test/org/openlcb/implementations/throttle/RemoteTrainNodeTest.java 2016-07-14 17:11:32 UTC (rev 4151)
+++ trunk/prototypes/java/test/org/openlcb/implementations/throttle/RemoteTrainNodeTest.java 2016-07-14 17:11:53 UTC (rev 4152)
@@ -15,11 +15,11 @@
public class RemoteTrainNodeTest extends TestCase {
public void testCtor() {
- new RemoteTrainNode(new NodeID(new byte[]{1,2,3,4,5,6}));
+ new RemoteTrainNode(new NodeID(new byte[]{1,2,3,4,5,6}), null);
}
public void testNodeMemory() {
- RemoteTrainNode node = new RemoteTrainNode(new NodeID(new byte[]{1,2,3,4,5,6}));
+ RemoteTrainNode node = new RemoteTrainNode(new NodeID(new byte[]{1,2,3,4,5,6}), null);
Assert.assertTrue(new NodeID(new byte[]{1,2,3,4,5,6}).equals(node.getNodeId()));
}
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:13:39
|
Revision: 4157
http://sourceforge.net/p/openlcb/svn/4157
Author: bracz
Date: 2016-07-14 17:13:37 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Makes the output messages enter a queue and hop to a dedicated output thread. This will prevent calling back from the dispatcher handler into the output handler which will then do local-loopback again, causing apparently recursive calls and ConcurrentModificationExceptions.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/OlcbInterface.java
trunk/prototypes/java/test/org/openlcb/FakeOlcbInterface.java
Modified: trunk/prototypes/java/src/org/openlcb/OlcbInterface.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/OlcbInterface.java 2016-07-14 17:13:15 UTC (rev 4156)
+++ trunk/prototypes/java/src/org/openlcb/OlcbInterface.java 2016-07-14 17:13:37 UTC (rev 4157)
@@ -7,6 +7,8 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
/**
* Collects all objects necessary to run an OpenLCB standards-compatible interface.
@@ -16,8 +18,12 @@
public class OlcbInterface {
/// Object for sending messages to the network.
+ protected final Connection internalOutputConnection;
+ /// Object we return to the customer when they ask for the output connection
protected final Connection outputConnection;
- private final OutputConnectionSniffer wrappedOutputConnection = new OutputConnectionSniffer();
+
+ private final OutputConnectionSniffer wrappedOutputConnection;
+ private final QueuedOutputConnection queuedOutputConnection;
/// Object for taking incoming messages and forwarding them to the necessary handlers.
private final MessageDispatcher inputConnection;
private final NodeID nodeId;
@@ -44,7 +50,10 @@
*/
public OlcbInterface(NodeID nodeId_, Connection outputConnection_) {
nodeId = nodeId_;
- this.outputConnection = outputConnection_;
+ this.internalOutputConnection = outputConnection_;
+ this.wrappedOutputConnection = new OutputConnectionSniffer(internalOutputConnection);
+ this.queuedOutputConnection = new QueuedOutputConnection(this.wrappedOutputConnection);
+ this.outputConnection = this.queuedOutputConnection;
inputConnection = new MessageDispatcher();
nodeStore = new MimicNodeStore(getOutputConnection(), nodeId);
@@ -61,6 +70,14 @@
public void connectionActive(Connection c) {
Message m = new InitializationCompleteMessage(nodeId);
outputConnection.put(m, getInputConnection());
+ // Starts the output queue once we have the confirmation from the lower level that
+ // the connection is ready and we have enqueued the initialization complete message.
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ queuedOutputConnection.run();
+ }
+ }).start();
}
});
}
@@ -123,14 +140,12 @@
}
@Override
- public void put(Message msg, Connection sender) {
+ public synchronized void put(Message msg, Connection sender) {
if (!pendingListeners.isEmpty() || !unpendingListeners.isEmpty()) {
- synchronized (this) {
- listeners.addAll(pendingListeners);
- pendingListeners.clear();
- listeners.removeAll(unpendingListeners);
- unpendingListeners.clear();
- }
+ listeners.addAll(pendingListeners);
+ pendingListeners.clear();
+ listeners.removeAll(unpendingListeners);
+ unpendingListeners.clear();
}
for (Connection c : listeners) {
c.put(msg, sender);
@@ -143,6 +158,12 @@
* path to sending messages.
*/
class OutputConnectionSniffer implements Connection {
+ private final Connection realOutput;
+
+ OutputConnectionSniffer(Connection realOutput) {
+ this.realOutput = realOutput;
+ }
+
@Override
public void put(Message msg, Connection sender) {
// For addressed messages we check if the target is local or remote.
@@ -159,13 +180,51 @@
// For global messages, we always send a copy of the message locally.
inputConnection.put(msg, sender);
}
- outputConnection.put(msg, sender);
+ realOutput.put(msg, sender);
}
@Override
public void registerStartNotification(ConnectionListener c) {
- outputConnection.registerStartNotification(c);
+ realOutput.registerStartNotification(c);
}
}
+ /**
+ * This class keeps an output connection operating using an internal queue. It keeps
+ * messages in an internal thread-safe queue and sends them on a separate thread.
+ * <p/>
+ * The caller must donate a thread to this connection by calling the run() method.
+ */
+ private class QueuedOutputConnection implements Connection {
+ private final Connection realOutput;
+ private final BlockingQueue<Message> outputQueue = new LinkedBlockingQueue<>();
+
+ QueuedOutputConnection(Connection realOutput) {
+ this.realOutput = realOutput;
+ }
+
+ @Override
+ public void put(Message msg, Connection sender) {
+ outputQueue.add(msg);
+ }
+
+ @Override
+ public void registerStartNotification(ConnectionListener c) {
+ internalOutputConnection.registerStartNotification(c);
+ }
+
+ /**
+ * Never returns.
+ */
+ private void run() {
+ while (true) {
+ try {
+ Message m = outputQueue.take();
+ realOutput.put(m, null);
+ } catch (InterruptedException e) {
+ continue;
+ }
+ }
+ }
+ }
}
Modified: trunk/prototypes/java/test/org/openlcb/FakeOlcbInterface.java
===================================================================
--- trunk/prototypes/java/test/org/openlcb/FakeOlcbInterface.java 2016-07-14 17:13:15 UTC (rev 4156)
+++ trunk/prototypes/java/test/org/openlcb/FakeOlcbInterface.java 2016-07-14 17:13:37 UTC (rev 4157)
@@ -12,6 +12,6 @@
*/
public FakeOlcbInterface() {
super(new NodeID(new byte[]{1,2,0,0,1,1}), new FakeConnection());
- fakeOutputConnection = (FakeConnection) outputConnection;
+ fakeOutputConnection = (FakeConnection) internalOutputConnection;
}
}
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:29:23
|
Revision: 4205
http://sourceforge.net/p/openlcb/svn/4205
Author: bracz
Date: 2016-07-14 17:29:20 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Removes accidental copy-paste.
Modified Paths:
--------------
trunk/prototypes/java/openlcb.jar
trunk/prototypes/java/src/org/openlcb/cdi/impl/MemorySpaceCache.java
Modified: trunk/prototypes/java/openlcb.jar
===================================================================
(Binary files differ)
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:28:59 UTC (rev 4204)
+++ trunk/prototypes/java/src/org/openlcb/cdi/impl/MemorySpaceCache.java 2016-07-14 17:29:20 UTC (rev 4205)
@@ -13,7 +13,7 @@
import java.util.Map;
import java.util.NavigableMap;
import java.util.Queue;
-import java.util.TreeMap;Upgrade gradle to 2.10
+import java.util.TreeMap;
import java.util.logging.Logger;
/**
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:30:59
|
Revision: 4210
http://sourceforge.net/p/openlcb/svn/4210
Author: bracz
Date: 2016-07-14 17:30:56 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Adds better printout for the stream data complete message.
Fixes stream transmitter test because it was setting incorrect expectations that did not correctly set the src/dst IDs.
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/StreamDataCompleteMessage.java
trunk/prototypes/java/test/org/openlcb/implementations/StreamTransmitterTest.java
Modified: trunk/prototypes/java/src/org/openlcb/StreamDataCompleteMessage.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/StreamDataCompleteMessage.java 2016-07-14 17:30:35 UTC (rev 4209)
+++ trunk/prototypes/java/src/org/openlcb/StreamDataCompleteMessage.java 2016-07-14 17:30:56 UTC (rev 4210)
@@ -50,7 +50,7 @@
public String toString() {
return super.toString()
- +" StreamDataComplete";
+ +" StreamDataComplete srcId=" + sourceStreamID + " dstId=" + destStreamID;
}
public int getMTI() { return MTI_STREAM_DATA_COMPLETE; }
Modified: trunk/prototypes/java/test/org/openlcb/implementations/StreamTransmitterTest.java
===================================================================
--- trunk/prototypes/java/test/org/openlcb/implementations/StreamTransmitterTest.java 2016-07-14 17:30:35 UTC (rev 4209)
+++ trunk/prototypes/java/test/org/openlcb/implementations/StreamTransmitterTest.java 2016-07-14 17:30:56 UTC (rev 4210)
@@ -62,10 +62,9 @@
xmt.put(m, null);
Assert.assertEquals("1st messages", 2, messagesReceived.size());
- Assert.assertTrue(messagesReceived.get(0)
- .equals(new StreamDataSendMessage(hereID, farID, data)));
- Assert.assertTrue(messagesReceived.get(1)
- .equals(new StreamDataCompleteMessage(hereID, farID, (byte)0, (byte)0)));
+ Assert.assertEquals(messagesReceived.get(0), new StreamDataSendMessage(hereID, farID, data));
+ Assert.assertEquals(messagesReceived.get(1), new StreamDataCompleteMessage(hereID, farID,
+ (byte)4, (byte)0));
}
public void testTwoMsgStream() {
@@ -109,7 +108,7 @@
Assert.assertTrue(messagesReceived.get(0)
.equals(new StreamDataSendMessage(hereID, farID, new int[256])));
Assert.assertTrue(messagesReceived.get(1)
- .equals(new StreamDataCompleteMessage(hereID, farID, (byte)0, (byte)0)));
+ .equals(new StreamDataCompleteMessage(hereID, farID, (byte)4, (byte)0)));
}
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:31:39
|
Revision: 4212
http://sourceforge.net/p/openlcb/svn/4212
Author: bracz
Date: 2016-07-14 17:31:36 +0000 (Thu, 14 Jul 2016)
Log Message:
-----------
Merge branch 'debug' of bracz.zrh:train/openlcb/gitsvn/svn into debug
# Conflicts:
# src/org/openlcb/LoaderClient.java
# src/org/openlcb/StreamDataCompleteMessage.java
# src/org/openlcb/implementations/MemoryConfigurationService.java
# test/org/openlcb/ProtocolIdentificationTest.java
# test/org/openlcb/cdi/jdom/CdiMemConfigReaderTest.java
# test/org/openlcb/implementations/DatagramMeteringBufferTest.java
Modified Paths:
--------------
trunk/prototypes/java/src/org/openlcb/DatagramAcknowledgedMessage.java
trunk/prototypes/java/src/org/openlcb/LoaderClient.java
trunk/prototypes/java/src/org/openlcb/OlcbInterface.java
trunk/prototypes/java/src/org/openlcb/can/GridConnect.java
trunk/prototypes/java/src/org/openlcb/can/MessageBuilder.java
trunk/prototypes/java/src/org/openlcb/can/OpenLcbCanFrame.java
trunk/prototypes/java/src/org/openlcb/can/impl/GridConnectInput.java
trunk/prototypes/java/src/org/openlcb/cdi/impl/MemorySpaceCache.java
trunk/prototypes/java/src/org/openlcb/cdi/jdom/CdiMemConfigReader.java
trunk/prototypes/java/src/org/openlcb/implementations/DatagramMeteringBuffer.java
trunk/prototypes/java/src/org/openlcb/implementations/DatagramService.java
trunk/prototypes/java/src/org/openlcb/implementations/DatagramUtils.java
trunk/prototypes/java/src/org/openlcb/implementations/MemoryConfigSpaceRetriever.java
trunk/prototypes/java/src/org/openlcb/implementations/MemoryConfigurationService.java
trunk/prototypes/java/src/org/openlcb/swing/memconfig/MemConfigDescriptionPane.java
trunk/prototypes/java/src/org/openlcb/swing/memconfig/MemConfigReadWritePane.java
trunk/prototypes/java/test/org/openlcb/FakeConnection.java
trunk/prototypes/java/test/org/openlcb/InterfaceTestBase.java
trunk/prototypes/java/test/org/openlcb/LoaderClientTest.java
trunk/prototypes/java/test/org/openlcb/can/GridConnectTest.java
trunk/prototypes/java/test/org/openlcb/can/MessageBuilderTest.java
trunk/prototypes/java/test/org/openlcb/cdi/jdom/CdiMemConfigReaderTest.java
trunk/prototypes/java/test/org/openlcb/implementations/DatagramMeteringBufferTest.java
trunk/prototypes/java/test/org/openlcb/implementations/DatagramServiceTest.java
trunk/prototypes/java/test/org/openlcb/implementations/MemoryConfigurationServiceTest.java
trunk/prototypes/java/test/org/openlcb/implementations/StreamTransmitterTest.java
trunk/prototypes/java/test/org/openlcb/swing/memconfig/MemConfigDescriptionPaneTest.java
trunk/prototypes/java/test/org/openlcb/swing/memconfig/MemConfigReadWritePaneTest.java
trunk/prototypes/java/test/tools/cansim/CanFrame.java
Added Paths:
-----------
trunk/prototypes/java/src/org/openlcb/FailureCallback.java
trunk/prototypes/java/src/org/openlcb/NoReturnCallback.java
trunk/prototypes/java/test/org/openlcb/implementations/DatagramUtilsTest.java
trunk/prototypes/java/test/org/openlcb/implementations/MemoryConfigurationServiceInterfaceTest.java
Modified: trunk/prototypes/java/src/org/openlcb/DatagramAcknowledgedMessage.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/DatagramAcknowledgedMessage.java 2016-07-14 17:31:15 UTC (rev 4211)
+++ trunk/prototypes/java/src/org/openlcb/DatagramAcknowledgedMessage.java 2016-07-14 17:31:36 UTC (rev 4212)
@@ -16,8 +16,18 @@
public DatagramAcknowledgedMessage(NodeID source, NodeID dest) {
super(source, dest);
+ flags = 0;
}
-
+
+ public DatagramAcknowledgedMessage(NodeID source, NodeID dest, int flags) {
+ super(source, dest);
+ this.flags = flags;
+ }
+
+ int flags;
+
+ public int getFlags() { return flags; }
+
/**
* Implement message-type-specific
* processing when this message
@@ -35,7 +45,8 @@
if (o == null) return false;
if (! (o instanceof DatagramAcknowledgedMessage))
return false;
- return super.equals(o);
+ if (!super.equals(o)) return false;
+ return (flags == ((DatagramAcknowledgedMessage)o).flags);
}
@Override
Added: trunk/prototypes/java/src/org/openlcb/FailureCallback.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/FailureCallback.java (rev 0)
+++ trunk/prototypes/java/src/org/openlcb/FailureCallback.java 2016-07-14 17:31:36 UTC (rev 4212)
@@ -0,0 +1,13 @@
+package org.openlcb;
+
+/**
+ * Created by bracz on 5/2/16.
+ */
+public interface FailureCallback {
+ /**
+ * Called when the requested operation encounters an error. Temporary errors are usually
+ * internally re-tried.
+ * @param errorCode OpenLCB error code (16-bit)
+ */
+ void handleFailure(int errorCode);
+}
Modified: trunk/prototypes/java/src/org/openlcb/LoaderClient.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/LoaderClient.java 2016-07-14 17:31:15 UTC (rev 4211)
+++ trunk/prototypes/java/src/org/openlcb/LoaderClient.java 2016-07-14 17:31:36 UTC (rev 4212)
@@ -10,6 +10,7 @@
import org.openlcb.StreamInitiateReplyMessage;
import java.util.Timer;
import java.util.TimerTask;
+import java.util.logging.Logger;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
@@ -25,6 +26,7 @@
//#include "LoaderClient.hpp"
public class LoaderClient extends MessageDecoder {
+ static Logger logger = Logger.getLogger("LoaderClient");
enum State { IDLE, ABORT, FREEZE, INITCOMPL, PIP, PIPREPLY, SETUPSTREAM, STREAM, STREAMDATA, DG, UNFREEEZE, SUCCESS, FAIL };
Connection connection;
Connection fromDownstream;
@@ -104,18 +106,22 @@
dcs.sendData(
new DatagramService.DatagramServiceTransmitMemo(dest, new int[]{0x20, 0xA1, space}) {
@Override
- public void handleReply(int code) {
- // System.out.println("lFreeze handleReply: "+code);
- //if((state==State.FREEZE)) {
- // if(code==DG_OK) { state = State.INITCOMPL; } // DG ok
- // else if(code==DG_FAIL) { state = State.INITCOMPL; } // DG timed out, but ok timeouts
- // else state = State.FAIL; // Apparently this node doesn't handle DGs
- //}
- state = State.PIP;
- sendPipRequest();
- startTimeout(3000);
- //System.out.println("lhandleFreeze Reply Exit: "+state);
+ public void handleSuccess(int flags) {
+ if(state==State.FREEZE) {
+ state = State.PIP;
+ sendPipRequest();
+ startTimeout(3000);
+ } else {
+ // ignore; maybe a late timeout callback.
+ }
}
+
+ @Override
+ public void handleFailure(int errorCode) {
+ // It is actually OK to have this fail because the remote node may have
+ // rebooted.
+ handleSuccess(0);
+ }
});
}
Timer timer;
@@ -199,12 +205,18 @@
bufferSize = 64;
state = State.STREAM;
- mcs.request(new McsWriteStreamMemo(dest, space, address) {
+ mcs.request(new McsWriteStreamMemo(dest, space, address, 4) {
@Override
- public void handleWriteReply(int code) {
- // System.out.println("Reply mcs.request McsWriteStreamMemo handleWriteReply: ");
+ public void handleSuccess() {
sendStream();
}
+
+ @Override
+ public void handleFailure(String where, int errorCode) {
+ state = State.FAIL;
+ logger.warning("Failed to setup stream at " + where + ": error 0x" + Integer
+ .toHexString(errorCode));
+ }
});
}
@@ -281,14 +293,18 @@
for (int i=0; i<size; i++) data[i] = content[nextIndex+i];
//System.out.println("lsendDGNext mcs.request(new McsWriteMemo: "+state);
- mcs.request(new McsWriteMemo(dest, space, nextIndex, data) {
+ mcs.requestWrite(dest, space, nextIndex, data, new McsWriteHandler() {
@Override
- public void handleWriteReply(int code) {
- //System.out.println("Reply mcs.request McsWriteMemo handleWriteReply: "+code);
+ public void handleFailure(int errorCode) {
+ sendDGNext();
+ }
+
+ @Override
+ public void handleSuccess() {
if(nextIndex<content.length) sendDGNext();
else {
+ state = State.SUCCESS;
sendUnfreeze();
- state = State.SUCCESS;
}
}
});
@@ -311,19 +327,22 @@
void sendUnfreeze() {
// System.out.println("lsendUnfreeze");
dcs.sendData(new DatagramService.DatagramServiceTransmitMemo(dest, new int[]{0x20, 0xA0, space}) {
+
@Override
- public void handleReply(int code) {
- System.out.println("lc-sendUnfreeze reply: "+state);
- if(state == State.SUCCESS) {
- // if(state == State.SUCCESS && msg.getSourceNodeID().equals(dest)) {
- feedback.onProgress((float)100.0);
- feedback.onDone(0,"Download Completed");
- }
- else {
- //feedback.onProgress((float)0.0);
+ public void handleSuccess(int flags) {
+ if (state == State.SUCCESS) {
+ feedback.onProgress((float) 100.0);
+ feedback.onDone(0, "Download Completed");
+ } else {
feedback.onDone(0,"Download Failed - "+errorString);
}
}
+
+ @Override
+ public void handleFailure(int errorCode) {
+ feedback.onDone(0,"Download Failed in UnFreeze - 0x"+Integer.toHexString(errorCode));
+ }
+
});
}
}
\ No newline at end of file
Added: trunk/prototypes/java/src/org/openlcb/NoReturnCallback.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/NoReturnCallback.java (rev 0)
+++ trunk/prototypes/java/src/org/openlcb/NoReturnCallback.java 2016-07-14 17:31:36 UTC (rev 4212)
@@ -0,0 +1,14 @@
+package org.openlcb;
+
+/**
+ * Represents the callback for an operation that returns nothing. THis will be shared by a number
+ * of different services.
+ *
+ * Created by bracz on 5/2/16.
+ */
+public interface NoReturnCallback extends FailureCallback {
+ /**
+ * Called when the requested operation completes successfully.
+ */
+ void handleSuccess();
+}
Modified: trunk/prototypes/java/src/org/openlcb/OlcbInterface.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/OlcbInterface.java 2016-07-14 17:31:15 UTC (rev 4211)
+++ trunk/prototypes/java/src/org/openlcb/OlcbInterface.java 2016-07-14 17:31:36 UTC (rev 4212)
@@ -115,6 +115,14 @@
return mcs;
}
+ /**
+ * Blocks the current thread until the outgoing messages are all sent out. Useful for testing.
+ */
+ public void flushSendQueue() {
+ dmb.waitForSendQueue();
+ queuedOutputConnection.waitForSendQueue();
+ }
+
public void registerMessageListener(Connection c) {
inputConnection.registerMessageListener(c);
}
@@ -198,6 +206,7 @@
private class QueuedOutputConnection implements Connection {
private final Connection realOutput;
private final BlockingQueue<Message> outputQueue = new LinkedBlockingQueue<>();
+ private int pendingCount = 0;
QueuedOutputConnection(Connection realOutput) {
this.realOutput = realOutput;
@@ -205,6 +214,9 @@
@Override
public void put(Message msg, Connection sender) {
+ synchronized(this) {
+ pendingCount++;
+ }
outputQueue.add(msg);
}
@@ -213,6 +225,17 @@
internalOutputConnection.registerStartNotification(c);
}
+ public void waitForSendQueue() {
+ while(true) {
+ synchronized (this) {
+ if (pendingCount == 0) return;
+ }
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {}
+ }
+ }
+
/**
* Never returns.
*/
@@ -221,6 +244,9 @@
try {
Message m = outputQueue.take();
realOutput.put(m, null);
+ synchronized(this) {
+ pendingCount--;
+ }
} catch (InterruptedException e) {
continue;
}
Modified: trunk/prototypes/java/src/org/openlcb/can/GridConnect.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/can/GridConnect.java 2016-07-14 17:31:15 UTC (rev 4211)
+++ trunk/prototypes/java/src/org/openlcb/can/GridConnect.java 2016-07-14 17:31:36 UTC (rev 4212)
@@ -1,5 +1,7 @@
package org.openlcb.can;
+import org.openlcb.implementations.DatagramUtils;
+
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
@@ -198,7 +200,7 @@
@Override
public int getElement(int n) {
- return data[n];
+ return DatagramUtils.byteToInt(data[n]);
}
@Override
Modified: trunk/prototypes/java/src/org/openlcb/can/MessageBuilder.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/can/MessageBuilder.java 2016-07-14 17:31:15 UTC (rev 4211)
+++ trunk/prototypes/java/src/org/openlcb/can/MessageBuilder.java 2016-07-14 17:31:36 UTC (rev 4212)
@@ -4,6 +4,7 @@
import java.util.HashMap;
import java.util.List;
import org.openlcb.*;
+import org.openlcb.implementations.DatagramUtils;
import org.openlcb.messages.TractionControlReplyMessage;
import org.openlcb.messages.TractionControlRequestMessage;
import org.openlcb.messages.TractionProxyReplyMessage;
@@ -250,9 +251,13 @@
case SimpleNodeIdentInfoReply:
retlist.add(new SimpleNodeIdentInfoReplyMessage(source, dest, content));
return retlist;
-
- case DatagramReceivedOK:
- retlist.add(new DatagramAcknowledgedMessage(source,dest));
+ case DatagramReceivedOK:
+ if (content != null && content.length > 0) {
+ retlist.add(new DatagramAcknowledgedMessage(source, dest, DatagramUtils
+ .byteToInt(content[0])));
+ } else {
+ retlist.add(new DatagramAcknowledgedMessage(source, dest));
+ }
return retlist;
case DatagramRejected:
retlist.add(new DatagramRejectedMessage(source,dest,(int)f.dataAsLong()));
@@ -649,8 +654,11 @@
public void handleDatagramAcknowledged(DatagramAcknowledgedMessage msg, Connection sender){
OpenLcbCanFrame f = new OpenLcbCanFrame(0x00);
f.setOpenLcbMTI(MessageTypeIdentifier.DatagramReceivedOK.mti());
+ f.setSourceAlias(map.getAlias(msg.getSourceNodeID()));
+ if (msg.getFlags() != 0) {
+ f.setData(new byte[]{0, 0, (byte)msg.getFlags()});
+ }
f.setDestAlias(map.getAlias(msg.getDestNodeID()));
- f.setSourceAlias(map.getAlias(msg.getSourceNodeID()));
retlist.add(f);
}
/**
@@ -679,7 +687,7 @@
OpenLcbCanFrame f = new OpenLcbCanFrame(0x00);
f.setOpenLcbMTI(MessageTypeIdentifier.StreamInitiateReply.mti());
// dest(2), maxBufferSize(2), flags(2),sourceStream, destinationStream
- f.setData(new byte[]{ (byte)0, (byte)0, 0, 64, msg.getSourceStreamID(), msg.getDestinationStreamID() } );
+ f.setData(new byte[]{(byte) 0, (byte) 0, 0, 64, msg.getSourceStreamID(), msg.getDestinationStreamID() } );
f.setDestAlias(map.getAlias(msg.getDestNodeID()));
f.setSourceAlias(map.getAlias(msg.getSourceNodeID()));
retlist.add(f);
Modified: trunk/prototypes/java/src/org/openlcb/can/OpenLcbCanFrame.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/can/OpenLcbCanFrame.java 2016-07-14 17:31:15 UTC (rev 4211)
+++ trunk/prototypes/java/src/org/openlcb/can/OpenLcbCanFrame.java 2016-07-14 17:31:36 UTC (rev 4212)
@@ -1,6 +1,7 @@
package org.openlcb.can;
import org.openlcb.*;
+import org.openlcb.implementations.DatagramUtils;
import javax.annotation.Nullable;
@@ -68,7 +69,7 @@
public boolean isRtr() { return false; }
public int getNumDataElements() { return length; }
- public int getElement(int n) { return data[n]; }
+ public int getElement(int n) { return DatagramUtils.byteToInt(data[n]); }
// bit 1
static final int MASK_FRAME_TYPE = 0x08000000;
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:31:15 UTC (rev 4211)
+++ trunk/prototypes/java/src/org/openlcb/can/impl/GridConnectInput.java 2016-07-14 17:31:36 UTC (rev 4212)
@@ -2,6 +2,7 @@
import org.openlcb.can.CanFrame;
import org.openlcb.can.CanFrameListener;
+import org.openlcb.implementations.DatagramUtils;
import java.io.BufferedReader;
import java.io.IOException;
@@ -162,7 +163,7 @@
@Override
public int getElement(int n) {
- return data[n];
+ return DatagramUtils.byteToInt(data[n]);
}
@Override
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:31:15 UTC (rev 4211)
+++ trunk/prototypes/java/src/org/openlcb/cdi/impl/MemorySpaceCache.java 2016-07-14 17:31:36 UTC (rev 4212)
@@ -195,13 +195,17 @@
count = 64;
}
final int fcount = count;
- connection.getMemoryConfigurationService().request(
- new MemoryConfigurationService.McsReadMemo(remoteNodeID, space,
- currentRangeNextOffset, count) {
+ connection.getMemoryConfigurationService().requestRead(remoteNodeID, space,
+ currentRangeNextOffset, count,
+ new MemoryConfigurationService.McsReadHandler() {
@Override
- public void
- handleWriteReply(int code) {
- super.handleWriteReply(code);
+ public void handleFailure(int code) {
+ logger.warning("Error reading memory space cache: dest " + remoteNodeID +
+ "space" + space + " offset " + currentRangeNextOffset + " error " +
+ "0x" + Integer.toHexString(code));
+ // ignore and continue reading other stuff.
+ currentRangeNextOffset += fcount;
+ loadRange();
}
@Override
@@ -217,7 +221,7 @@
" address= " + address + " length=" + data.length + " " +
"expected" +
" address=" + currentRangeNextOffset + " expectedspace=" +
- MemorySpaceCache.this.space + " expectedcount=" + this.count);
+ MemorySpaceCache.this.space + " expectedcount=" + fcount);
}
if (data.length == 0) {
logger.warning(String.format("Datagram read returned 0 bytes. " +
@@ -235,8 +239,7 @@
}
loadRange();
}
- }
- );
+ });
}
private Map.Entry<Range, byte[]> getCacheForRange(long offset, int len) {
@@ -267,19 +270,21 @@
}
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) {
+ connection.getMemoryConfigurationService().requestWrite(remoteNodeID, space, offset,
+ data, new MemoryConfigurationService.McsWriteHandler() {
@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));
- }
+ public void handleFailure(int errorCode) {
+ logger.warning(String.format("Write failed (space %d address %d): 0x" +
+ "%04x", space, offset, errorCode));
cdiEntry.fireWriteComplete();
}
+
+ @Override
+ public void handleSuccess() {
+ logger.finer(String.format("Write complete (space %d address %d).",
+ space, offset));
+ cdiEntry.fireWriteComplete();
+ }
}
);
// @TODO: 4/2/16 Handle write errors and report to user somehow.
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:31:15 UTC (rev 4211)
+++ trunk/prototypes/java/src/org/openlcb/cdi/jdom/CdiMemConfigReader.java 2016-07-14 17:31:36 UTC (rev 4212)
@@ -58,9 +58,16 @@
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) {
+ MemoryConfigurationService.McsReadHandler memo =
+ new MemoryConfigurationService.McsReadHandler() {
+ @Override
+ public void handleFailure(int code) {
+ done();
+ // TODO: 5/2/16 proxy error messages to the caller.
+ // don't do next request
+ }
+
+ public void handleReadData(NodeID dest, int space, long address, byte[] data) {
// handle return data, checking for null in string or zero-length reply
if (data.length == 0) {
done();
@@ -78,7 +85,7 @@
nextRequest();
}
};
- service.request(memo);
+ service.requestRead(node, space, nextAddress, LENGTH, memo);
}
private void done() {
Modified: trunk/prototypes/java/src/org/openlcb/implementations/DatagramMeteringBuffer.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/implementations/DatagramMeteringBuffer.java 2016-07-14 17:31:15 UTC (rev 4211)
+++ trunk/prototypes/java/src/org/openlcb/implementations/DatagramMeteringBuffer.java 2016-07-14 17:31:36 UTC (rev 4212)
@@ -1,6 +1,5 @@
package org.openlcb.implementations;
-import edu.umd.cs.findbugs.annotations.SuppressWarnings;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.Timer;
@@ -34,7 +33,7 @@
public DatagramMeteringBuffer(Connection toDownstream) {
this.toDownstream = toDownstream;
- new Thread(new Consumer(queue)).start();
+ datagramComplete();
fromDownstream = new ReplyHandler();
}
@@ -42,7 +41,8 @@
Connection toDownstream;
Connection fromDownstream;
MessageMemo currentMemo;
-
+ int timeoutMillis = TIMEOUT;
+
/**
* This is where e.g. replies from the OpenLCB
* network should be returned to.
@@ -52,18 +52,43 @@
}
BlockingQueue<MessageMemo> queue = new LinkedBlockingQueue<MessageMemo>();
-
+ int pendingEntries = 0;
+
+ public void setTimeout(int timeoutMillis) {
+ this.timeoutMillis = timeoutMillis;
+ }
+
+ public void waitForSendQueue() {
+ while(true) {
+ synchronized (this) {
+ if (pendingEntries == 0) return;
+ }
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {}
+ }
+ }
+
/**
* Accept a datagram message to be sent
*/
@Override
public void put(Message msg, Connection toUpstream) {
- if (msg instanceof DatagramMessage)
- queue.add(new MessageMemo((DatagramMessage)msg, toUpstream, toDownstream));
- else
+ if (msg instanceof DatagramMessage) {
+ synchronized (this) {
+ ++pendingEntries;
+ }
+ queue.add(new MessageMemo((DatagramMessage) msg, toUpstream, toDownstream));
+ } else {
toDownstream.put(msg, fromDownstream);
+ }
}
-
+
+ private void datagramComplete() {
+ currentMemo = null;
+ new Thread(new Consumer(queue)).start();
+ }
+
class ReplyHandler extends AbstractConnection {
/*
* Find the current handler and have it handle it
@@ -106,8 +131,7 @@
timerExpired();
}
};
- timer.schedule(task, TIMEOUT);
-
+ timer.schedule(task, timeoutMillis);
}
void endTimeout() {
if (timer != null) timer.cancel();
@@ -130,16 +154,12 @@
public void handleDatagramAcknowledged(DatagramAcknowledgedMessage msg, Connection sender){
// 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);
+ // not for us
return;
}
endTimeout();
- // forward message upstream
- //toUpstream.put(msg, toUpstream);
-
- // and allow sending another
- new Thread(new Consumer(queue)).start();
+ // allow sending another
+ datagramComplete();
}
/**
@@ -149,8 +169,7 @@
public void handleDatagramRejected(DatagramRejectedMessage msg, Connection sender) {
// 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);
+ // not for us
return;
}
endTimeout();
@@ -158,21 +177,22 @@
if (msg.canResend()) {
forwardDownstream();
} else {
- // forward upstream to originator and let them sort it out
- //toUpstream.put(msg, toUpstream);
- // and allow sending another
- new Thread(new Consumer(queue)).start();
+ // allow sending another
+ datagramComplete();
}
}
}
- static class Consumer implements Runnable {
+ class Consumer implements Runnable {
private final BlockingQueue<MessageMemo> queue;
Consumer(BlockingQueue<MessageMemo> q) { queue = q; }
@Override
public void run() {
try {
consume(queue.take());
+ synchronized (DatagramMeteringBuffer.this) {
+ pendingEntries--;
+ }
} catch (InterruptedException ex) {}
// and exits. Another has to be started with this item is done.
}
Modified: trunk/prototypes/java/src/org/openlcb/implementations/DatagramService.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/implementations/DatagramService.java 2016-07-14 17:31:15 UTC (rev 4211)
+++ trunk/prototypes/java/src/org/openlcb/implementations/DatagramService.java 2016-07-14 17:31:36 UTC (rev 4212)
@@ -38,7 +38,8 @@
this.downstream = downstream;
}
-
+
+ public static final int FLAG_REPLY_PENDING = 0x80;
static final int DEFAULT_ERROR_CODE = 0x1000;
NodeID here;
Connection downstream;...
[truncated message content] |
|
From: <br...@us...> - 2016-07-15 05:09:59
|
Revision: 4213
http://sourceforge.net/p/openlcb/svn/4213
Author: bracz
Date: 2016-07-15 05:09:56 +0000 (Fri, 15 Jul 2016)
Log Message:
-----------
Updates to 0.7 version of the library, regenerates JAR files.
Modified Paths:
--------------
trunk/prototypes/java/manifest
trunk/prototypes/java/openlcb-demo.jar
trunk/prototypes/java/openlcb.jar
trunk/prototypes/java/src/org/openlcb/Version.java
Modified: trunk/prototypes/java/manifest
===================================================================
--- trunk/prototypes/java/manifest 2016-07-14 17:31:36 UTC (rev 4212)
+++ trunk/prototypes/java/manifest 2016-07-15 05:09:56 UTC (rev 4213)
@@ -4,9 +4,9 @@
Name: org.openlcb
Specification-Title: OpenLCB
-Specification-Version: 0.6.4
+Specification-Version: 0.7.4
Specification-Vendor: OpenLCB group
Package-Title: openlcb
-Package-Version: 0.6.5
+Package-Version: 0.7.5
Package-Vendor: OpenLCB group
Modified: trunk/prototypes/java/openlcb-demo.jar
===================================================================
(Binary files differ)
Modified: trunk/prototypes/java/openlcb.jar
===================================================================
(Binary files differ)
Modified: trunk/prototypes/java/src/org/openlcb/Version.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/Version.java 2016-07-14 17:31:36 UTC (rev 4212)
+++ trunk/prototypes/java/src/org/openlcb/Version.java 2016-07-15 05:09:56 UTC (rev 4213)
@@ -26,7 +26,7 @@
* Minor number changes with change that
* effects interoperability
*/
- static final public int minor = 6;
+ static final public int minor = 7;
/* Specification modifier - updated periodically
*/
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-10-23 14:18:44
|
Revision: 4215
http://sourceforge.net/p/openlcb/svn/4215
Author: bracz
Date: 2016-10-23 14:18:40 +0000 (Sun, 23 Oct 2016)
Log Message:
-----------
Merge branch 'master' of github.com:openlcb/OpenLCB_Java
Modified Paths:
--------------
trunk/prototypes/java/README
trunk/prototypes/java/build.xml
trunk/prototypes/java/src/org/openlcb/cdi/swing/CdiPanel.java
Added Paths:
-----------
trunk/prototypes/java/lib/jacocoant.jar
Modified: trunk/prototypes/java/README
===================================================================
--- trunk/prototypes/java/README 2016-10-23 13:03:48 UTC (rev 4214)
+++ trunk/prototypes/java/README 2016-10-23 14:18:40 UTC (rev 4215)
@@ -14,4 +14,4 @@
Authors include:
Bob Jacobsen jac...@ma...
-
+ Paul Bender pau...@ac...
Modified: trunk/prototypes/java/build.xml
===================================================================
--- trunk/prototypes/java/build.xml 2016-10-23 13:03:48 UTC (rev 4214)
+++ trunk/prototypes/java/build.xml 2016-10-23 14:18:40 UTC (rev 4215)
@@ -2,7 +2,7 @@
<!-- Bob Jacobsen, Copyright 2009 -->
<!-- Revision $Revision: 370 $ -->
-<project name="OpenLCB" default="run" basedir=".">
+<project name="OpenLCB" default="run" basedir="." xmlns:jacoco="antlib:org.jacoco.ant">
<!-- basedir="." means all paths are relative to the "java" subdir. -->
<description>
@@ -27,6 +27,7 @@
<!-- set global properties for this build -->
<property name="source" value="src"/>
<property name="test" value="test"/>
+ <property name="coveragetarget" value="./coveragereport"/>
<property name="target" value="classes"/>
<property name="jartarget" value="."/>
<property name="doctarget" value="doc"/>
@@ -46,6 +47,52 @@
<pathelement location="${target}/" /> <!-- last to check for name collisions -->
</path>
+ <!-- Java Code Coverage -->
+ <taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml">
+ <classpath path="lib/jacocoant.jar" />
+ </taskdef>
+
+ <!-- fileset for the jacoco targets. -->
+ <fileset id="jacocofileset" dir="${target}">
+ <include name="**/*.class" />
+ <!-- Exclude classes necessary for testing only from the code coverage report-->
+ <exclude name="**/*Test*.class" />
+ <!-- Exclude testing infrastructure classes -->
+ <exclude name="**/*Scaffold.class" />
+ <exclude name="**/*JUnit*.class" />
+ <exclude name="**/*Demo.class" />
+ <exclude name="**/*Mock*.class" />
+ <exclude name="**/package-info.class" />
+ <exclude name="org/openlcb/FakeConnection.class" />
+ <exclude name="org/openlcb/cdi/jdom/SampleFactory.class" />
+ <exclude name="org/openlcb/cdi/swing/CdiPanelDemo.class" />
+ <exclude name="org/openlcb/implementations/MockVersionedValueListener.class" />
+ <exclude name="org/openlcb/FakeOlcbInterface.class" />
+ <exclude name="tools/jmri/DecoderDefnToCdi.class" />
+ <exclude name="tools/cansim/CanFrame.class" />
+ <exclude name="tools/cansim/CanSegment.class" />
+ <exclude name="tools/cansim/CanInterface.class" />
+ <exclude name="tools/Timed.class" />
+ <exclude name="tools/Timer.class" />
+ <exclude name="tools/QueueSim*.class" />
+ <exclude name="simulations/NodeIDCollisions.class" />
+ <exclude name="scenarios/ScenarioRunner*.class" />
+<exclude name="scenarios/TwoBusesFiltered.class" />
+<exclude name="scenarios/ThreeBuses.class" />
+<exclude name="scenarios/NineOnALink.class" />
+<exclude name="scenarios/ConfigDemoApplet*.class" />
+<exclude name="scenarios/BlueGoldCheck*.class" />
+<exclude name="scenarios/TwoBuses.class" />
+<exclude name="scenarios/can/TwoOnASegment.class" />
+<exclude name="scenarios/can/CanScenarios.class" />
+<exclude name="scenarios/can/NineOnASegment.class" />
+<exclude name="scenarios/BlueGoldApplet*.class" />
+ </fileset>
+
+ <!-- end of definitions -->
+
+ <!-- target definitions start here -->
+
<target name="init" description="create needed directories">
<!-- Create the time stamp -->
<tstamp/>
@@ -56,8 +103,11 @@
<target name="clean" description="remove compilation results to force rebuild">
<mkdir dir="${target}"/>
- <delete includeEmptyDirs="true">
+ <delete includeEmptyDirs="true" quiet="true">
<fileset dir="${target}"/>
+ <fileset dir="${coveragetarget}"/>
+ <file file="jacoco.exec"/>
+ <file file="junit-results.xml"/>
</delete>
</target>
@@ -103,7 +153,7 @@
<classpath refid="project.class.path" />
</javac>
</target>
-
+
<target name="run" depends="compile, tests" description="build and run test suite">
<java classname="AllTest"
fork="yes" >
@@ -113,6 +163,33 @@
</java>
</target>
+ <target name="run-coverage" depends="compile, tests" description="build and run test suite, generating coverage report.">
+ <jacoco:coverage destfile="jacoco.exec" excludes="org.slf4j.*">
+ <junit haltonerror="false" haltonfailure="false" showoutput="yes" printsummary="withOutAndErr" fork="yes" dir="." timeout="3600000">
+ <classpath refid="project.class.path" />
+ <sysproperty key="java.security.policy" value="lib/security.policy"/>
+ <sysproperty key="java.library.path" path=".:lib/"/>
+ <test name="AllTest" outfile="junit-results">
+ <formatter type="xml"/>
+ </test>
+ </junit>
+ </jacoco:coverage>
+ <jacoco:report>
+ <executiondata>
+ <file file="jacoco.exec" />
+ </executiondata>
+
+ <structure name="AntTestReporting">
+ <classfiles>
+ <fileset refid="jacocofileset"/>
+ </classfiles>
+ </structure>
+
+ <html destdir="${coveragetarget}" />
+ </jacoco:report>
+
+ </target>
+
<target name="bg" depends="compile, tests" description="build and run Blue/Gold test">
<java classname="scenarios.BlueGoldCheck"
dir=".."
Added: trunk/prototypes/java/lib/jacocoant.jar
===================================================================
--- trunk/prototypes/java/lib/jacocoant.jar (rev 0)
+++ trunk/prototypes/java/lib/jacocoant.jar 2016-10-23 14:18:40 UTC (rev 4215)
@@ -0,0 +1,5096 @@
+PK+\xD3$L\xBD\xF2\x938\xEC\x97\xFF\xF3\x85̾~\x98?\xFF\xA0\xDD8\xCCK\xFFo=\xAB\xD7\xDF\xF8G\xBF\xF0S\xD7/\xFF\xF9R\xBA\xC9?AX=\xFE+\xBD\xE8\xFC\xAB\xD4\xEA]\xE2dq辘\xA8\xD5\xF0\xCF?\xF0\xC2=\x85\xFD(\xDF@\x8D\xFD\xB6.\xBF|\xFB\x87?\xFF\xF8\xF3\x8F\xB7G\xBF)\xF8\xFD\x81W+\xF4\xCFN\x884\xD5\xBFWV\xB7\x99\xBD] \xB5.\xD3d\xFF\x9F1L+\xBF\xE8\xB58\xC6\xD9\x90\xFC\xEA\x94yz\xAF\x94Ux\xF3\x87\xE7\xA1Q2\xBA\x82\xF4Nٝ\xDEt6-G\xCEg\xD2\xCA\xC6x|x\x9E~S\x81\xAA\xF0}@\xCC\;6\xEC"\xB4\x9D\xD8\xC7\xD34{1\x9Dr\xE6\xF9\x833{\x9B?e\xEBj{\xB9\x9D\x89`\xB3>\xD7\xF2\xACvUr+\xFA\xB6\x87do
+{\x83%\x86\xA9\xAF\xD7\xF9\x8B+\x94\xAA:\x8B\xBB3\xF1\xDB\xE1\x83\xD9]et\xE3\xF1i\xEB1\xCB<[zF\xE1T\xB2l\xA2*\xFD\x8C<3\xF9\xAF2\x8D\xDF\xFFڋ\xF4_|\x9D\xE4\x83\xF3\xDDL`fZ\x99\xA7\xB6\xBFC՚X\x9E\xFEP~b\xA7ح$\xD2/\xB8`p\xC1\xC6\xE8\xD8ۣ\xF0\xA5m\x98\xDDV\x88N\xC5rpk\xCB^\x9F\x9Bwz\xDFb\xBBSdun\x84e8f\x82\xE4l\x9Cau\xC8@0Ҵ>!~u\xD8ҝ\xD9N\xC8}\xA0\x8Do{#\xCA\xCF\x97N\xD4\xE6\x99\xC1\x97]\xAA\x95\xA4z\x99/S{\xE6P\x8E\xE0\xD4"s|.-{\x89\x99e\x96\xA3%\xE5x\xF6P\xEA<I-\x80\xCEw\xA1fZl{\x8B\xEC%q\x9D\x89]\xF5\x83\xFFm\xB2\xAC\x9Aڦ\x83\xEBȉt\xDA\xD8$\x93\xCC|\xAE\x927\xBB\xC0F\xC4\xEC\xDDL\xAFnƫ\xBC\x9F\xC5V\xB0HQ\xA8O\xCA\xCC\xD5Xw{LvN\xE5\x88,=\xB6\xE9\xE1ā\xBB\xE9_\x87\xB1/f\xA3\xA7\xB0\xC2\xD6ەҡҊ\xE3q*\xB9"\x81\x97mtd\x9F\xE0\xC8Ѧ\xC0\xDD\xF7\xBE\xBE\xE6H\x8E\x9Bc5l\xD3\xCAr\xA9*\xF9R\xC7THg]ZN\xBCv\x92l\x80\xD3{\xD5s.=fSJ"ci\xB8\xAB \x85\xBB\xA4\xF2\xCD\xDF]`\xDC_1\xED\x88+*p\xD0a\x96\xEE\xBCu\xEB[\xC5&\xF4\xCDV(#\xE8\xF2]\x87Ű6u\x9B\xD4{\x80\xD3$|\xD0s\xD4o\xF1K\x9D\xA8\x8A\x8E;]\xB9к\xF1\xD3\xDE\xE9\x8C,㪗}\x94T\xA6\xA3-\xA5\xB3\xB4\xF0P)\xB9\xF2\xC3\xAFv_\xED\x8D+\x88\xD1\xD2y[\xF1\xEA\xC8#\x86\xFA\x9B\xF1\x98\xE3k\x9A\xC7\xE9fuӽ09\xFB\xBC\xAE/\xFC͌Fd\xA1\xF6#P\xE2G \xE2\xEE\xC40\xE25c\xF0d\x9E\x815\xED\x8A%z\x9D\xA9RC\x9BUM\x8F\xF8\x84\xB7S\xBDc\xD0I\xEB\xBC\xCD\xC2&3\x9B\x95
+\xE1Z!\xD7\xA3\xBD\xB4%M\x9Fޛ>\xC2(\xFF\xEEX*\xCAV'|\x95\xA8"kS\xDE\xE9\xA6;[\x84\xB4\xEB\xA1Wf?eD\xBF\xE3\xAA_+9\xDE\xE4\xD0PR\x91\xD5\xF8uv\xC56\xF3\xA7\\xF3#\xEE}E\xA4\xDEt\x84m\x98vP.']&\xC9r\xE5\xCB%\xB0\xC0\xE77M\xC7\xEC\xF6O\xD0\xE2/\xDEnl1\x8C\xA1ӓ\x9D\xBA#\xB4\xD7-Ûy\x97\x84y\x99\xCFY\x91\xAF\xC9<܌\xA0\xD2\xF7&)a\xCE\xBC\xC9\xCF\xF0\xABa\xBCEl#\xA7ڰj\x83\x87/\xBD\xFA\xAF\xA1v\xDE`\xBB'Bj\xFCn\xA8\x95\xFC\xB4\x97)u\x95ו4&\xC2..6G1m\xCC\xF5ڌ\xADhd1\x87.\x83'#\xC1\xFB\x9BvL\xBC\xBEn\xF39p+W\xFFx\xD6/a\xEC\xFD\xBC\xCB)\x9BM\xD8\xF4:C+\xDF\xED\xD7н\xD0\xFB/A\x9C;jN\xE4\xE4@\xDF
+KW\x8D\xA8"\xAAˠ-\x92!\xB2\xBD\x9C͇0\x97\xEA\xB8
+_\xA2\xA25\xFC\x8BN\xAB\xA2{\xF9yp2#öTmнN\xB6\xF0
+$\xD7z=\xA3\x99 gEt\x95o<\x9648\xA6\x93\xC8\x9F"Ⲯ\xEC+\xE4\xD6\xC4䬅A\xEA\xBDg\xB5\x9D\xAC\xAE\x86\x94y\xA3\xCEЭ*-\xF7\x81e.\xDAnE^\xF2\x83}\xC5ی\x9A\x80\xC1\xDFi\xC3 \xF7f\xB1\xEBּ\xF8i\xD1\xC6t\xE3:\xB4\\xF3\xB6ATaD\\xDEl\xCF#2u\xCB^\xA7G\xB1\x96\x89oG5\x8F ja\xDB݈M\xA5\x88>do\xB4\x82\x9FӦ\xA2$\xC9\xEAT
+1\x9C|o\xDE\xEA]\xA7\x8D\xC4\xC9\xAF\xF7\xFF\xC0\xF5\xB8\xAE}\x91\x92\xC1\xF9D\x99(\xB5,;36y\xD6V\xADBD\xEDi\xF6kP\x87\xD5j\xAD\xBA\xB8)\xE8\x80J\xE0ҷE\xF0z\xD2\xC1\xBC\xD3\xE7\x8D\xF7Cy\xEF\xB6bp\x86\xB2\xF5<Z\x93\xB431\xACk\xBD^v\xEC\xF2\xD7E\xBC\xCBtܶ\xC8\xF0\x96\xDF2\xB0\xAD\x8B'{\xA90.vܚ\xD2Vf\x8B\xE7\xF9&Vo{·I\x80\xCE8d\x8BI\xB2*\xE1-\xA0\xC4\xA9k\xDAicyo\x95%\xBF\x98`-t\x91\x98\xE5Љa\xE1KӬ\xBD\xC3J\xD7X\xB2̦\xF4w\xC1\xD3+\x9D\x9D\xE4\xF68*JP\x896*y{\x8B\xF9\xB8;\x91\x81#\xDD\xC2\xEB`\x84g\xFC\xC0Q\xBE|p\x96ʎ\x8F7>)\x98hO\x9B
+\x82&\xE21\x8EGb\xF2wQT\x93E>եv\xBA\x93\xC0{\x86fݍշ&~\xF19Z\x93lv0\x81\x84,\xC3 ֥}0\xE4\xA3\xEB\x92s\x90A;H \xA7/\xEE\x8DQ7\xD5\xF5j^\xA6\xE5\xFEA\x95\xBE\x91v#2Y5Ah\xA9g-\xBA>\xDD6\xD1\xDEf\xAC\xF0v\x88/#\xD1\xCD]j8nTj\xF6i\xAB\x84\xEBf~\xE0\xC0\xEBJ7!\x9C;/\xE1\xE3NI\xCDO\\x97\xA9]Յ\xBF\xF1\x93;fY֔\x97\xC7n\xAF˸\xC1w\xCEA\xA9\xA9\xDFF=z*\xB8\xBF\x9F\xE2w\xE1\xB1:\x9B\xE5\xE6\xC8hF\xBA
+\xB7Y\xDBJ\xB4Z\x80\xA7
+69v\x87\xFEڷ\xFD82\xF3!d\xAF\xCEɲ\xD1|\x86\\xA5\x86\x84rpFC\x86\x80\x94\xF4),\xF7\xD7\xEBwÎ\xEBa͐M#\x9F\xE3-\xB0\x88\xD53\x98\xEDהZ\xA3Y\xFF3a\xFFw\x85s\x8A~Q\xA7\xA3;\xA0rN/\xDB\xED\xA9\xCE;`\xBB\xDBl]\xF8+\xAA\xA5gS9\x98\xEFk\xFA\x84\xBE\xED\xE8\xE0\x8AJ0\xD8\x89\x83)vjD') K\xCCbYH\xFAq3\x95\xBA\xFC\x85\xE4y#\x8C\x9C\xB3YU*\xA5*\x83괄\x8B\xF6R\xEEgu\xA2p\xE2\xEF\xFC-2\xE5\xA5mO bFi\x9C\xE3\xF0\xF3ۂ?6\xD3\xDBl\x8C\xF7\xFC\x9E
+S_\xAE\xC7/Fm\xBE7\xC8\xFAl鳵v\xBA\x85\x92\x9E\xACOrS\xCF\xC1\xF9gR\xE1\xDD\xF1\xAF\x8C\xF93֞\xCDÕ\xCDg\xC5L\\xD5~D\xD2iSg\xB3τ;\x8F<\xE1+\xA2\xA4
+G\x94r\x95-\xB8\xC8ۛ.\xB7h\xE7\xBC\xAA\xE4\xDE^,\xAA\xA7\xD2H#q\xDC\xC8d \xB1\x8Bzs\xBB\xE6X\xE9j\xA6\xF5\xEE\xB0\xEF\xEC\xADC\xE74\xF3\x8EX\x99apm٭\x90\xA4T)\x93\xBB \xC0Ao\x88Ay\xC1\xC1\xB8~@\x99a\xECW\xF3\xB3\xCC`aQ_[\xF8xHs\xE0^\xD44\x85?"\x96^\xB8\xDBI\xC7\xD9{\xEDCC7\xD9\xF7\xC8\xEEV\xD4Y7\x8F\xB9\xA3;\xDF\xF3\xB0\x85\xC3;\xBCD\xBF\xAD\xFC\xCB%\xCBCCF,e\xA3\xF7j\x82\xF8Lx\xF6\xDD"\xFDZR\xC7.,\x92\xA5q$\xCÈB`\xF6\xB3\x8Do-\xCBdv\xD8\xC0\x9A\xE6|\x82sw\xB0\xF7Y\xA7R\xD0\xD9~\xAD\x82+R\xA7!_\x9B\xEC\xAA+u\xC7\xE7\xBE\xF0|I\xC5#\xA2\xD0S;/O\xD9\xF0,0\xB6[\xEE\x80s\xE2\xA0nwJ\xC5]p\x9E \xBF\xFF|p\xCBm\xEF߸\xCAO\x86\xD5Oױ\xCC
+\xAC݊ew\x89E]\xD7\xD21)\xA62\xF7\xB2WF-6\x92W&\xAD\\xD4\xF5\xB2\xF1\xE0_972\xF2\x98\xF7\xFE\xE2e\xEC\xEB\xFF\xF5l?\x8Da\xE6~|:t2\xB8 B\x94\xAEAщ\xD2\xF5\xDE2\xE8|\xDEcׇe5\x8Fxr\xB3;\x99\x8F\x98I\xE7Hg1 T\xB98F\xF1R\:\x9DRˎ@^\xCD
+\xA8JO\xB4U$\w\xA1b\xB3(
+tL4\xDFF~\x9A~
++\xF749\x83QfM&\xB0ą\xC4:\xD6\xE7\x8A\xC8%\xD1\xF1\xF3\x92\xA2\xFA\xBD\xAA\xA5U
+/\\xC8p
+\x81\x99'T\x8B[S\xA1\xAE\xC6f\xCE\xD6 \xC6\xD0e\xBF\xA4\xF2\xF4\x9B\xC5\xDD%d5߇7\\xACW2\x91\xCA\x8A\xDDi\xC3=ǭ\xB0;2 !t0\xF7\xBDT\x9D\xED\x8EN\x9Dj\xE4T\xF8]\x9A\x99ԍ\xB7Xp*\xDB\xDC\xD0Q\xE0\x9DD\xAA
+J`LJ\xD9~\xB1\xB6B\x83\xBD\xDF \xA6\xDET\xF7o\xA3<P\xA6\xB6\xCF<\xF6\xBAoc\xE4@\xCC6\xA0\xBDʏ܃\x98eQ\x9D?!hKI\x8Fuel!^\xCF\xCE\xD5#\xB6\xD5 ނ\x8C\xFA\x94\xCB|=\xA4\xD1\xE1\xE7\xE4`\xAB\xA5>\xD3\xB5i7\x80\x88TmE\xA5<JF\xFDp:\xC3 \xED\x95\xDA[\xE3n\xA8\xC53i\x9B\xE1>*9\x82b)}\xA2\xDC\xE5\x87\xDB_\xDF~\xE8\xCF`|\xF7\xBDj\xEE\xC9\xFBD\x97]@\xCF\xF0\xB8
+V\x9A-͛\xEE\xE2\x8D\xEE\xFA=\xAA\xFCG
+mO0X\xDB\xD0j@h8ou\xC02\xF6\xC6|\xA6{\x9B6\xD4CrE\xD8ń\x8Ac bj\xB5\xB7.95=\xC7\xEC\x95\xDB3/\x85\x8E\xEF\xA1\xD8\xE7r5\xBF\xA6q\xF5r\xC5I{\xB6\xD9\xE1\xF9-\x87\xAFZ\xD5\x9A`\x85&L\xED\xDA`\xDD^v\xA7W\xFD \xF9\xC10\x97ARG\xDA`[)\xAEYg\xEDf2ؖ\xDCK\xE1v\x9A\xBFe$^+]\xE2ͮ\xF5u)V\xFC\xA7_\xFE\xB5+`\xF4\xDD\x9B<\xD1ӊwx\xEClb\x92bv\x88\xA5QUZ\xFC\xE8\xF8\xBFËr\xCA\xEF#\xCDJr\xE6K\xEFJ6\x941xZ\xAD\8u\x92Y\xFDI\xF1ס{Oڴ\xC09!\xB7K\x9AVt\x82c\xFB\xFD9\xC0\xF2Ӌ\xB8\x9FfY\xF5"e\xCF!'e\xBE3;\x88d@\xEE\xA1\xC6bP\x89!\xD2
+|\xDE<B\xDBu\xFFӷ\xE2\x98\xE1|@&\xD1\xF3ȻbgcYCN\x80\xA0Ln\xD2h\x8E,\xE9]\xB5\xE1\xF5\xF1Sf&T\x85\x9A\xAF3\xD8<xj\xCD\xD2\xEC|\xCD|"uO4\xF9\xE3\xF0\xE6{\xF7\x9D\xBB|XƑ\x96^BV\x81\xCB@B\xA3\xDA\xCD[\xDE,$\xDF\xFB\xB9;\x91sb\xED{?\xC1\xAEuWR\xC2\xD3پ\xBBlp\xA1]l|\xCBZ9\xF7Y\xC7l\x8F\x96Wkf\xDD@Ke_\x8A$\x88\x8E\x9AP\xEADp\xF9{Y\xEE\xBC\xF0\xAB*<\xF62\xFC+\xE8k\xE3\xD5\xC9ٱ\x9Ab/\x96)\xD7m\xCB "\x84w\xF6
+xӤ=sg\xEB\x95\xF0\xAA5\xC73\xA2\xDD\xEC\xD3^\x9E\x97\xC04'\xF0\xE8d6u\xAF\xEB\xE4\xFD\xC7Q逶\xF9Jm\xF3X\xE7\xCC\xDD@U\xC9ZuR\xAC\xA9\xA2[?8\xAFJ\x98a\xC4\xCB\xF8(\xB4[ӦCq\x85N\xDB\x90O\xF6[5ݨ\xEFR\x91\xB9u\xE1oT7\xF9\xBA+\x8D(\xA0֮\xCBa\x82\xDFTw:-\xE6\xFDq\xD43tN58\xF43\xEC\xD90G\xDB\xF5\xCD3q(\xAB\x905n\xB3\x9F\xA3\xE6i\x82$\xB8\xD7ݪvu\xF1\xBCKȔ<hhuM\xE1k1\xF1=!W\x98M[\xB8\xA1\xCC\xEDH\xB9\xEA9h\xB5\xB3C\xB7\xA66\x9C\xC49\xCḀDɟMě\xA3%\xCFXku\xAE\x82\xB0\xB5\xE2\x80ӗ\xC9mV\xF3Y\xF7Q-\xE4\xC3]N\x82\x8B\x8E\xBA\xE0Q\xDCQ\xE6f{}\xD3\xF38$\\xB3\xBF\xFE=k\xF6ַ\xF6K\x81\xC1"a\xC0&_\x9D\xAFl(
+\xB0\xD2\x9B\xEE\x88A\xF3\xA3\xF7\xEF\xFF\xC2\xD0\xDEW0bk,\xDC \xC9[S+\xE6ܘ|\xD4,\xCE\xE6\xDC\xD3v4\xA2\x9BC\xC8B\xCER\xFFI`a\xDCn\xE8\x92ܽ"9\xB3\xE2\xF4\xB9e,Q\x82\xCB\xE9\xCF\xAA\xEF\xB1\xD9\xCEEh\xC81b\xEC\xB6eu\x9C\xDA\xD1i\xAEь\xDEl\x9D\x89j\xDB\x9A\xACW\x83\xC9\xF3Wm;f˙#gm\xB3\x90P41\xC2nqA\xCE\xD7\xE9^\x8EG \xDE\xCB&\x87\xCF\xC4'+\x90\xC2\xFD\x88S\\xDFf\xE4\xA8ڧ\xBE\x92\x8B맛\xA8\xBE\x83\xB0Q
+9oS!8\xB1]\xAC\xB7\xA2[\xCCBܭ֙Q\\xF4\x99\xBC\xCFc\xB6\xD7|\xC0\xD8L1&n\x92e\xB2\xB91\xAD\xC9;\xE1\xB8\x92{\x8A.\x87\xFDD7ϯr\xB6\xB6UP\xC3)_\xE1+$\xAF:\xE4\xC7n2\x91\xC9\xF8վg\x85\xAA\x89\x94\xBB\x93+,\x8B4砧\xA0\xF7XU\xCA\xF0=+\xF2eK\x991b\x9Av(N&\xE9\xFD\xD8E#Nk*\xC8*.\xDEU[\x9D`\x9E\xAF\xD2^\x8B7\xBF\xB9\xA0\x8E"\x8A\xDEﵸ\xBET\xEA\xE6C\x95\xBA\x80\x98\xA0םx\xA1\x97\xDA-W#\x89?\x9Bg\xD4\xD3Э5\x99ޅ\xF790\xB3(\xD8*|\xE2\xB4ۚ\x84\xA8+Y\xF9BD\xAC۵\xFC\xABR\xEE\xE4\x9B\xFB(\xFC\x99\xEE8\xDED\xD0\xF8\xF3h\xAF,\xF7
+FI\xB6 +\x87\xEB\xD8y5ϭ/a\xF9!+:q\x8B\xCF!ܝ;\x96\xDA\xC2J\x84\xAF\x91.\xC1>\xB10-WST\xC9P\xF00\xB4\xBD\xCC\xC0TPV\xEAF;\xEF+G\xFF\xE4\x8F\xDEw\x8C\xFA\xA5\xCB\xFE\xA4\xC5NEZ"\x96\xA2%\xBA\xDC-.\xBEy\x9E\xBBV\xE6\xFD\x9DS(\xD6\xCEJ\xB7b\xE6\xD85o\x8B;\xD4\xF3\xEA\xCD@=!P\xDF\xFA\xB2y}åw\xAC8yY\xD7.d2\xD8 D+\xEAR\xD6\xFB\xEBA\xE1\xA2l>\xEA2{\xA4\xDD\xC7v\x8A<\xEF\x8F;g;i\xB9\xC2+a\x8B\xAF \xB0Ju\xEC\xF6\x86G"\xF1qڼ=\xC2W\xAA"v\xAD\xBA\xEB\xF5\xB0\xCE+WgUé|S\xDF\xC8\xFFKfiX\xAE\xD0~\xBAfv\xCA\\xE1Յ_*\xB4\xEF\xE5m\xB9"O\xDC\xD3\xF1\xCB\xE6\xDF\xCB\xFD\xAA^\xC2^\xEE\xF6^\xA5\xD1K"d \xC1\xEC[\x91\xA9\xEA|G"\xEA\xE7\xF951\xF2\xA13B\xD3dA\xA5\xEA\xC2V˯\xDEiK\xCC")g94\x8D\xB0_\xF2\x9Cf\xF1c1\xE5\x84y9\xCAs\xB3\xEEm\xE05J7K\x9AM\x96\xAE\xE0Ԭ\xBD\xCD\xC4߬X\x9Ce\x9E6\xACw\xA07V\xB1\xB2Vzì\x8B\xA6\xAEW(:vU\xC8`C\xF8pBx\xEF\xBA\x890I\xDA\xA2\xF4p\xF6
+\xD5NǤ\xE0.\xC5i\xF5\xA8\xE9\x99\xC2\xE9v\x90\x9B8\x99w\x87.\x95"P\x967b\xB7,Q\xAB }\xD71\59\xF1s;aD\xB8*9\xE5\xA6\xEA\xA1\xEE\xDF\xEC\xCF\xF3\xAB)\x8E\xF4\xB6\xA5/\xE4\xE0\xCDPq\xB1\x8A1>\xC2h\xBD\x89\xE7\xA49Q\xF0\xFA\xBD\xA70\xA4pV\xBBSYC\xAC+\xB8^ \xAC\xB5\xED\xE0\xAA>-<\xD7,\xC7\xFDd\x8C\x86\xAB\xA6fx!fVv\xF4*X.h\xB8\xB8Z>t3vb\xFD'\x98\xE3B\x969ܵ\xDB\xCA\xE8\xA2\xD5\xA3\x9F\xE6\xCADOŐ\xDF\xE1AU\x84i\xA0fٰ1\xB5\xC9.\xF7rMb\xD0\xCC\xE7\xF5y\xBB6Q!\x97\xF2&\x99\xB2\xAFw\xA7}x!\xDCQZ1\xA5>/6!5_^\x8E\x90\x99K\xFD\x92\xD1\xCA\xD3?s?\xF8\xC2\xC9X\xE2<'\xE1kb\xB0ڲ\xBB\xE5=\xDF\x8F\xDA\xC51\xAFh2q\xEB\xCC;h3\xFD\xC0)ZiC\x96N\xB2C\xAD\x8Fpup(%\xFA\xBD\xFC_\xF20,C\x81)F\xDB\xDE\xE2\xB9U\xE0Y\xC0\xD6\xE5\xAD\xB1\xFE\x9E=yK4\xB3ĩ\x84l6%\xC66\xD9\xD6_7nޮ+\xAA\xDE緱\x86\x95\x8F"\xEEDž\xBFˊwW\xA9\xA6\x92-\xDD$᥊r\x99]a\xE1\x911U\xBC\xF8sA\xFB\xFD\xEB\xD4\xE5\xB40\xCE\xF0-7 D"C\xB0\xAD\x86i\x9E\x9B\xDAG\xB5\xDF\xEBL.O\x97O\xE3gw\xA1\xDBYB\xB3\xC2m\x8E\x88\xE9\xE4\xDEs
+\xEF\xEFU\x9C+A\x9F(h\xFAZ\xC9\xF6\xF9\xCE\xDE\xF7\xA9\x86)\xA8\xC2̙\x9D#\xD3W\xB6\xA8\xCC\xC6;\xB2\xF4E@\xB7\xF4\x96X\x8D]\xDD\xFAA\xAAa\xC4T\xB6֙@S*\xA4\xAE6\xCF\xE9&\x91ٝAZD\xD1\xFD\x9EM)|o\xB8\xB75\x97W_\x9F(\xB6\xA3\xAD0}k\x93\xFEay\x86\x98 Dw\xA7!\xFB\xEF\xF7\xDF.\xA2\xB5<\xE4z\xC9H[\xA1X\xB3=V\xB8\xF1X\xA6\xF9\x87\x88\xE2\xE5\xBA\xF3\xD7\xDA\xD8a\xEAY+\xB3\xFD\xC1
+D|\x8B\xE6<\xB9u\x86m\xDBO\xA9J\xD2Gpz\xE8M\xEAr\x92\x95o\xF7\xEBR\x98\xF2\x9C\xD0`{9v\xEF\xE1On\xE9\xC7i\x86)\x8B\x831\xDB\xEF1Z\xC0\xC5]|t\xE2]r/{\xF1\xC7:\xEB~\\xD1#$x4h\xBA\xD5= \xEF\xD8\xC9\x84-\x82)\xEDam5d\xB9\xC5V⋨|&\xD0\xFE\xA9hpT
+\xF6\x8Ds\xED\xA4\xCAQ\xEC\xD5i\xB3Y3Bt܊ \xEF)<\xF2\xAB-4F(\x9F[cD\xB4'd\xEB<\x87\x8E\\C\xBB\x98\xEA\xAE\xF1\xC5I\xB86\xA0\xB9\xEAi\xB4ȠV
+k\xD9g\x80\xE8c\x9Bt\xC4\xE8ɭ=\xBB\xED\x8ED\xE6\x9CK\xE1\xB4+\xF1\xADBbF!˧~0\xE1>\xB6I;{\xD7\xF8\xACJA\xCFؙb>\x8Ay\xC9\xE7ǚhF\x92K\xDF$y\xAA\xA0܅f\xA2\xE5ڈ{>\xBA!ǘ\x88k\xD1\xD0ũʘ\x97.\x9AԽr\xF6\xDB\xF6\xB8\xD5\xF3\xDEK\xF3\xF2VЭ\xEB磼X6[\xB1}\xE5Wz\xA9w\x84J״?瘝\xCFO\xE5g\x87\xD1\xE3_\xAFt\xEB\xE8\xDDҋ\xCD\xF3
+\x9CQ$\xB6_q\xC1\/.\xA6\x86\xFA\xF6\x83η6\xE2\xE0mvV{a\xB3\xF13\x8E\xD4M\xA4 1'\x8E\xB5\xCF8\xF8\x97\x8BV\xB8G\xE2.\xEF7x\xE498\xA6(\xDB0\xA3S\xE7\xBA9]\xC4T\x9A\xD3\xFC\xFC91|SԱ\xA2\x8F\xAAt\xE6-3y\xA5\x93\xE2Ɖ\xADM\xB78\x94\x9A4\xC6\xF7\x8E\xF8\x85\xBF\xA0)w\xEAc0\xB2\xBC];4%,\x92U\xC0\xE5\xBC]R\x86\xC6⫉;\x81_J`\x87\xC1\xD6\xBF
+ŕ\xA3\xF0|\xB79\xC8.\xA1\x8B{\xCAy\xE9}\x8E2\xBFKrƨꞨcH\x9F\xD5bh\xE7\xFE3\xCEe\xE3^\x9E:\x80\xC7}!/\xE2J\xF9\xD5\xF8刚Ȧ\x86p1V\xDA\xD9eR\xC0\xC8\xE7\xEE\x9C\x8A\x9E\xBA\xDB\xEAMG&˞5d\x9E\xE6\xAC!\xEC\xD7x\xAD\xA8\x8E\xE4ee2\xA6}\x8EI\xF9\x81\x84Qr\x89\x9C]s\xA6\xE6n\xB5\xB9\xDC.m,]\xE9\xC1\xB4\xAD\xB16\x93G*m\xF4\x8E\x83\xA1\xE2\x97d\x91邬gIZ\x89\xBFMr\xA6\xC2\xD4\xDFki~I\x8D\xA7C\xA9qf.
+'\x9F\xBBUD\xCF\x81\xF6\xEEM7\xAC2\x9D\xAF\xFB\xDE6\xEC1\x86\xD2\xF4\xEA\+\xCArmeM\x8BD\x82\xBB\xA2z*c\xFArO\xC9#tG
+\xEDZ\xA6\xBD\x90*\xEB`+\xADj\xFC\xB6:\xA0$\x97OVֽՐL\xD6\xD6Ͳ=(nQ\xE7FN9)\x9BM\xB4e \xE9\x8A\xEA\xFAo\xD8\xF3W\xFFH\xF7qc5\x9C\xFA\xB5\xF7\xE9\\x82\xB1\x8D&1\xF1(bfP)VB\xFD\xBF\xF9/p~\xAD\xEBj\xCC\xBAs\xA4\x9A\xBA\xACk'\\xA5bK\x8C\xDD\xC8\xF6s\xF6C\xED\xCDd1\xFD\xA2\xA3\x9C\xB3/;\xAE\x85U\x8D\b՜\x84#16\x9F\xEE\xD8x\xF1W\xA3 0\xA5\xDB\xD2\xC8\xE1\xC2IΉ\xDAb\x8A0[P\xF4\xC9g:\:\xF3\xBEM\xED\xF1ĭ\x98-ҝv^f`h]I\xDD&\x8Ecp\xF8v\xA5\xDE7E\xA3\xA9\xA1e\\xAE\xD2n1\x80\xD7š\xF3\xA0- \xD6f-=\x95T\xFB\x80O\xA4\xBA
+\xB8\x91-\xA45\x91K%\xB0A\xC5+z\xAC+\xF85\xF9\xC6`O%#\xAF7\xB8U\xC5T\\x99\xBB\xAAlXI8\xE0boA\xFF\x88?\xEDc\x92\xC9\xD3\xF0uy\xE4\x88v\xDCC\xF3*,\xCA\xF3\xADa\x92\xE9\xBD\xFB\xFFPK\xD2wWo\xC9%+\x87\x96\x91\xAC\xB4\xDEؖf\xE6T\xFE\xF3}\xAC*\xEB\xD2uA!s\xACX\xB7\xCAвc\x97LӬ\xB6\xEEG\xB3\x8B\xFBt\xA7b}\xE4\xD4U\xDF\x94a}U\x9B\xE5\xC9P\xD7X\x9B/\xDC!\x9D%\x89\x95^\x840u\xB5&ϳ\xB2~\xBA\xC9PF\x9B\xB1c\x82}錾\xD2$-
+C\xF9\xFEz]U\xCF7)\xDD\xFBZ?/.\xA8\x93\xAC\xEFG\xBAm\xD9\xDC\x97\xCE\xE2&I\xBF!O\xF7\x95\x83
+CW\x82t\x81\x81$G#\x8E\xF7\xF6\xDB3\xF2o^܀\x89պ)x\xDB\xFE\x9F\xF7\xED~\xFC\xE7\xFD\x9B\xE4Y\xF2O^f\xB9[֡\xFB\xFBv\x80\xB72\xF9m\x8F\xEA\xF9\xBA\x8D\xA3\xF5\xC2\xD0\xFC\x80y\x89\x9A\xB8ç\xC7\xCB-\xFFv\xBA\xFBi\xE4ۧ\xA7\xE7\xDA/\x81\xEB\x86+\xAE͎\x97D\x87\x8CNg\xD8p\x80NJ\xFD\xB4X\xD0\xD9m\x9B\xFE\xF9\xC3.Pf \xDE\xDAg\x9D\xCAY\xB5y\xD4\xE4\x91\xBD"\xCF\xD6\xEDCV\xEF2M\xDE\xFF\xF5&\xD2߶M\x92?\xDDo\xED\x87\xF9\xFAr6wAN\x86\x84\xD5i[\xEB\xDC\xA1\xEC\x87\xE7/\xDCw\xD8L\xEC&n\xFA\xFCT\x84\x8A+\xA7X\x94C\xBCc3\xB1\xE1C.,t(\x8C\xED\xC4ymҮ\xEA\xD2rj\xB6̚\\xABp\xCA\xAC\xBA\xB3ֺ\xA8\xC1A\xB2\xC1OrʔF\xDC/9g\x84f侐\xEAZ\x97 \xE5/tꊭ\xE4\xD4(\x94\xF8`\xC7\xDB+\xEE\xC2\xDD\xD6\xF6*\x8B%#+\xA5՜媳,\xAE\xC0\xBB\xE9߄\xB1+d\x93\xAFp\[T\xBF\xB4\xAEޮ.z{\x9Dx\xDF`.\xA2\xE3\xC4Ӧ5\xC8\xDFᄍ\xE6\xC1\xAA\xA2\xA7\xEB\xEA "9\x9D4\xAC+\xFC,ȋ\x95O=͐\x8A\xF1 t\x93\xF1r\xBD\xE4YV\xB2n\xC9\xEB\xBC\xCDe{\xE8\xF2]\x87\x85\xB0zn"\x80\xB0I:Za\xC8\xC0\xE0\xD8v,_\xB1|\xC1F\xE6z\xBA\xF2o\xA0Uuӛә8\xC6\xCET,\xC8[\x8B&_\xE3\xACqޝ\xC4\xE88v\xEB\xE39즏\xC1\&+\xA1\xB4@\xE7N3\x88\xF7\xF1\xAAw:k\x9D\xAEwR:\xCBs)Yl/b睠\xE8u\xB5&\xA2\xC7\xF7\xBBq\xAA\\xBBwx\x8B\x81\xE7l \x9EKĵK懺\xC4κ1\\xD0 $\xF4>Y\xDF@\xC7\xE1\x94\xEF\xEAۣFd\x87Ѳ\xF7ױ\x86\xB6\xA4\xD1u\xD6N;\xCC\xF9\xAAmxl<\xE1@\xB8\x87\xF3\xF9"\x94\xE1v\xD8\xD8P\x8CZ
+\xEE\xC67^\x8F{\xDF\xE9e>\xC2\xCES\x83蠍\xA9mJ\xE7eA\xD0<\xCB\xD3\xC7\xDB^\xAF!\x89o[\xAB\xB5\x840z\xFC\x93V\xEAL<\xD0\xBA\xA6G=\xF0b\xC6"\xFB\xA4u\x88\x96u\x81J\xDB\xE8\x87\xFAh\x92rˉ\xEEa\xDA]A~\x87_\xE3.A\x86L\x94\xB67\xC5\xE7<U\xF9\x9Av'\xC0\xD0/!5y7\xD4R~ګoRS\xE7M\xBD\x9Fa\xBF\x96\xA2'\xF9\xBC]\x97kq\xA8\xA7\xD7[\xF7\xE0\xCC \xDA1\xF3\xF5\xC9ux\x91\xA5C\x96\xFA\x85\x87\x8Fe\xB8\xE1y\x8B\xA4\xD0~\xC2R?y\xEB\xB70\xF6\xFE\xDE՜\xCDn\xB3v\x97\x9C#\xA9\x97
+\xD5\xC4\x8B\x96&\xF9\xD4ٝ\xB0ٟ\x98\xA7&b\x9BD,\\xDF\x9Frex963$\x85\xA7c"\x82\xDB1\x8B\xF9\xD5n\xF1\xD7!-q\xF36\xC5܍\x9E\xDE\xE9\xEC$\xB7\xA6Qeؤ\xF5\xBAjI\xA7\xF2\xFB\xF5+焕w\x82b\xA3\xE3u\xC7\xF3\xBDw\x89'\xAE\xFD\xA6ݷS\xC1\xFD\xEF\xA0\xFDp[Gd?\x85\xEC\xFEz\xC8S \xAA\x80\xBF\xEAv\xD6c'\x8A\xAF\xCEa\xD3?\xB0ܷ\xF7\x9F\xBA7\xCF\x97\xA80\xBD\xAA\xB7\xA7\xAB\x8F\xE1j\xFC}YTN{\x81\xBA\x97(\xFE':\xF9~\xCC\xE7\xF81\x94\xA3\xAB\xBA,\x88y\x91Y\x8C\x98\xF4t\xFEw\x9C\x9E]\xDE\xEE.\xF0\x9C'2\x9A\xD81ё\xE7\xF4`\x8BX5h\xA7b\x93\x94\xEBg\\xE7=8\x9B\xC4v\xCBI=GKQ\x83h\xBC\x9EwGh]\x80\x8E ;\xE5I\xE4A\xE6\xFC3\xB0\x82\xAE \x81\xDF'\xAB\xF6\xB0`W\xFB\xE0jaE\xB8~Ѵ\xBE\xDD<Մ\xF1˿P\x8A5M\xB4:Tw\x93\xEA\xC8\xBA\xA1@\\xF8+Hx\xF7\xCA\xE0;\xD3\xFCp\xD1O7\x93#\xD0ִ
+\x92\xEE\x92G\xBC\x93Cnzaar6\x97\xAF\xFE,\xB2\x9A\xD0\xC9\WK\\x90,\xD2\xF5|\xE9\x9D^+\xBD/'%\xDFÇG^rb\xB70\xEA\xFD\xAC/͜\x95\xB74\x89S,\xC04K\x830\xF3\x92b\xFEje\x9E\xBA`\xD7 \xE5\\xE4\xD16\xA3A\xF0{\xEB\x84O\\xDE]\xC4P\xE6\xE9ru\xCA\xBD\xDDr5$.:\xA6{l}!ۂ\xF5;\xF3C\xDBY\xB7g\xA2\xFD\xEC*\xE4\xFA\xECt\xFBt\xE4L\xF2\xF69rS\xBAv\xB3\x87w\xBE\xE7a\x9F\xDFp\xAA&\x84(\xA1\xAE\xE7\xE4K\xEB\xF5\x85"\xBDa\xEF\xA8\xC5WL\xC7Ho\xB8u./\xEC&\xA1\x97\x82V\xDB.9\x9D\xC3ǽ\xFAfB\x83z\xD0%\xFCi\x97\xFC\xDBť\xB6U>\xB1K\x9Dd\xB9T#,\xA1Z*i\x88Z`v\xEB<\xE1C)\x85v\x83U\x90=?\xD0i\xE8\x8FMӟc\xDF\xEAD\xD68.*T\xAC\xDB {\xFE~ \xFE\xED\xAE>
+%.I\xC3\xE7\xD0Q\xCCXB\x98W\xE8fY6|\xBD?\xDC\xF0\xB5\x9B<\x8Fo\xA8o]/$7Y\xB9k&vPC\x91\xA9Eŏ\xC2\xF5\xB6̓\xF5\xFF\xE7j\x95\xBF\x83xrl\xC02\xF0ahG\x8D9x\x89x\xB2.W\xA5x\xF8\xC4?\xBE\x9Bօ\xB5̪\x80-=\xAA+\xD7=\xAD\xC0]n\xA2->\xE4\x9B\x99\xAB,yZ7D\x96\xA55h\xF5\xED\x85\\xFF9\xD1TX~\x83\x89\xF4\xA6[u[.pӺh\xB2\xB5z\xFD+\x97\xF7!\xB2ØO+c\xA2y0\x83hܰ͆=\x8C\xFBwT\xC5{\x85ԟ\xE7i\xAA\xE01\xB0\xB9\xA5\xB5Z\x83\xC3M\xEA\x986\x83\xF6\x8C\xF9\xD23\xFD̡\x921\xDFx\x84\xC0\x96\x85\xE1dOs\xDA¨H\xC0쯤c\x9F\xC3iJ\xA0\xF2((\xC1\x96h5\x91` \xC3\x93\xD5\xDC#\xBD\xCB\xF4dʃ0\x9CڲT\xCF\xDET7\xDB%`d\xEDp\xA9u\x8B\xCEҗ\xD8L\xF9\xE6\xBAɱk%\xD571\xA3㬺I\xC1vj\x97\xFB$A\xD0u;\x85\x81,\xD0U\xBE\xE4\xBFr]\x84L\xCFS_ v\x80\x88\xF5%\x93OH\xB1c\xB7Rq\xCA\xFC\xE3zt\xCE3Fʝ\x9B\xB9^\xB33HGɔn\xBD\xC7R\xA8\xC5\xBB\xC0\xB7\xC4\xF8\xA6\xF9\xF1\xE5\xE57H1\xF9\xDD\x8AL\xD6\xA30>\xF5ڦ\xC48; \xE5\xB5\xEFofr\xB4\xFFOxQ\xCD\xF9}\x84\xE87\xAB\xF2HfX\x95\x9C\x82ť\xD8\xECܚN\x80\x9D\xD8\xE6\x99\xE2oB7\xBE\xBCh\xD3\xD0D
+\xD8.\xCB\xD6jQv\xF1\xFAz&w\xAA\xDE\xEC;^\xBAKԛ\x94\xBD\x86\x9C\x90^\xAB\x9D\xEE\xB4K{sl\xACC+w\xA6L\xC2E8\x97\x92|\xC2\xD2on\x9F\xBE\xC7<\x87\xE1AALiBnG\xA3\xC4s\x90\xE3zN\xF7sq\xF9[\xB5\xE1/\xF5\xF1sf\x86Cw\xFE`\xE7\xAA;\xF0\x87|\xDDPۤ\xA94zi\xE0͋$\x8Ax\x87\x81q8\xBA\x97\xFB\xCD\xDD\xFF\xF8s?\x83\xCA49\x8B\xD0Q\xD8I2d\xA3\xB3\xE7<S\xC3Y\xE9%\x9E\xBA\x9ES\xCD\xF7p\xBDy3\xDC-/\xCC\xCC\xFB\xDC^\x98\x94\xFF\xE5"
+k\xB2\xBC\xAAs9\xF9Ҋ\x98tR\xD0\xA3\xAF\xAA\x8CV-(+\xA7\xF4\x9B\xBD\xE1\x8CI\x84\xD6,\xB3\xC6\xDA&ՠڶ\x95aKȣ_\xB5Q?#No\xFC\xDEM
+f\xDF_\xEE\xA5
+\xF4\xD0".\xF0U\xE6\6[\xD9h\x85x\xA9D\x98\xFCG \xDC\xCB&\x9F\xE7+\x92\xB5|bךcva*\xA1\x8DZ\xB0ˣ-Ϋ\xD83\xF0\xFD\x84MjH\xEFS\xF6\xACt\xA3Un04\xAE\xB0r\xEEW\x935_\x86\xFA\xEF\xF9\x80\xA9\x9DZ.\xF5\xFB\xDC\xF0\xF3§bo\xECaC\x8E\xAD\x9B\xF4\x85\xC6\xC4N\x93\xE1\xEB/r\xB6\xB1UP\xCF]io\xAB|!ɜ(\\xFAa\xC9\xF1\xA9 -\xA5̰\xBB͟sK^\xC4\xF1\x92\xF4z\x90\xB85h\xAF\x803\xE5$\xA6cf_)\xCC\xF9\x98Ȟ\xD6\xEB\xF5m\xEF\xC2c\xB6a^\xD4բw\xBD\xE2Q\x9E\xB0\x9F \x8D\xAAiM\xF8\xCB9\xCC\xD7]\xE9\xF5!+[a\x8B"%\xE2\xAF|}\xECs\xD9\xC7\xC8\xC9\xC8\xEB7\xDA\xF2.\xC8/\x97g\xE0z\xA5L=\xAE\xE1r\x91\xB0\x8B5\xDA@pk\xEC\xDFeQ\xD4\xEF\x9F&\xCC\xA4\xC1\xA9-s\xC6¡O.\xB5\x95\xBD\xD0<\xE6B\xC3\\xE1\xE9\x87\xEC\xF8}\xCD\xD9|\xB5\xBB\x837
+\x9B\x99X\xC4\xB59\xEFy\xAA!L\xA7\x92\x8A\xFD\xEF\xF9\xF7\x99\xE6\x90\xCBA\xD2\xCAU\xB1\x8A2\x90j1\x9Ed\x93H\x85 3龟\x85ks\x82̲U[\x9F\xC1@$\xC5DW\xD4\xE8pIe\x82(\xB9\x9Dq,\xB7@h\xB6\x9A\xE6\xB8Lk\xDA\\x99蔗\x82@X`\x96
+\x80Si\xAC\x97[\\xD1焋r\xBAME_\x8C\xC1\xBEb\xDCx\xDETa/P\x9A\xCD\xEF\xF7\x80#\x9F\xF75\x92ǥ\xBBm2V\xE8\xD0\xE9bYK\xA1h\xFF,{#[\xF7\xCCJ=S+\xB0Ii{\xCD\xBEů\xBCK<\x84\xF2̇\x98\xAF8ßZqɺg\xB4\xA1\xA5㪬\x8A,\x85\xDD\xB7m\xBE\x88\x8Eu\xD0s\xC9\xF6\x9F\xCA\xF0k\x8B\xCEs\xBE \x92\x8E\x95\xBAغu\x96\xD2|\x91[m\xBA\xA8ʑ\xCF\xCA\xDD˾МM.\xB7\xD8\xC5V\x8C)\xD8uH8jg\xB9\x8C\xC0\xE6K\xD4\xE7Ou\xFB\xA8ؓ-:9\xE0Vj\x9Dmk\xE9\x80Kڸ\xBA\xA3\xD5/\xE6"\xB0\xED\xF4\xDFi\xF7GG\xF8\x9CpeP\xC7\xD1Q\xEDP\xAFQ\xE1\xAC\xCFwv\xC6-\x84\xBAg_2"<\xE2\i6-\xE2\xB2o\xF9_0W\xB9\xC02Bm\xDF\xED^\xCA+?3U\xCFKx\xE0BZ\x8F\xB5\xC6\xE9e\xAC_\xCF\xC3\xC9\xE7N{t\x89j\xFF\xAE\x86\xBDz\xCEk\xDA\xF5
+ʇ\x8D\xB7t\x8AL\x97YR:\x8CI\xCA\xCDT\xE7\xD9D8\xB9Μf\xD2a-\xA2\x85Ɩ\x91\xF3\xE0\xACTRDt\xB3\xC9>W\xA6`\xE3u\\x9FUp1\xA9\xA2u\x86\xB1K\xBA\xAE\xD6ʱ^X1YSU\xE6\xAF\xD5\xC0<\x9F\x80P\x88ⷪc\xE4\x94r.A\xDF\xD8)E\xD3m\x90,\x89j\xEA\xAE6\xE1DqON#;l!A~\xADJ\xF1p\x95J?V/5\xDD~
+\xF1y\xDFD4d\xA3\xE6\x87^O\x8C\xEE2\xA1\x8B\xF8Z\xB7\xC8\xD7d\xFB^\xD95)\xD8W\xF7\xE4\x8A\xDDm\x923\xB8_x\xC01\xDDK\xF0B\xE8\xEATM\xD7Mn\xBF\xE2\xD0~B\x825\x9D\xC7\xE6\xB5\xF2\xB3#\xE5
+F\x9FW\xF6\xC5ڂ\xFB~\x98`\xA6~1.\x92\xE7\xC5\xF7\xEF\xFA\xA3R\xF3a7\xDFfv|\xEC'\xFA\xCF\xFF\xFC\xF5\xE4eP/\x92\x8E\xFBq\x8BBG|\xD4OБe\xA9\xA6\x9A\x93\x82\xADEg\xF4\xF3hڮּBy\xB1\xE0\x9D\xB2\xF6B\xB7\xEA\xE5\\xE8\xF3\xC1/X\xA9\xDF\xDC;%'N\xA6N\xB6\xBD~l֠\xC2\xFB\xB1\xEC\xAAL\xDD&\x8C/\xB3\xF8o\x90u2D\xAC\xB5(\xCD,\xD9(\xA2\xCA(\xAB\xD5\xEFR\xD3\xED
+\xF95\xFAu\xF4\xC3sr\xA3Xcà\x9EM\x9E)_<\xEA8\xC9\xF6\x81\xF3\x88\xFE\x81U^c\xD4!/\xA89\xDC)υ\x91pa\xA8<\xE0d\xCA\xD2_\xAD\x9F\xC0\xA3J՟\xEB\xCE\xDCjĜv[\s`\xA7\xED\xFBL\\xBF\x94\x8C\xF8q]?\xB3\xF6\x93\x8Aw\x8A\xAD>\xF8\xC7|e@\x8D\x86M: \xF8\xE0 \xF0\x92\x89|\xF3\x8F?\xAA\xD4\xE6K\x9B\xB7\xE6+\x88\xAF\xA5\x81\x98%\xF4\xEA\xACvɞ?E:35\xCE\xE2c\x9D\xCB䲡\xBF\x8F\x82\xCBC@++$:L\xEE\xFB~\xBE0\x97\xE31\xE0\xE9Eޱ\x81\xC6\xDD:YʁχC\x92\xAAbm\xF3\xF8!\xDAS\xD7\xFF\xD5\xF1\xCB\xF6xb\xEA9\xE6\x9D7\x87\x85\xB49:\xF4\xAEA#\xF9L\xCE\xE9\xC16\xCDP\xF8\xC5
+֔\xEC\x95\xE5\xE2z\xD8\xDC\\xEF^\x9C\x95XS\x8A\xDF]\xECkz\xC6]w{\xAD\xDC`G)Y6\xBA&
+\xAB\xBA[|\xE1j\x9F\xA6EɊ\xCEL\xF1\x819L#\xFC1?\x8E\xC7հ\x81
+z]薳\xD4\xCE\xEE\xEF\xF7\xAC\xF8y'Sc/\xC4\xFE\xB2\x96\xAC\x8E9\x90\x90\xB4\xDE6\xD0\xE24H\xE6T\xFD\xF2\xAC?\xFAب0\xE9\x976\xB8.\x98kd\xAE\xD5l7\x8D+ٞ'6\xB6\x9E5V\xB6\xA2}\xBA\x9Ejt\xFD\x99ļ\xE7\xC4'\xD5O'\xAC.ӸK\xCE,\xC0\xB6\xD8\xAC#\xC4D\xDD|f\xDD\xEF\xFD\xDE[M\xE5\xD3;\x9DBq\\x9A\xA6\xB2b\xF7*\xCE`\xC0 :\x9Cd\xC3'rgJ\xE1\x89\xC4\xC7ko\xAD\xE7k\xEA\xE6\xE6ij\xFAa\x91(\xF9δ\xF5\xAAm\xC9UP\xE2\xF9T\xD1ݫ6\xFByȄ\x9F֨\x98ޢ\xBFT\x84\xBE\xEA\xBB$A8\xF0TL\x95
+\xCE]ҽܯ\xBE\x89A\xF8\xC0\xEB\xCFUQ+PN\x95\xF68\x9D\x9C\xE4\xBD.vJ\xF6C\x82\x97\xE5+\x89e^\xB3\xF8\xB1x5\xA3\xEE\xBE'b\x80^9\xBB+\xD3\xD5\xE1\xE1(\x9F\xCDWR\xFC#\xFF\xF7ܸ\x9E*A8\xC6\xC3\xC5@ؒ鯃0\xA0\x81\xB31,\xF9\xDF\xED\x96<\xCC\xF9\x9B9qTY\xB0\x85\x9Ev(l\xEE\x8B\xCBX\xB5\xD2^\x95%e.\xCD\xF8{\x9D\xF9\xFD\x9Fs3cݵ\xE5#\x91\xC6\xE9:\xB5w0\xC4\xC5O\xCER\xFCRB\xEDC\\xDF\xDCS\xC2O\x8E\xA3"\xFDy0\x93\x83\x91\xA40\xB8_\xA4:\xBDR\xBAs \xF5\xEEk\x9D\x80\x93:8$%+\xCC0.wv\xF0\xF6\xF3\xEF\xDB\xCF'\x93h\x86 \xBC\xCB\xDE<X\x93\xEDzHE\xBB*n\xFD\xBB\xEA\x8Bҽ<\xEF`\xCD\xD7@\x8F\x86\x94%r\x92\x9E\x81\xB7\xA86\x99J\xF0KC=\xEC\xD2{m\xEC\xF3\xE8\xC5
+\xB3E\xCC\xEEyC\xA7\x8E\x9Fd\xD7D'\xD5\xD7s3|\xBE\xCFVbGV\x8A\xA8\xD5\xC9ҭ\xBD0U\x9C\xA4F\xC68\x84\xE6\xBF\xF2veVh:\xEFt\x91\xE2M\xEDԣ\x84U\xA3ě\x98\x8D[\xCB#\xFEZ!\xCA\xFB\x9D̡'\x8B\xD4/\xC4\xC1JN\xEApD<\xDC\xE9S*\xCFk}\xDD~\x8D\x8F\xFFu\xABɈ\x8E\xE5\xBB4\xE9-J>u\xA0P\x95\xC3FEb\xFC\x93\xBC\xCC{Q\xD2\xFCT\x9A\x98\xC9<\xD8^պ\xDD\xD3Dž\x8D\x93\x81\x99ѤB\xFB\xF2W\x9A\x87f\xEAn\xCB'S>\x89F_\xAF\x8E*\xA9|M\xEDx`\x9D\xDAC\xC1\x9Dl\xA1\x9EJN\xEF\xF3\xA8 \x99\xDCH߸b\x83\xA0-\x83\x99\xA8Z1\x82\xF5,\x88\x84\xFC:z)\xC3\xFF?
+\x9AN}>\xA6;v\xEA\xD8\xF3+\xB8% ;ZB\xDB\xD2p,+\xFF\xC283C-f\xAAxv\x85\x8C\x85z\x8CK_nC%\xF2\xD9\xCCtEV/Y\xD6?\xAD\x9D>A\xEA\xD4\x87\xF5Xv\\xF8a\xA9\xC1X\x806N\xB3\x87
+\xF6%\xE3\xF4[\xB5\xE3\xE4{\x982\x99_\xF1 2Mb\xA1
+\xC6o\xF1\x81[\x87Iʿ\x94Qz\x9A\x9F:FK\xA8\xB6/\xCAQ\xF7\x87t\xCF\xFB\xE5X\xB3kL8~%\xF38ك\xFA\x98<Tj\x83\xB0\x8C\xE...
[truncated message content] |
|
From: <br...@us...> - 2016-10-23 18:38:04
|
Revision: 4219
http://sourceforge.net/p/openlcb/svn/4219
Author: bracz
Date: 2016-10-23 18:38:02 +0000 (Sun, 23 Oct 2016)
Log Message:
-----------
recompile jars.
Modified Paths:
--------------
trunk/prototypes/java/openlcb-demo.jar
trunk/prototypes/java/openlcb.jar
Modified: trunk/prototypes/java/openlcb-demo.jar
===================================================================
(Binary files differ)
Modified: trunk/prototypes/java/openlcb.jar
===================================================================
(Binary files differ)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <br...@us...> - 2016-10-23 21:25:55
|
Revision: 4221
http://sourceforge.net/p/openlcb/svn/4221
Author: bracz
Date: 2016-10-23 21:25:52 +0000 (Sun, 23 Oct 2016)
Log Message:
-----------
Bumps implementation version number.
Modified Paths:
--------------
trunk/prototypes/java/manifest
trunk/prototypes/java/openlcb-demo.jar
trunk/prototypes/java/openlcb.jar
trunk/prototypes/java/src/org/openlcb/Version.java
Modified: trunk/prototypes/java/manifest
===================================================================
--- trunk/prototypes/java/manifest 2016-10-23 21:25:35 UTC (rev 4220)
+++ trunk/prototypes/java/manifest 2016-10-23 21:25:52 UTC (rev 4221)
@@ -7,6 +7,6 @@
Specification-Version: 0.7.4
Specification-Vendor: OpenLCB group
Package-Title: openlcb
-Package-Version: 0.7.5
+Package-Version: 0.7.6
Package-Vendor: OpenLCB group
Modified: trunk/prototypes/java/openlcb-demo.jar
===================================================================
(Binary files differ)
Modified: trunk/prototypes/java/openlcb.jar
===================================================================
(Binary files differ)
Modified: trunk/prototypes/java/src/org/openlcb/Version.java
===================================================================
--- trunk/prototypes/java/src/org/openlcb/Version.java 2016-10-23 21:25:35 UTC (rev 4220)
+++ trunk/prototypes/java/src/org/openlcb/Version.java 2016-10-23 21:25:52 UTC (rev 4221)
@@ -34,7 +34,7 @@
/* Library modifier - updated periodically
*/
- static final public int libMod = 5;
+ static final public int libMod = 6;
/**
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|