Compare commits
10 Commits
54cc7dc65f
...
158175da6d
| Author | SHA1 | Date | |
|---|---|---|---|
| 158175da6d | |||
| 4283a2ebc4 | |||
| 6590ddac10 | |||
| 62796af99b | |||
| 50567a9846 | |||
| 20a235781d | |||
| fbb1375ffa | |||
| 8dbb2e2d6d | |||
| f45c7b0519 | |||
| 5dc25b8858 |
27
build.gradle
27
build.gradle
@@ -1,5 +1,6 @@
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'eclipse'
|
||||
apply plugin: 'protobuf'
|
||||
apply plugin: 'maven'
|
||||
|
||||
group = 'com.github.boukefalos'
|
||||
@@ -10,6 +11,16 @@ task wrapper(type: Wrapper) {
|
||||
gradleVersion = '2.2'
|
||||
}
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.andrewkroh.gradle:gradle-protobuf-plugin:0.4.0'
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url 'https://github.com/Boukefalos/jlibloader/raw/mvn-repo/'
|
||||
@@ -21,14 +32,26 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile 'org.slf4j:slf4j-api:1.+'
|
||||
compile 'org.slf4j:slf4j-log4j12:1.+'
|
||||
compile 'org.picocontainer:picocontainer:2.15'
|
||||
compile 'com.github.boukefalos:jlibusb:0.5.7'
|
||||
compile 'org.slf4j:slf4j-log4j12:1.+'
|
||||
}
|
||||
|
||||
uploadArchives {
|
||||
repositories.mavenDeployer {
|
||||
repository(url: uri('.maven'))
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
srcDirs = [ 'src/main/java' ]
|
||||
}
|
||||
}
|
||||
generated {
|
||||
java {
|
||||
srcDirs = [ 'build/generated/java' ]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,68 +1,61 @@
|
||||
package com.github.boukefalos.ibuddy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.picocontainer.DefaultPicoContainer;
|
||||
import org.picocontainer.MutablePicoContainer;
|
||||
import org.picocontainer.Parameter;
|
||||
import org.picocontainer.parameters.ConstantParameter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import base.exception.LoaderException;
|
||||
import base.loader.AbstractLoader;
|
||||
|
||||
import com.github.boukefalos.ibuddy.exception.LoaderException;
|
||||
import com.github.boukefalos.ibuddy.implementation.Local;
|
||||
import com.github.boukefalos.ibuddy.implementation.Remote;
|
||||
import com.github.boukefalos.ibuddy.server.Server;
|
||||
|
||||
public class Loader {
|
||||
protected static Logger logger = LoggerFactory.getLogger(Loader.class);
|
||||
protected static MutablePicoContainer pico;
|
||||
public class Loader extends AbstractLoader<Loader> {
|
||||
protected static final String PROPERTIES_FILE = "ibuddy.properties";
|
||||
|
||||
public static iBuddy getiBuddy() throws LoaderException {
|
||||
if (!setup()) {
|
||||
throw new LoaderException();
|
||||
}
|
||||
return pico.getComponent(iBuddy.class);
|
||||
public Loader(Properties properties) throws LoaderException {
|
||||
super();
|
||||
|
||||
/* Add implementation */
|
||||
switch (properties.getProperty("implementation")) {
|
||||
case "local":
|
||||
pico.addComponent(Local.class);
|
||||
break;
|
||||
case "remote":
|
||||
pico.addComponent(Remote.class);
|
||||
|
||||
/* Add sender implementation */
|
||||
try {
|
||||
String protocol = properties.getOrDefault("protocol", "tcp").toString();
|
||||
String implementation = properties.getOrDefault("tcp.implementation", "socket").toString();
|
||||
String host = properties.getProperty("remote.host");
|
||||
int port = Integer.valueOf(properties.getProperty("remote.port"));
|
||||
addClientSender(protocol, implementation, host, port);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new LoaderException("Failed to parse remote.port");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Add server */
|
||||
if (properties.getProperty("server") != null) {
|
||||
pico.addComponent(Server.class);
|
||||
|
||||
/* Add server forwarder implementation */
|
||||
try {
|
||||
String protocol = properties.getOrDefault("server.protocol", "tcp").toString();
|
||||
String implementation = properties.getOrDefault("tcp.implementation", "socket").toString();
|
||||
int port = Integer.valueOf(properties.getProperty("server.port"));
|
||||
addServerForwarder(protocol, implementation, port);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new LoaderException("Failed to parse server.port");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Server getServer() throws LoaderException {
|
||||
if (!setup()) {
|
||||
throw new LoaderException();
|
||||
}
|
||||
return pico.getComponent(Server.class);
|
||||
public iBuddy getiBuddy() {
|
||||
return pico.getComponent(iBuddy.class);
|
||||
}
|
||||
|
||||
protected static boolean setup() {
|
||||
if (pico == null) {
|
||||
/* Read properties file */
|
||||
Properties properties = new Properties();
|
||||
try {
|
||||
properties.load(Loader.class.getClassLoader().getResourceAsStream("ibuddy.properties"));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
logger.error("Failed to load properties file", e);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Initialise container */
|
||||
pico = new DefaultPicoContainer();
|
||||
|
||||
/* Add implementation */
|
||||
if (properties.getProperty("implementation").equals("local")) {
|
||||
/* Local */
|
||||
pico.addComponent(Local.class);
|
||||
} else {
|
||||
/* Remote */
|
||||
pico.addComponent(Remote.class, Remote.class, new Parameter[]{
|
||||
new ConstantParameter(properties.getProperty("remote.host")),
|
||||
new ConstantParameter(Integer.valueOf(properties.getProperty("remote.port")))});
|
||||
}
|
||||
|
||||
/* Add server */
|
||||
pico.addComponent(Server.class, Server.class, new Parameter[]{
|
||||
new ConstantParameter(Integer.valueOf(properties.getProperty("server.port")))});
|
||||
}
|
||||
return true;
|
||||
public Server getServer() {
|
||||
return pico.getComponent(Server.class);
|
||||
}
|
||||
}
|
||||
|
||||
83
src/main/java/com/github/boukefalos/ibuddy/Server.java
Normal file
83
src/main/java/com/github/boukefalos/ibuddy/Server.java
Normal file
@@ -0,0 +1,83 @@
|
||||
package com.github.boukefalos.ibuddy;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jraf.jlibibuddy.IBuddyException;
|
||||
|
||||
import proto.Ibuddy.Blink;
|
||||
import proto.Ibuddy.Color;
|
||||
import proto.Ibuddy.Command;
|
||||
import proto.Ibuddy.Flap;
|
||||
import proto.Ibuddy.Head;
|
||||
import proto.Ibuddy.Nudge;
|
||||
import proto.Ibuddy.State;
|
||||
import base.Forwarder;
|
||||
import base.server.receiver.AbstractReceiver;
|
||||
|
||||
public class Server extends AbstractReceiver {
|
||||
protected iBuddy iBuddy;
|
||||
|
||||
public Server(iBuddy iBuddy, Forwarder forwarder) {
|
||||
super(forwarder);
|
||||
this.iBuddy = iBuddy;
|
||||
}
|
||||
|
||||
public void receive(byte[] buffer) {
|
||||
ByteArrayInputStream input = new ByteArrayInputStream(buffer);
|
||||
logger.debug("Received input");
|
||||
try {
|
||||
Command command = Command.parseDelimitedFrom(input);
|
||||
logger.debug("Command type = " + command.getType().name());
|
||||
switch (command.getType()) {
|
||||
case HEAD:
|
||||
Head head = command.getHead();
|
||||
Color color = head.getColor();
|
||||
if (head.getSingle()) {
|
||||
boolean state = head.getState().equals(State.ON);
|
||||
switch (color) {
|
||||
case RED:
|
||||
iBuddy.setHeadRed(state);
|
||||
case GREEN:
|
||||
iBuddy.setHeadGreen(state);
|
||||
case BLUE:
|
||||
iBuddy.setHeadBlue(state);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
iBuddy.setHead(color);
|
||||
}
|
||||
break;
|
||||
case WINGS:
|
||||
iBuddy.setWings(command.getWings().getDirection());
|
||||
break;
|
||||
case ROTATE:
|
||||
iBuddy.setRotate(command.getRotate().getDirection());
|
||||
break;
|
||||
case HEART:
|
||||
iBuddy.setHeart(command.getHeart().getState().equals(State.ON));
|
||||
break;
|
||||
case BLINK:
|
||||
Blink blink = command.getBlink();
|
||||
iBuddy.blink(blink.getColor(), blink.getOnTime(), blink.getOffTime(), blink.getTimes());
|
||||
break;
|
||||
case NUDGE:
|
||||
Nudge nudge = command.getNudge();
|
||||
iBuddy.nudge(nudge.getDelay(), nudge.getTimes());
|
||||
break;
|
||||
case FLAP:
|
||||
Flap flap = command.getFlap();
|
||||
iBuddy.flap(flap.getDelay(), flap.getTimes());
|
||||
break;
|
||||
default:
|
||||
iBuddy.off();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to parse input");
|
||||
return;
|
||||
} catch (IBuddyException e) {
|
||||
logger.error("Failed to send command to iBuddy", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package com.github.boukefalos.ibuddy.exception;
|
||||
|
||||
public class LoaderException extends Exception {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
package com.github.boukefalos.ibuddy.exception;
|
||||
|
||||
public class ServerException extends Exception {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.github.boukefalos.ibuddy.exception;
|
||||
|
||||
|
||||
public class iBuddyException extends Exception {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,9 +1,27 @@
|
||||
package com.github.boukefalos.ibuddy;
|
||||
|
||||
import com.github.boukefalos.ibuddy.exception.iBuddyException;
|
||||
import org.jraf.jlibibuddy.IBuddyException;
|
||||
|
||||
public interface iBuddy {
|
||||
public void sendHeadRed(boolean headRed) throws iBuddyException;
|
||||
public void sendHeadGreen(boolean headGreen) throws iBuddyException;
|
||||
public void sendHeadBlue(boolean headBlue) throws iBuddyException;
|
||||
import proto.Ibuddy.Color;
|
||||
import proto.Ibuddy.Direction;
|
||||
import base.Control;
|
||||
|
||||
public interface iBuddy extends Control {
|
||||
public void setHeart(boolean on) throws IBuddyException;
|
||||
public void setHeadRed(boolean on) throws IBuddyException;
|
||||
public void setHeadBlue(boolean on) throws IBuddyException;
|
||||
public void setHeadGreen(boolean on) throws IBuddyException;
|
||||
public void setHead(Color color) throws IBuddyException;
|
||||
public void setWingsUp() throws IBuddyException;
|
||||
public void setWingsDown() throws IBuddyException;
|
||||
public void setWingsCenter() throws IBuddyException;
|
||||
public void setWings(Direction direction) throws IBuddyException;
|
||||
public void setRotateLeft() throws IBuddyException;
|
||||
public void setRotateRight() throws IBuddyException;
|
||||
public void setRotateCenter() throws IBuddyException;
|
||||
public void setRotate(Direction direction) throws IBuddyException;
|
||||
public void off() throws IBuddyException;
|
||||
public void blink(Color color, int onTime, int offTime, int times) throws IBuddyException;
|
||||
public void nudge(int delay, int times) throws IBuddyException;
|
||||
public void flap(int delay, int times) throws IBuddyException;
|
||||
}
|
||||
|
||||
@@ -2,41 +2,115 @@ package com.github.boukefalos.ibuddy.implementation;
|
||||
|
||||
import org.jraf.jlibibuddy.IBuddy;
|
||||
import org.jraf.jlibibuddy.IBuddyException;
|
||||
import org.jraf.jlibibuddy.IBuddyUtils;
|
||||
|
||||
import proto.Ibuddy.Color;
|
||||
import proto.Ibuddy.Direction;
|
||||
|
||||
import com.github.boukefalos.ibuddy.iBuddy;
|
||||
import com.github.boukefalos.ibuddy.exception.iBuddyException;
|
||||
|
||||
public class Local implements iBuddy {
|
||||
IBuddy IBuddy;
|
||||
IBuddy IBuddy;
|
||||
|
||||
@SuppressWarnings("static-access")
|
||||
public Local() {
|
||||
IBuddy = IBuddy.getIBuddy();
|
||||
}
|
||||
@SuppressWarnings("static-access")
|
||||
public Local() {
|
||||
IBuddy = IBuddy.getIBuddy();
|
||||
}
|
||||
|
||||
public void sendHeadRed(boolean headRed) throws iBuddyException {
|
||||
try {
|
||||
IBuddy.sendHeadRed(headRed);
|
||||
} catch (IBuddyException e) {
|
||||
throw new iBuddyException();
|
||||
}
|
||||
}
|
||||
public void start() {}
|
||||
public void stop() {}
|
||||
public void exit() {}
|
||||
|
||||
public void sendHeadGreen(boolean headGreen) throws iBuddyException {
|
||||
try {
|
||||
IBuddy.sendHeadGreen(headGreen);
|
||||
} catch (IBuddyException e) {
|
||||
throw new iBuddyException();
|
||||
}
|
||||
|
||||
}
|
||||
public void setHeadRed(boolean on) throws IBuddyException {
|
||||
IBuddy.sendHeadRed(on);
|
||||
}
|
||||
|
||||
public void sendHeadBlue(boolean headBlue) throws iBuddyException {
|
||||
try {
|
||||
IBuddy.sendHeadBlue(headBlue);
|
||||
} catch (IBuddyException e) {
|
||||
throw new iBuddyException();
|
||||
}
|
||||
|
||||
}
|
||||
public void setHeadBlue(boolean on) throws IBuddyException {
|
||||
IBuddy.sendHeadBlue(on);
|
||||
}
|
||||
|
||||
public void setHeadGreen(boolean on) throws IBuddyException {
|
||||
IBuddy.sendHeadGreen(on);
|
||||
}
|
||||
|
||||
public void setHeart(boolean on) throws IBuddyException {
|
||||
IBuddy.sendHeart(on);
|
||||
}
|
||||
|
||||
public void setHead(Color color) throws IBuddyException {
|
||||
IBuddy.sendHeadColor(mapColor(color));
|
||||
}
|
||||
|
||||
public void setWingsUp() throws IBuddyException {
|
||||
IBuddy.sendWings(false, true);
|
||||
}
|
||||
|
||||
public void setWingsDown() throws IBuddyException {
|
||||
IBuddy.sendWings(true, false);
|
||||
}
|
||||
|
||||
public void setWingsCenter() throws IBuddyException {
|
||||
IBuddy.sendWings(false, false);
|
||||
}
|
||||
|
||||
public void setWings(Direction direction) throws IBuddyException {
|
||||
switch (direction) {
|
||||
case UP:
|
||||
setWingsUp();
|
||||
break;
|
||||
case DOWN:
|
||||
setWingsDown();
|
||||
break;
|
||||
default:
|
||||
setWingsCenter();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void setRotateLeft() throws IBuddyException {
|
||||
IBuddy.sendRotate(false, true);
|
||||
}
|
||||
|
||||
|
||||
public void setRotateRight() throws IBuddyException {
|
||||
IBuddy.sendRotate(true, false);
|
||||
}
|
||||
|
||||
public void setRotateCenter() throws IBuddyException {
|
||||
IBuddy.sendRotate(false, false);
|
||||
}
|
||||
|
||||
public void setRotate(Direction direction) throws IBuddyException {
|
||||
switch (direction) {
|
||||
case LEFT:
|
||||
setRotateLeft();
|
||||
break;
|
||||
case RIGHT:
|
||||
setRotateRight();
|
||||
default:
|
||||
setRotateCenter();
|
||||
}
|
||||
}
|
||||
|
||||
public void off() throws IBuddyException {
|
||||
IBuddy.sendAllOff();
|
||||
}
|
||||
|
||||
public void blink(Color color, int onTime, int offTime, int times) throws IBuddyException {
|
||||
IBuddyUtils.blink(IBuddy, mapColor(color), onTime, offTime, times);
|
||||
}
|
||||
|
||||
public void nudge(int delay, int times) throws IBuddyException {
|
||||
IBuddyUtils.nudge(IBuddy, delay, times);
|
||||
}
|
||||
|
||||
public void flap(int delay, int times) throws IBuddyException {
|
||||
IBuddyUtils.flap(IBuddy, delay, times);
|
||||
}
|
||||
|
||||
protected org.jraf.jlibibuddy.IBuddy.Color mapColor(Color color) {
|
||||
return color.equals(Color.NONE)
|
||||
? org.jraf.jlibibuddy.IBuddy.Color.OFF
|
||||
: org.jraf.jlibibuddy.IBuddy.Color.valueOf(color.name());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,69 +1,186 @@
|
||||
package com.github.boukefalos.ibuddy.implementation;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.SocketException;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.jraf.jlibibuddy.IBuddyException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import proto.Ibuddy.Blink;
|
||||
import proto.Ibuddy.Color;
|
||||
import proto.Ibuddy.Command;
|
||||
import proto.Ibuddy.Direction;
|
||||
import proto.Ibuddy.Flap;
|
||||
import proto.Ibuddy.Head;
|
||||
import proto.Ibuddy.Heart;
|
||||
import proto.Ibuddy.Nudge;
|
||||
import proto.Ibuddy.Rotate;
|
||||
import proto.Ibuddy.State;
|
||||
import proto.Ibuddy.Type;
|
||||
import proto.Ibuddy.Wings;
|
||||
import base.Control;
|
||||
import base.Sender;
|
||||
|
||||
import com.github.boukefalos.ibuddy.iBuddy;
|
||||
|
||||
public class Remote implements iBuddy {
|
||||
public class Remote implements iBuddy, Control {
|
||||
protected final static int BUFFER_SIZE = 1024;
|
||||
protected Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
protected DatagramSocket udpSocket;
|
||||
protected InetAddress inetAddress;
|
||||
protected int port;
|
||||
protected Sender sender;
|
||||
|
||||
public Remote(String host, int port) throws UnknownHostException{
|
||||
inetAddress = InetAddress.getByName(host);
|
||||
this.port = port;
|
||||
}
|
||||
public Remote(Sender sender) {
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
public void sendHeadRed(boolean headRed) {
|
||||
send("RED");
|
||||
}
|
||||
public void start() {
|
||||
sender.start();
|
||||
}
|
||||
|
||||
public void sendHeadGreen(boolean headGreen) {
|
||||
send("GREEN");
|
||||
}
|
||||
public void stop() {
|
||||
sender.stop();
|
||||
}
|
||||
|
||||
public void sendHeadBlue(boolean headBlue) {
|
||||
send("BLUE");
|
||||
}
|
||||
public void exit() {
|
||||
sender.exit();
|
||||
}
|
||||
|
||||
protected void send(String request) {
|
||||
send(request.getBytes());
|
||||
}
|
||||
public void setHeart(boolean on) throws IBuddyException {
|
||||
send(
|
||||
Command.newBuilder()
|
||||
.setType(Type.HEART)
|
||||
.setHeart(Heart.newBuilder()
|
||||
.setState(mapState(on))).build());
|
||||
}
|
||||
|
||||
protected void send(byte[] buffer) {
|
||||
try {
|
||||
setup();
|
||||
DatagramPacket datagramPacket = new DatagramPacket(buffer, buffer.length, inetAddress, port);
|
||||
udpSocket.send(datagramPacket);
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to send buffer", e);
|
||||
}
|
||||
}
|
||||
public void setHeadRed(boolean on) throws IBuddyException {
|
||||
send(
|
||||
Command.newBuilder()
|
||||
.setType(Type.HEAD)
|
||||
.setHead(Head.newBuilder()
|
||||
.setState(mapState(on))
|
||||
.setSingle(true)
|
||||
.setColor(Color.RED)).build());
|
||||
}
|
||||
|
||||
protected boolean setup() {
|
||||
if (udpSocket == null) {
|
||||
try {
|
||||
udpSocket = new DatagramSocket();
|
||||
} catch (SocketException e) {
|
||||
logger.error("Failed to create socket", e);
|
||||
return false;
|
||||
}
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
public void run() {
|
||||
udpSocket.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
public void setHeadBlue(boolean on) throws IBuddyException {
|
||||
send(
|
||||
Command.newBuilder()
|
||||
.setType(Type.HEAD)
|
||||
.setHead(Head.newBuilder()
|
||||
.setState(mapState(on))
|
||||
.setSingle(true)
|
||||
.setColor(Color.BLUE)).build());
|
||||
}
|
||||
|
||||
|
||||
public void setHeadGreen(boolean on) throws IBuddyException {
|
||||
send(
|
||||
Command.newBuilder()
|
||||
.setType(Type.HEAD)
|
||||
.setHead(Head.newBuilder()
|
||||
.setState(mapState(on))
|
||||
.setSingle(true)
|
||||
.setColor(Color.GREEN)).build());
|
||||
}
|
||||
|
||||
public void setHead(Color color) throws IBuddyException {
|
||||
State state = mapState(!color.equals(Color.NONE));
|
||||
send(
|
||||
Command.newBuilder()
|
||||
.setType(Type.HEAD)
|
||||
.setHead(Head.newBuilder()
|
||||
.setState(state)
|
||||
.setSingle(false)
|
||||
.setColor(color)).build());
|
||||
}
|
||||
|
||||
public void setWingsUp() throws IBuddyException {
|
||||
setWings(Direction.UP);
|
||||
}
|
||||
|
||||
public void setWingsDown() throws IBuddyException {
|
||||
setWings(Direction.DOWN);
|
||||
}
|
||||
|
||||
public void setWingsCenter() throws IBuddyException {
|
||||
setWings(Direction.CENTER);
|
||||
}
|
||||
|
||||
public void setWings(Direction direction) throws IBuddyException {
|
||||
send(
|
||||
Command.newBuilder()
|
||||
.setType(Type.WINGS)
|
||||
.setWings(Wings.newBuilder()
|
||||
.setDirection(direction)).build());
|
||||
}
|
||||
|
||||
public void setRotateLeft() throws IBuddyException {
|
||||
setRotate(Direction.LEFT);
|
||||
}
|
||||
|
||||
public void setRotateRight() throws IBuddyException {
|
||||
setRotate(Direction.RIGHT);
|
||||
}
|
||||
|
||||
public void setRotateCenter() throws IBuddyException {
|
||||
setRotate(Direction.CENTER);
|
||||
}
|
||||
|
||||
public void setRotate(Direction direction) throws IBuddyException {
|
||||
send(
|
||||
Command.newBuilder()
|
||||
.setType(Type.ROTATE)
|
||||
.setRotate(Rotate.newBuilder()
|
||||
.setDirection(direction)).build());
|
||||
}
|
||||
|
||||
public void off() throws IBuddyException {
|
||||
send(
|
||||
Command.newBuilder()
|
||||
.setType(Type.STATE).build());
|
||||
}
|
||||
|
||||
public void blink(Color color, int onTime, int offTime, int times) throws IBuddyException {
|
||||
send(
|
||||
Command.newBuilder()
|
||||
.setType(Type.BLINK)
|
||||
.setBlink(Blink.newBuilder()
|
||||
.setOnTime(onTime)
|
||||
.setOffTime(offTime)
|
||||
.setTimes(times)).build());
|
||||
}
|
||||
|
||||
public void nudge(int delay, int times) throws IBuddyException {
|
||||
send(
|
||||
Command.newBuilder()
|
||||
.setType(Type.NUDGE)
|
||||
.setNudge(Nudge.newBuilder()
|
||||
.setDelay(delay)
|
||||
.setTimes(times)).build());
|
||||
}
|
||||
|
||||
public void flap(int delay, int times) throws IBuddyException {
|
||||
send(
|
||||
Command.newBuilder()
|
||||
.setType(Type.FLAP)
|
||||
.setFlap(Flap.newBuilder()
|
||||
.setDelay(delay)
|
||||
.setTimes(times)).build());
|
||||
}
|
||||
|
||||
protected static State mapState(boolean on) {
|
||||
return on ? State.ON : State.OFF;
|
||||
}
|
||||
|
||||
protected void send(Command command) {
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream(BUFFER_SIZE);
|
||||
try {
|
||||
command.writeDelimitedTo(output);
|
||||
sender.send(output.toByteArray());
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to send command");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
package com.github.boukefalos.ibuddy.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.SocketException;
|
||||
|
||||
import org.jraf.jlibibuddy.IBuddy;
|
||||
import org.jraf.jlibibuddy.IBuddy.Color;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.github.boukefalos.ibuddy.Loader;
|
||||
import com.github.boukefalos.ibuddy.exception.LoaderException;
|
||||
import com.github.boukefalos.ibuddy.exception.ServerException;
|
||||
import com.github.boukefalos.ibuddy.exception.iBuddyException;
|
||||
|
||||
public class Server extends Thread {
|
||||
protected Logger logger = LoggerFactory.getLogger(getClass());
|
||||
protected com.github.boukefalos.ibuddy.iBuddy iBuddy;
|
||||
protected DatagramSocket diagramSocket;
|
||||
|
||||
public Server(int port) throws ServerException {
|
||||
try {
|
||||
iBuddy = Loader.getiBuddy();
|
||||
diagramSocket = new DatagramSocket(port);
|
||||
return;
|
||||
} catch (LoaderException e) {
|
||||
logger.error("Failed to load iBuddy", e);
|
||||
} catch (SocketException e) {
|
||||
logger.error("Failed to initialize socket", e);
|
||||
}
|
||||
throw new ServerException();
|
||||
}
|
||||
|
||||
@SuppressWarnings("incomplete-switch")
|
||||
public void run() {
|
||||
while (true) {
|
||||
byte[] buffer = new byte[1024];
|
||||
DatagramPacket datagramPacket = new DatagramPacket(buffer, buffer.length);
|
||||
try {
|
||||
diagramSocket.receive(datagramPacket);
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to receive packet", e);
|
||||
}
|
||||
String received = new String(datagramPacket.getData(), datagramPacket.getOffset(), datagramPacket.getLength());
|
||||
try {
|
||||
Color color = IBuddy.Color.valueOf(received);
|
||||
switch (color) {
|
||||
case RED:
|
||||
iBuddy.sendHeadRed(true);
|
||||
case GREEN:
|
||||
iBuddy.sendHeadGreen(true);
|
||||
case BLUE:
|
||||
iBuddy.sendHeadBlue(true);
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.error("No such command", e);
|
||||
} catch (iBuddyException e) {
|
||||
logger.error("Failed to send command to iBuddy", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -205,18 +205,18 @@ public class IBuddy {
|
||||
* @param command the command byte.
|
||||
*/
|
||||
private synchronized void sendMessage(byte command) throws IBuddyException {
|
||||
open();
|
||||
open();
|
||||
try {
|
||||
device.controlMsg(USB.REQ_TYPE_TYPE_CLASS | USB.REQ_TYPE_RECIP_INTERFACE, USB.REQ_SET_CONFIGURATION, 0x02, 0x01, INIT, INIT.length, 100, true);
|
||||
} catch (USBException e) {
|
||||
close();
|
||||
close();
|
||||
throw new IBuddyException("Could not send message to i-Buddy", e);
|
||||
}
|
||||
byte[] commandMessage = getCommandMessage(command);
|
||||
try {
|
||||
device.controlMsg(USB.REQ_TYPE_TYPE_CLASS | USB.REQ_TYPE_RECIP_INTERFACE, USB.REQ_SET_CONFIGURATION, 0x02, 0x01, commandMessage, commandMessage.length, 100, true);
|
||||
} catch (USBException e) {
|
||||
close();
|
||||
close();
|
||||
throw new IBuddyException("Could not send message to i-Buddy", e);
|
||||
}
|
||||
close();
|
||||
@@ -497,7 +497,7 @@ public class IBuddy {
|
||||
private synchronized void open() throws IBuddyException {
|
||||
device = USB.getDevice(DEVICE_VENDOR, DEVICE_PRODUCT);
|
||||
try {
|
||||
device.open(1, 0, 0);
|
||||
device.open(1, 1, 0);
|
||||
} catch (USBException e) {
|
||||
throw new IBuddyException("Could not open i-Buddy", e);
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
package test;
|
||||
import com.github.boukefalos.ibuddy.Loader;
|
||||
|
||||
public class TestClient {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Loader.getiBuddy().sendHeadGreen(true);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
package test;
|
||||
import org.jraf.jlibibuddy.IBuddy;
|
||||
import org.jraf.jlibibuddy.IBuddy.Color;
|
||||
import org.jraf.jlibibuddy.IBuddyException;
|
||||
import org.jraf.jlibibuddy.IBuddyUtils;
|
||||
|
||||
public class TestOriginal {
|
||||
public static void main(String[] args) {
|
||||
IBuddy iBuddy = IBuddy.getIBuddy();
|
||||
try {
|
||||
while (true) {
|
||||
iBuddy.sendAllOff();
|
||||
for (Color color : IBuddy.Color.values()) {
|
||||
iBuddy.sendHeart(false);
|
||||
iBuddy.sendHeadColor(color);
|
||||
Thread.sleep(100);
|
||||
iBuddy.sendHeart(true);
|
||||
Thread.sleep(500);
|
||||
}
|
||||
iBuddy.sendAllOff();
|
||||
Thread.sleep(2000);
|
||||
IBuddyUtils.flap(iBuddy, 400, 6);
|
||||
}
|
||||
} catch (IBuddyException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
package test;
|
||||
import com.github.boukefalos.ibuddy.Loader;
|
||||
|
||||
public class TestServer {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Loader.getServer().start();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
82
src/main/proto/ibuddy.proto
Normal file
82
src/main/proto/ibuddy.proto
Normal file
@@ -0,0 +1,82 @@
|
||||
package proto;
|
||||
|
||||
enum Type {
|
||||
STATE = 1;
|
||||
HEAD = 2;
|
||||
WINGS = 3;
|
||||
ROTATE = 4;
|
||||
HEART = 5;
|
||||
BLINK = 6;
|
||||
NUDGE = 7;
|
||||
FLAP = 8;
|
||||
}
|
||||
|
||||
enum State {
|
||||
ON = 1;
|
||||
OFF = 2;
|
||||
}
|
||||
|
||||
enum Direction {
|
||||
CENTER = 1;
|
||||
DOWN = 2;
|
||||
UP = 3;
|
||||
LEFT = 4;
|
||||
RIGHT = 5;
|
||||
}
|
||||
|
||||
enum Color {
|
||||
NONE = 1;
|
||||
RED = 2;
|
||||
GREEN = 3;
|
||||
BLUE = 4;
|
||||
YELLOW = 5;
|
||||
PURPLE = 6;
|
||||
CYAN = 7;
|
||||
WHITE = 8;
|
||||
}
|
||||
|
||||
message Head {
|
||||
required State state = 1;
|
||||
required bool single = 2;
|
||||
required Color color = 3;
|
||||
}
|
||||
|
||||
message Wings {
|
||||
required Direction direction = 1;
|
||||
}
|
||||
|
||||
message Rotate {
|
||||
required Direction direction = 1;
|
||||
}
|
||||
|
||||
message Heart {
|
||||
required State state = 1;
|
||||
}
|
||||
|
||||
message Blink {
|
||||
required int32 onTime = 1;
|
||||
required int32 offTime = 2;
|
||||
required int32 times = 3;
|
||||
optional Color color = 4;
|
||||
}
|
||||
|
||||
message Nudge {
|
||||
required int32 delay = 1;
|
||||
required int32 times = 2;
|
||||
}
|
||||
|
||||
message Flap {
|
||||
required int32 delay = 1;
|
||||
required int32 times = 2;
|
||||
}
|
||||
|
||||
message Command {
|
||||
required Type type = 1;
|
||||
optional Head head = 2;
|
||||
optional Wings wings = 3;
|
||||
optional Rotate rotate = 4;
|
||||
optional Heart heart = 5;
|
||||
optional Blink blink = 6;
|
||||
optional Nudge nudge = 7;
|
||||
optional Flap flap = 8;
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
implementation=local
|
||||
remote.host=localhost
|
||||
remote.port=8883
|
||||
server.port=8883
|
||||
implementation=remote
|
||||
server=true
|
||||
server.protocol=tcp
|
||||
30
src/test/java/test/TestOriginal.java
Normal file
30
src/test/java/test/TestOriginal.java
Normal file
@@ -0,0 +1,30 @@
|
||||
package test;
|
||||
import org.jraf.jlibibuddy.IBuddy;
|
||||
import org.jraf.jlibibuddy.IBuddy.Color;
|
||||
import org.jraf.jlibibuddy.IBuddyException;
|
||||
import org.jraf.jlibibuddy.IBuddyUtils;
|
||||
|
||||
public class TestOriginal {
|
||||
public static void main(String[] args) {
|
||||
IBuddy iBuddy = IBuddy.getIBuddy();
|
||||
try {
|
||||
while (true) {
|
||||
iBuddy.sendAllOff();
|
||||
for (Color color : IBuddy.Color.values()) {
|
||||
iBuddy.sendHeart(false);
|
||||
iBuddy.sendHeadColor(color);
|
||||
Thread.sleep(100);
|
||||
iBuddy.sendHeart(true);
|
||||
Thread.sleep(500);
|
||||
}
|
||||
iBuddy.sendAllOff();
|
||||
Thread.sleep(2000);
|
||||
IBuddyUtils.flap(iBuddy, 400, 6);
|
||||
}
|
||||
} catch (IBuddyException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
44
src/test/java/test/TestTcpCommunication.java
Normal file
44
src/test/java/test/TestTcpCommunication.java
Normal file
@@ -0,0 +1,44 @@
|
||||
package test;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import proto.Ibuddy.Color;
|
||||
|
||||
import com.github.boukefalos.ibuddy.Loader;
|
||||
import com.github.boukefalos.ibuddy.Server;
|
||||
import com.github.boukefalos.ibuddy.iBuddy;
|
||||
|
||||
public class TestTcpCommunication {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Properties localProperties = new Properties();
|
||||
localProperties.setProperty("implementation", "local");
|
||||
localProperties.setProperty("server", "true");
|
||||
localProperties.setProperty("server.port", "8883");
|
||||
localProperties.setProperty("server.protocol", "tcp");
|
||||
localProperties.setProperty("tcp.implementation", "socket");
|
||||
|
||||
Properties remoteProperties = new Properties();
|
||||
remoteProperties.setProperty("implementation", "remote");
|
||||
remoteProperties.setProperty("protocol", "tcp");
|
||||
remoteProperties.setProperty("remote.host", "localhost");
|
||||
remoteProperties.setProperty("remote.port", "8883");
|
||||
|
||||
Loader localLoader = new Loader(localProperties);
|
||||
Loader remoteLoader = new Loader(remoteProperties);
|
||||
|
||||
Server server = localLoader.getServer();
|
||||
iBuddy iBuddy = remoteLoader.getiBuddy();
|
||||
|
||||
server.start();
|
||||
iBuddy.start();
|
||||
|
||||
iBuddy.setHead(Color.GREEN);
|
||||
|
||||
server.exit();
|
||||
iBuddy.exit();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
44
src/test/java/test/TestUdpCommunication.java
Normal file
44
src/test/java/test/TestUdpCommunication.java
Normal file
@@ -0,0 +1,44 @@
|
||||
package test;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import proto.Ibuddy.Color;
|
||||
|
||||
import com.github.boukefalos.ibuddy.Loader;
|
||||
import com.github.boukefalos.ibuddy.Server;
|
||||
import com.github.boukefalos.ibuddy.iBuddy;
|
||||
|
||||
public class TestUdpCommunication {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Properties localProperties = new Properties();
|
||||
localProperties.setProperty("implementation", "local");
|
||||
localProperties.setProperty("protocol", "udp");
|
||||
localProperties.setProperty("server", "true");
|
||||
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", "255.255.255.255");
|
||||
remoteProperties.setProperty("remote.port", "8883");
|
||||
|
||||
Loader localLoader = new Loader(localProperties);
|
||||
Loader remoteLoader = new Loader(remoteProperties);
|
||||
|
||||
iBuddy iBuddy = remoteLoader.getiBuddy();
|
||||
Server server = localLoader.getServer();
|
||||
|
||||
iBuddy.start();
|
||||
server.start();
|
||||
|
||||
iBuddy.setHead(Color.WHITE);
|
||||
|
||||
server.exit();
|
||||
iBuddy.exit();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user