Migrate to general jlibarduino

This commit is contained in:
2015-06-25 15:56:42 +01:00
parent 55d51fdcd2
commit df4bab1750
19 changed files with 4860 additions and 427 deletions

View File

@@ -0,0 +1,27 @@
package com.github.boukefalos.arduino;
import java.util.ArrayList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import base.work.Listen;
import base.worker.Worker;
public abstract class AbstractArduino extends Listen<Object> implements Arduino {
public static final int BUFFER_SIZE = 1024;
protected Logger logger = LoggerFactory.getLogger(getClass());
protected ArrayList<Listen<Object>> listenList;
public AbstractArduino() {
super(Worker.Type.DIRECT);
}
public void start() {}
public void stop() {}
public void exit() {
stop();
}
}

View File

@@ -0,0 +1,13 @@
package com.github.boukefalos.arduino;
import base.Control;
import base.work.Listen;
import com.github.boukefalos.arduino.exception.ArduinoException;
public interface Arduino extends Control {
public void register(Listen<Object> listen);
public void remove(Listen<Object> listen);
public void send(byte[] buffer) throws ArduinoException;
}

View File

@@ -1,4 +1,4 @@
package com.github.boukefalos.tm1638; package com.github.boukefalos.arduino;
import java.util.Properties; import java.util.Properties;
@@ -10,30 +10,32 @@ import org.picocontainer.parameters.ConstantParameter;
import base.exception.LoaderException; import base.exception.LoaderException;
import base.loader.AbstractLoader; import base.loader.AbstractLoader;
import com.github.boukefalos.tm1638.exception.ArduinoException; import com.github.boukefalos.arduino.exception.ArduinoException;
import com.github.boukefalos.tm1638.implementation.Local; import com.github.boukefalos.arduino.implementation.Local;
import com.github.boukefalos.tm1638.implementation.Remote; import com.github.boukefalos.arduino.implementation.Remote;
public class Loader extends AbstractLoader<Loader> { public class Loader extends AbstractLoader<Loader> {
protected static final String PROPERTIES_FILE = "TM1638.properties"; protected static final String PROPERTIES_FILE = "arduino.properties";
public Loader(Properties properties) throws LoaderException { public Loader(Properties properties) throws LoaderException {
super(); this(Local.class, Remote.class, Server.class, properties);
}
public Loader(Class<?> localClass, Class<?> remoteClass, Class<?> serverClass, Properties properties) throws LoaderException {
/* Add implementation */ /* Add implementation */
switch (properties.getProperty("implementation")) { switch (properties.getProperty("implementation")) {
case "local": case "local":
pico.addComponent(TM1638.class, Local.class); pico.addComponent(localClass);
break; break;
case "remote": case "remote":
pico.addComponent(TM1638.class, Remote.class); pico.addComponent(remoteClass);
/* Add remote duplex implementation */ /* Add remote duplex implementation */
try { try {
String protocol = properties.getOrDefault("server.protocol", "tcp").toString(); String protocol = properties.getOrDefault("protocol", "tcp").toString();
String implementation = properties.getOrDefault("tcp.implementation", "socket").toString(); String implementation = properties.getOrDefault("tcp.implementation", "socket").toString();
String host = properties.getProperty("remote.host"); String host = properties.getProperty("remote.host");
int port = Integer.valueOf(properties.getProperty("remote.port")); int port = Integer.valueOf(properties.getProperty("remote.port"));
addClientDuplex(protocol, implementation, host, port); addClientDuplex(protocol, implementation, host, port);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
throw new LoaderException("Failed to parse remote.port"); throw new LoaderException("Failed to parse remote.port");
@@ -44,7 +46,7 @@ public class Loader extends AbstractLoader<Loader> {
/* Add server */ /* Add server */
if (properties.getProperty("server") != null) { if (properties.getProperty("server") != null) {
boolean direct = Boolean.parseBoolean(properties.getOrDefault("server.direct", Server.DIRECT).toString()); boolean direct = Boolean.parseBoolean(properties.getOrDefault("server.direct", Server.DIRECT).toString());
pico.addComponent(Server.class, Server.class, new Parameter[] { pico.addComponent(serverClass, serverClass, new Parameter[] {
new ComponentParameter(), new ComponentParameter(),
new ComponentParameter(), new ComponentParameter(),
new ConstantParameter(direct)}); new ConstantParameter(direct)});
@@ -61,9 +63,9 @@ public class Loader extends AbstractLoader<Loader> {
} }
} }
public TM1638 getTM1638() throws ArduinoException { public Arduino getArduino() throws ArduinoException {
try { try {
return pico.getComponent(TM1638.class); return (Arduino) pico.getComponent(Arduino.class);
} catch (PicoCompositionException e) { } catch (PicoCompositionException e) {
throw new ArduinoException("Failed to load"); throw new ArduinoException("Failed to load");
} }

View File

@@ -0,0 +1,64 @@
package com.github.boukefalos.arduino;
import java.io.IOException;
import base.Control;
import base.Duplex;
import base.Receiver;
import base.exception.worker.ActivateException;
import base.exception.worker.DeactivateException;
import base.work.Listen;
import com.github.boukefalos.arduino.exception.ArduinoException;
public class Server extends Listen<Object> implements Control, Receiver {
protected static final boolean DIRECT = false;
protected Arduino arduino;
protected Duplex duplex;
protected boolean direct;
public Server(Arduino arduino, Duplex duplex) {
this(arduino, duplex, DIRECT);
}
public Server(Arduino tm1638, Duplex duplex, boolean direct) {
this.arduino = tm1638;
this.duplex = duplex;
this.direct = direct;
arduino.register(this); // Arduino > [input()]
duplex.register(this); // Client > [receive()]
}
public void activate() throws ActivateException {
duplex.start();
super.activate();
}
public void deactivate() throws DeactivateException {
duplex.stop();
super.deactivate();
}
public void receive(byte[] buffer) {
// Client > [Server] > Arduino
if (direct) {
try {
arduino.send(buffer);
} catch (ArduinoException e) {
logger.error("", e);
}
} else {
// option to decode() in derivatives?
}
}
public void input(byte[] buffer) {
// Arduino > [Server] > Client
try {
duplex.send(buffer);
} catch (IOException e) {
logger.error("", e);
}
}
}

View File

@@ -1,4 +1,4 @@
package com.github.boukefalos.tm1638.exception; package com.github.boukefalos.arduino.exception;
import java.io.IOException; import java.io.IOException;

View File

@@ -1,23 +1,23 @@
package com.github.boukefalos.tm1638.implementation; package com.github.boukefalos.arduino.implementation;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import base.work.Listen; import base.work.Listen;
import com.github.boukefalos.tm1638.AbstractTM1638; import com.github.boukefalos.arduino.AbstractArduino;
import com.github.boukefalos.tm1638.Arduino; import com.github.boukefalos.arduino.exception.ArduinoException;
import com.github.boukefalos.tm1638.exception.ArduinoException; import com.github.boukefalos.arduino.port.Port;
public class Local extends AbstractTM1638 { public class Local extends AbstractArduino {
protected Arduino arduino; protected Port arduino;
protected OutputStream outputStream; protected OutputStream outputStream;
public Local() throws Exception { public Local() throws Exception {
this(Arduino.getInstance()); this(Port.getInstance());
} }
public Local(Arduino arduino) throws ArduinoException { public Local(Port arduino) throws ArduinoException {
this.arduino = arduino; this.arduino = arduino;
outputStream = arduino.getOutputStream(); outputStream = arduino.getOutputStream();
} }

View File

@@ -1,4 +1,4 @@
package com.github.boukefalos.tm1638.implementation; package com.github.boukefalos.arduino.implementation;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
@@ -7,12 +7,11 @@ import base.Duplex;
import base.Receiver; import base.Receiver;
import base.work.Listen; import base.work.Listen;
import com.github.boukefalos.tm1638.AbstractTM1638; import com.github.boukefalos.arduino.AbstractArduino;
import com.github.boukefalos.tm1638.exception.ArduinoException; import com.github.boukefalos.arduino.exception.ArduinoException;
public class Remote extends AbstractTM1638 implements Receiver { public class Remote extends AbstractArduino implements Receiver {
protected Duplex duplex; protected Duplex duplex;
protected ArrayList<Listen<Object>> listenList;
public Remote(Duplex duplex) { public Remote(Duplex duplex) {
this.duplex = duplex; this.duplex = duplex;

View File

@@ -0,0 +1,36 @@
package com.github.boukefalos.arduino.port;
import java.io.InputStream;
import java.lang.reflect.Method;
import purejavacomm.SerialPortEvent;
import base.work.Listen;
public class ParsingPort extends Port {
protected Class<?> messageClass;
protected ParsingPort(Class<?> messageClass) {
this.messageClass = messageClass;
}
public static Port getInstance(Class<?> messageClass) {
if (port == null) {
port = new ParsingPort(messageClass);
}
return port;
}
public void serialEvent(SerialPortEvent event) {
try {
Method m = messageClass.getMethod("parseDelimitedFrom", InputStream.class);
Object object = m.invoke(null, inputStream);
for (Listen<Object> listen : listenList) {
listen.add(object);
}
} catch (Exception e) {
logger.error("", e);
} catch (Throwable e) {
logger.error("", e);
}
}
}

View File

@@ -1,4 +1,5 @@
package com.github.boukefalos.tm1638; package com.github.boukefalos.arduino.port;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
@@ -15,12 +16,11 @@ import purejavacomm.SerialPort;
import purejavacomm.SerialPortEvent; import purejavacomm.SerialPortEvent;
import purejavacomm.SerialPortEventListener; import purejavacomm.SerialPortEventListener;
import purejavacomm.UnsupportedCommOperationException; import purejavacomm.UnsupportedCommOperationException;
import tm1638.Tm1638.Echo;
import base.work.Listen; import base.work.Listen;
import com.github.boukefalos.tm1638.exception.ArduinoException; import com.github.boukefalos.arduino.exception.ArduinoException;
public class Arduino implements SerialPortEventListener { public class Port implements SerialPortEventListener {
public static final int BUFFER_SIZE = 1024; public static final int BUFFER_SIZE = 1024;
public static final int TIME_OUT = 1000; public static final int TIME_OUT = 1000;
public static final String PORT_NAMES[] = { public static final String PORT_NAMES[] = {
@@ -31,35 +31,37 @@ public class Arduino implements SerialPortEventListener {
"COM3", // Windows "COM3", // Windows
}; };
protected static Logger logger = LoggerFactory.getLogger(Arduino.class); protected static Logger logger = LoggerFactory.getLogger(Port.class);
protected static Arduino arduino; protected static Port port;
protected int bufferSize; protected int bufferSize;
protected SerialPort port = null; protected SerialPort serialPort = null;
protected InputStream inputStream = null; protected InputStream inputStream = null;
protected ArrayList<Listen<Object>> listenList = new ArrayList<Listen<Object>>(); protected ArrayList<Listen<Object>> listenList = new ArrayList<Listen<Object>>();
protected Arduino(int bufferSize) { protected Port() {}
protected Port(int bufferSize) {
this.bufferSize = bufferSize; this.bufferSize = bufferSize;
} }
public void register(Listen<Object> listen) { public void register(Listen<Object> listen) {
listenList.add(listen); listenList.add(listen);
} }
public void remove(Listen<Object> listen) { public void remove(Listen<Object> listen) {
listenList.remove(listen); listenList.remove(listen);
} }
public static Arduino getInstance() { public static Port getInstance() {
return getInstance(BUFFER_SIZE); return getInstance(BUFFER_SIZE);
} }
public static Arduino getInstance(int bufferSize) { public static Port getInstance(int bufferSize) {
if (arduino == null) { if (port == null) {
arduino = new Arduino(bufferSize); port = new Port(bufferSize);
} }
return arduino; return port;
} }
protected void connect() throws ArduinoException { protected void connect() throws ArduinoException {
@@ -72,17 +74,17 @@ public class Arduino implements SerialPortEventListener {
for ( String portName: PORT_NAMES) { for ( String portName: PORT_NAMES) {
if (portid.getName().equals(portName) || portid.getName().contains(portName)) { if (portid.getName().equals(portName) || portid.getName().contains(portName)) {
try { try {
port = (SerialPort) portid.open("", TIME_OUT); serialPort = (SerialPort) portid.open("", TIME_OUT);
port.setFlowControlMode( serialPort.setFlowControlMode(
SerialPort.FLOWCONTROL_XONXOFF_IN + SerialPort.FLOWCONTROL_XONXOFF_IN +
SerialPort.FLOWCONTROL_XONXOFF_OUT); SerialPort.FLOWCONTROL_XONXOFF_OUT);
inputStream = port.getInputStream(); inputStream = serialPort.getInputStream();
System.out.println( "Connected on port: " + portid.getName()); System.out.println("Connected on port: " + portid.getName());
port.addEventListener(this); serialPort.addEventListener(this);
} catch (UnsupportedCommOperationException | PortInUseException | IOException | TooManyListenersException e) { } catch (UnsupportedCommOperationException | PortInUseException | IOException | TooManyListenersException e) {
throw new ArduinoException("Failed to connect"); throw new ArduinoException("Failed to connect");
} }
port.notifyOnDataAvailable(true); serialPort.notifyOnDataAvailable(true);
return; return;
} }
} }
@@ -92,47 +94,46 @@ public class Arduino implements SerialPortEventListener {
} }
public void serialEvent(SerialPortEvent event) { public void serialEvent(SerialPortEvent event) {
try { switch (event.getEventType()) {
switch (event.getEventType()) { case SerialPortEvent.DATA_AVAILABLE:
case SerialPortEvent.DATA_AVAILABLE: byte[] buffer = new byte[bufferSize];
// Where should this be parsed, or should byte[] be passed directly? try {
Echo echo = Echo.parseDelimitedFrom(inputStream); inputStream.read(buffer);
System.err.println(echo.getMessage()); for (Listen<Object> listen : listenList) {
for (Listen<Object> listen : listenList) { listen.add(buffer);
listen.add(echo); }
} } catch (IOException e) {
break; logger.error("", e);
default: }
break; break;
} default:
} catch (IOException e) { break;
logger.error("", e);
} }
} }
public InputStream getInputStream() throws ArduinoException { public InputStream getInputStream() throws ArduinoException {
if (port == null) { if (serialPort == null) {
connect(); connect();
} }
try { try {
return port.getInputStream(); return serialPort.getInputStream();
} catch (IOException e) { } catch (IOException e) {
throw new ArduinoException("Failed to get inputstream"); throw new ArduinoException("Failed to get inputstream");
} }
} }
public OutputStream getOutputStream() throws ArduinoException { public OutputStream getOutputStream() throws ArduinoException {
if (port == null) { if (serialPort == null) {
connect(); connect();
} }
try { try {
return port.getOutputStream(); return serialPort.getOutputStream();
} catch (IOException e) { } catch (IOException e) {
throw new ArduinoException("Failed to get inputstream"); throw new ArduinoException("Failed to get inputstream");
} }
} }
public void close() { public void close() {
port.close(); serialPort.close();
} }
} }

View File

@@ -1,65 +0,0 @@
package com.github.boukefalos.tm1638;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import tm1638.Tm1638.Color;
import tm1638.Tm1638.Command;
import tm1638.Tm1638.Command.Type;
import tm1638.Tm1638.Construct;
import tm1638.Tm1638.Ping;
import tm1638.Tm1638.SetLed;
import base.Sender;
public abstract class AbstractTM1638 implements TM1638, Sender {
public static final int BUFFER_SIZE = 1024;
protected Logger logger = LoggerFactory.getLogger(getClass());
public void start() {}
public void stop() {}
public void exit() {
stop();
}
public void command(Command command) {
ByteArrayOutputStream output = new ByteArrayOutputStream(BUFFER_SIZE);
try {
command.writeDelimitedTo(output);
byte[] buffer = output.toByteArray();
send(buffer);
} catch (IOException e) {
logger.error("Failed to send command");
}
}
public void construct(int dataPin, int clockPin, int strobePin) {
command(Command.newBuilder()
.setType(Type.CONSTRUCT)
.setConstruct(
Construct.newBuilder()
.setDataPin(dataPin)
.setClockPin(clockPin)
.setStrobePin(strobePin).build()).build());
}
public void ping(int id) {
command(Command.newBuilder()
.setType(Type.PING)
.setPing(Ping.newBuilder()
.setId(id)).build());
}
public void setLed(Color color, int pos) {
command(Command.newBuilder()
.setType(Type.SET_LED)
.setSetLed(
SetLed.newBuilder()
.setColor(color)
.setPos(pos).build()).build());
}
}

View File

@@ -1,96 +0,0 @@
package com.github.boukefalos.tm1638;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import tm1638.Tm1638.Color;
import tm1638.Tm1638.Command;
import tm1638.Tm1638.Ping;
import tm1638.Tm1638.SetLed;
import base.Control;
import base.Duplex;
import base.Receiver;
import base.exception.worker.ActivateException;
import base.exception.worker.DeactivateException;
import base.work.Listen;
import com.github.boukefalos.tm1638.exception.ArduinoException;
public class Server extends Listen<Object> implements Control, Receiver {
protected static final boolean DIRECT = false;
protected TM1638 tm1638;
protected Duplex duplex;
protected boolean direct;
public Server(TM1638 tm1638, Duplex duplex) {
this(tm1638, duplex, DIRECT);
}
public Server(TM1638 tm1638, Duplex duplex, boolean direct) {
this.tm1638 = tm1638;
this.duplex = duplex;
this.direct = direct;
tm1638.register(this); // Arduino > [input()]
duplex.register(this); // Client > [receive()]
}
public void activate() throws ActivateException {
duplex.start();
super.activate();
}
public void deactivate() throws DeactivateException {
duplex.stop();
super.deactivate();
}
public void receive(byte[] buffer) {
// Client > [Server] > Arduino
if (direct) {
try {
tm1638.send(buffer);
} catch (ArduinoException e) {
logger.error("", e);
}
} else {
ByteArrayInputStream input = new ByteArrayInputStream(buffer);
try {
Command command = Command.parseDelimitedFrom(input);
logger.debug("Command type = " + command.getType().name());
switch (command.getType()) {
case PING:
Ping ping = command.getPing();
tm1638.ping(ping.getId());
break;
case SET_LED:
SetLed setLed = command.getSetLed();
logger.debug("Color = " + setLed.getColor().name());
switch (setLed.getColor()) {
case RED:
tm1638.setLed(Color.RED, 1);
case GREEN:
tm1638.setLed(Color.GREEN, 1);
default:
break;
}
break;
default:
break;
}
} catch (IOException e) {
logger.error("Failed to parse input");
return;
}
}
}
public void input(byte[] buffer) {
// Arduino > [Server] > Client
try {
duplex.send(buffer);
} catch (IOException e) {
logger.error("", e);
}
}
}

View File

@@ -1,18 +0,0 @@
package com.github.boukefalos.tm1638;
import com.github.boukefalos.tm1638.exception.ArduinoException;
import tm1638.Tm1638.Color;
import base.Control;
import base.work.Listen;
public interface TM1638 extends Control {
public void register(Listen<Object> listen);
public void remove(Listen<Object> listen);
public void send(byte[] buffer) throws ArduinoException;
public void construct(int dataPin, int clockPin, int strobePin);
public void ping(int i);
public void setLed(Color color, int pos);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,59 +0,0 @@
package tm1638;
enum Color {
GREEN = 1;
RED = 2;
BOTH = 3;
NONE = 4;
}
enum Module {
TM1638 = 1;
InvertedTM1638 = 2;
TM1640 = 3;
}
message Command {
enum Type {
SERVER = 1;
PING = 2;
CONSTRUCT = 3;
SET_LED = 4;
}
required Type type = 1;
optional Server server = 2;
optional Ping ping = 3;
optional Construct construct = 4;
optional SetLed setLed = 5;
}
message Server {
optional string host = 1;
required int32 port = 2;
}
message Ping {
required int32 id = 1;
}
message Echo {
required int32 id = 1;
optional string message = 2;
}
message Construct {
required int32 dataPin = 1;
required int32 clockPin = 2;
optional int32 strobePin = 3;
optional bool activateDisplay = 4 [default = true];
optional int32 intensity = 5 [default = 7];
optional Module module = 6 [default = TM1638];
optional int32 id = 7 [default = 0];
}
message SetLed {
required Color color = 1;
required int32 pos = 2;
optional int32 id = 3 [default = 1];
}

View File

@@ -0,0 +1,24 @@
package jlibarduino;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.lang.reflect.Method;
import tm1638.Tm1638.Echo;
public class Test {
public static void main(String[] args) throws Exception {
Echo echo = Echo.newBuilder().setMessage("abc").setId(123).build();
ByteArrayOutputStream output = new ByteArrayOutputStream();
echo.writeDelimitedTo(output);
byte[] buffer = output.toByteArray();
ByteArrayInputStream input = new ByteArrayInputStream(buffer);
Class<?> messageClass = Echo.class;
Method m = messageClass.getMethod("parseDelimitedFrom", InputStream.class);
Object object = m.invoke(null, input);
echo = (Echo) object;
System.out.println(echo.getMessage());
System.out.println(echo.getId());
}
}

View File

@@ -1,36 +0,0 @@
package test;
import tm1638.Tm1638.Color;
import tm1638.Tm1638.Echo;
import base.work.Listen;
import com.github.boukefalos.tm1638.TM1638;
import com.github.boukefalos.tm1638.implementation.Local;
public class TestLocal extends Listen<Object> {
public static void main(String[] args) throws Exception {
TM1638 TM1638 = new Local();
main(TM1638);
}
public static void main(TM1638 TM1638) throws InterruptedException {
TM1638.register(new TestLocal());
TM1638.construct(8, 9, 7);
int i = 123;
while (i < 10000) {
TM1638.ping(i++);
TM1638.setLed(i % 3 == 0 ? Color.GREEN : Color.RED, i % 7);
Thread.sleep(1000);
}
}
public TestLocal() {
super();
start();
}
public void input(Echo echo) {
System.out.println("> " + echo.getMessage() + " " + echo.getId());
}
}

View File

@@ -1,35 +0,0 @@
package test;
import java.util.Properties;
import base.exception.worker.ActivateException;
import com.github.boukefalos.tm1638.Loader;
import com.github.boukefalos.tm1638.Server;
import com.github.boukefalos.tm1638.TM1638;
import com.github.boukefalos.tm1638.exception.ArduinoException;
public class TestRemoteImplementation extends TestLocal {
protected TM1638 tm1638;
public TestRemoteImplementation(Loader loader) throws ArduinoException {
tm1638 = loader.getTM1638();
tm1638.register(this);
}
public void activate() throws ActivateException {
tm1638.start();
super.activate();
}
public static void main(Properties localProperties, Properties remoteProperties) throws Exception {
Loader localLoader = new Loader(localProperties);
Loader remoteLoader = new Loader(remoteProperties);
Server server = localLoader.getServer();
server.start();
TM1638 TM1638 = remoteLoader.getTM1638();
main(TM1638);
}
}

View File

@@ -1,28 +0,0 @@
package test;
import java.util.Properties;
import com.github.boukefalos.tm1638.exception.ArduinoException;
public class TestTcpImplementation {
public static void main(String[] args) throws Exception {
Properties localProperties = new Properties();
localProperties.setProperty("implementation", "local");
localProperties.setProperty("server", "true");
localProperties.setProperty("server.direct", "false");
localProperties.setProperty("server.port", "8883");
localProperties.setProperty("server.protocol", "tcp");
Properties remoteProperties = new Properties();
remoteProperties.setProperty("implementation", "remote");
remoteProperties.setProperty("protocol", "tcp");
remoteProperties.setProperty("remote.host", "localhost");
remoteProperties.setProperty("remote.port", "8883");
try {
TestRemoteImplementation.main(localProperties, remoteProperties);
} catch (ArduinoException e) {
System.err.println(e.getMessage());
}
}
}

View File

@@ -1,22 +0,0 @@
package test;
import java.util.Properties;
public class TestUdpImplementation {
public static void main(String[] args) throws Exception {
Properties localProperties = new Properties();
localProperties.setProperty("implementation", "local");
localProperties.setProperty("server", "true");
localProperties.setProperty("server.direct", "false");
localProperties.setProperty("server.port", "8883");
localProperties.setProperty("server.protocol", "udp");
Properties remoteProperties = new Properties();
remoteProperties.setProperty("implementation", "remote");
remoteProperties.setProperty("protocol", "udp");
remoteProperties.setProperty("remote.host", "localhost");
remoteProperties.setProperty("remote.port", "8883");
TestRemoteImplementation.main(localProperties, remoteProperties);
}
}