Skip to content

Commit

Permalink
+ slf4j logging
Browse files Browse the repository at this point in the history
* method names and classes refactoring
+ FirmataTests module
* changed module dependencies tree
+ hardware tests
  • Loading branch information
Anton Smirnov committed Dec 11, 2011
1 parent 77b6e73 commit f04fdca
Show file tree
Hide file tree
Showing 45 changed files with 312 additions and 281 deletions.
8 changes: 7 additions & 1 deletion Firmata/pom.xml
Expand Up @@ -12,7 +12,7 @@

<groupId>name.antonsmirnov.firmata</groupId>
<artifactId>Firmata</artifactId>
<version>2.1</version>
<version>2.2</version>
<name>Firmata</name>

<developers>
Expand All @@ -31,6 +31,12 @@
<version>1.0</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.4</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
Expand Down
139 changes: 75 additions & 64 deletions Firmata/src/main/java/name/antonsmirnov/firmata/Firmata.java
@@ -1,9 +1,11 @@
package name.antonsmirnov.firmata;

import name.antonsmirnov.firmata.deserializer.*;
import name.antonsmirnov.firmata.message.*;
import name.antonsmirnov.firmata.reader.*;
import name.antonsmirnov.firmata.serial.ISerial;
import name.antonsmirnov.firmata.serializer.*;
import name.antonsmirnov.firmata.writer.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -17,6 +19,8 @@
*/
public class Firmata {

private static final Logger log = LoggerFactory.getLogger(Firmata.class);

private static final int BUFFER_SIZE = 64;

/**
Expand Down Expand Up @@ -61,7 +65,7 @@ public static interface Listener {
void onStringSysexMessageReceived(StringSysexMessage message);

/**
* Unknown byte received (no active Deserializers)
* Unknown byte received (no active MessageReader)
* @param byteValue
*/
void onUnknownByteReceived(int byteValue);
Expand Down Expand Up @@ -91,8 +95,8 @@ public void setSerial(ISerial serial) {
}

public Firmata() {
initSerializers();
initDeserializers();
initWriters();
initReaders();
}

private Listener listener;
Expand All @@ -105,40 +109,40 @@ public void setListener(Listener listener) {
this.listener = listener;
}

private static Map<Class<? extends Message>, IMessageSerializer> serializers;
private static Map<Class<? extends Message>, IMessageWriter> writers;

private void initSerializers() {
serializers = new HashMap<Class<? extends Message>, IMessageSerializer>();
private void initWriters() {
writers = new HashMap<Class<? extends Message>, IMessageWriter>();

serializers.put(AnalogMessage.class, new AnalogMessageSerializer());
serializers.put(DigitalMessage.class, new DigitalMessageSerializer());
serializers.put(ReportAnalogPinMessage.class, new ReportAnalogPinMessageSerializer());
serializers.put(ReportDigitalPortMessage.class, new ReportDigitalPortMessageSerializer());
serializers.put(ReportProtocolVersionMessage.class, new ReportProtocolVersionMessageSerializer());
serializers.put(SetPinModeMessage.class, new SetPinModeMessageSerializer());
serializers.put(SystemResetMessage.class, new SystemResetMessageSerializer());
writers.put(AnalogMessage.class, new AnalogMessageWriter());
writers.put(DigitalMessage.class, new DigitalMessageWriter());
writers.put(ReportAnalogPinMessage.class, new ReportAnalogPinMessageWriter());
writers.put(ReportDigitalPortMessage.class, new ReportDigitalPortMessageWriter());
writers.put(ReportProtocolVersionMessage.class, new ReportProtocolVersionMessageWriter());
writers.put(SetPinModeMessage.class, new SetPinModeMessageWriter());
writers.put(SystemResetMessage.class, new SystemResetMessageWriter());

// sysex messages
SysexMessageSerializer sysexMessageSerializer = new SysexMessageSerializer();
serializers.put(SysexMessage.class, sysexMessageSerializer);
serializers.put(StringSysexMessage.class, sysexMessageSerializer);
serializers.put(ReportFirmwareVersionMessage.class, sysexMessageSerializer);
SysexMessageWriter sysexMessageWriter = new SysexMessageWriter();
writers.put(SysexMessage.class, sysexMessageWriter);
writers.put(StringSysexMessage.class, sysexMessageWriter);
writers.put(ReportFirmwareVersionMessage.class, sysexMessageWriter);
}

private static List<IMessageDeserializer> deserializers;
private static List<IMessageReader> readers;

private IMessageDeserializer activeDeserializer;
private IMessageReader activeReader;

private void initDeserializers() {
deserializers = new ArrayList<IMessageDeserializer>();
potentialDeserializers = new ArrayList<IMessageDeserializer>();
private void initReaders() {
readers = new ArrayList<IMessageReader>();
potentialReaders = new ArrayList<IMessageReader>();

deserializers.add(new AnalogMessageDeserializer());
deserializers.add(new DigitalMessageDeserializer());
deserializers.add(new FirmwareVersionMessageDeserializer());
deserializers.add(new ProtocolVersionMessageDeserializer());
deserializers.add(new SysexMessageDeserializer());
deserializers.add(new StringSysexMessageDeserializer());
readers.add(new AnalogMessageReader());
readers.add(new DigitalMessageReader());
readers.add(new FirmwareVersionMessageReader());
readers.add(new ProtocolVersionMessageReader());
readers.add(new SysexMessageReader());
readers.add(new StringSysexMessageReader());
}

/**
Expand All @@ -157,70 +161,76 @@ public Firmata(ISerial serial) {
* @param message concrete outcoming message
*/
public void send(Message message) {
IMessageSerializer serializer = serializers.get(message.getClass());
if (serializer == null)
IMessageWriter writer = writers.get(message.getClass());
if (writer == null)
throw new RuntimeException("Unknown message type: " + message.getClass());

serializer.writeToSerial(message, serial);
log.info("Sending {}", message);
writer.write(message, serial);
}

private List<IMessageDeserializer> potentialDeserializers;
private List<IMessageReader> potentialReaders;

private byte[] buffer = new byte[BUFFER_SIZE];

private int bufferLength;

private Message lastReceivedMessage;

public Message getLastReceivedMessage() {
protected synchronized void setLastReceivedMessage(Message message) {
this.lastReceivedMessage = message;
log.info("Received {}", lastReceivedMessage);
}

public synchronized Message getLastReceivedMessage() {
return lastReceivedMessage;
}

public void onDataReceived(int incomingByte) {
buffer[bufferLength++] = (byte)incomingByte;

if (activeDeserializer == null) {
if (activeReader == null) {
// new message byte is received
int command = DECODE_COMMAND(incomingByte);

if (potentialDeserializers.size() == 0) {
if (potentialReaders.size() == 0) {
// first byte check
findPotentialDeserializers(command);
findPotentialReaders(command);
} else {
// not first byte check
// few potential deserializers found, so we should check the next bytes to define Deserializer
filterPotentialDeserializers(command);
// few potential readers found, so we should check the next bytes to define MessageReader
filterPotentialReaders(command);
}

tryHandle();

} else {
// continue handling with activeDeserializer
activeDeserializer.handle(buffer, bufferLength);
// continue handling with activeReader
activeReader.read(buffer, bufferLength);

if (activeDeserializer.finishedHandling()) {
if (activeReader.finishedReading()) {
// message is ready
lastReceivedMessage = activeDeserializer.getMessage();
activeDeserializer.fireEvent(listener);
activeReader.fireEvent(listener);
setLastReceivedMessage(activeReader.getMessage());
reinitBuffer();
}
}
}

// pass the next bytes in order to define according deserializer
private void filterPotentialDeserializers(int command) {
List<IMessageDeserializer> newPotentialDeserializers = new ArrayList<IMessageDeserializer>();
// pass the next bytes in order to define according reader
private void filterPotentialReaders(int command) {
List<IMessageReader> newPotentialReaders = new ArrayList<IMessageReader>();

for (IMessageDeserializer eachPotentialDeserializer : potentialDeserializers)
if (eachPotentialDeserializer.canHandle(buffer, bufferLength, command))
newPotentialDeserializers.add(eachPotentialDeserializer);
for (IMessageReader eachPotentialReader : potentialReaders)
if (eachPotentialReader.canRead(buffer, bufferLength, command))
newPotentialReaders.add(eachPotentialReader);

potentialDeserializers = newPotentialDeserializers;
potentialReaders = newPotentialReaders;
}

private void tryHandle() {
int potentialDeserializersCount = potentialDeserializers.size();
switch (potentialDeserializersCount) {
int potentialReadersCount = potentialReaders.size();
switch (potentialReadersCount) {

// unknown byte
case 0:
Expand All @@ -229,27 +239,28 @@ private void tryHandle() {
reinitBuffer();
break;

// the only one deserializer
// the only one reader
case 1:
activeDeserializer = potentialDeserializers.get(0);
activeDeserializer.startHandling();
activeReader = potentialReaders.get(0);
activeReader.startHandling();
log.info("Started reading with {} ...", activeReader.getClass().getSimpleName());
break;

// default:
// (in case if few serializers are found, we should pass the next bytes to define final deserializer)
// (in case if few writers are found, we should pass the next bytes to define final reader)
}
}

private void reinitBuffer() {
bufferLength = 0;
activeDeserializer = null;
potentialDeserializers.clear();
activeReader = null;
potentialReaders.clear();
}

private void findPotentialDeserializers(int command) {
for (IMessageDeserializer eachDeserializer : deserializers) {
if (eachDeserializer.canHandle(buffer, bufferLength, command)) {
potentialDeserializers.add(eachDeserializer);
private void findPotentialReaders(int command) {
for (IMessageReader eachReader : readers) {
if (eachReader.canRead(buffer, bufferLength, command)) {
potentialReaders.add(eachReader);
}
}
}
Expand Down
Expand Up @@ -19,6 +19,6 @@ public boolean equals(Object obj) {

@Override
public String toString() {
return "ReportFirmwareVersionMessage[]";
return "ReportProtocolVersionMessage[]";
}
}
@@ -1,19 +1,19 @@
package name.antonsmirnov.firmata.deserializer;
package name.antonsmirnov.firmata.reader;

import name.antonsmirnov.firmata.Firmata;
import name.antonsmirnov.firmata.message.AnalogMessage;
import name.antonsmirnov.firmata.serializer.AnalogMessageSerializer;
import name.antonsmirnov.firmata.writer.AnalogMessageWriter;

import static name.antonsmirnov.firmata.BytesHelper.DECODE_BYTE;
import static name.antonsmirnov.firmata.BytesHelper.DECODE_CHANNEL;

/**
* MessageDeserializer for AnalogMessage
* MessageReader for AnalogMessage
*/
public class AnalogMessageDeserializer implements IMessageDeserializer<AnalogMessage> {
public class AnalogMessageReader implements IMessageReader<AnalogMessage> {

public boolean canHandle(byte[] buffer, int bufferLength, int command) {
return command == AnalogMessageSerializer.COMMAND;
public boolean canRead(byte[] buffer, int bufferLength, int command) {
return command == AnalogMessageWriter.COMMAND;
}

private boolean isHandling;
Expand All @@ -23,7 +23,7 @@ public void startHandling() {
message = new AnalogMessage();
}

public void handle(byte[] buffer, int length) {
public void read(byte[] buffer, int length) {
if (length == 2) {
message.setPin(DECODE_CHANNEL(buffer[0]));
} else {
Expand All @@ -32,7 +32,7 @@ public void handle(byte[] buffer, int length) {
}
}

public boolean finishedHandling() {
public boolean finishedReading() {
return !isHandling;
}

Expand Down
@@ -1,24 +1,24 @@
package name.antonsmirnov.firmata.deserializer;
package name.antonsmirnov.firmata.reader;

import name.antonsmirnov.firmata.message.SysexMessage;
import name.antonsmirnov.firmata.serializer.SysexMessageSerializer;
import name.antonsmirnov.firmata.writer.SysexMessageWriter;

import static name.antonsmirnov.firmata.BytesHelper.DECODE_STRING;

/**
* Base MessageDeserializer for SysexMessage
* Base MessageReader for SysexMessage
*/
public abstract class BaseSysexMessageDeserializer<ConcreteSysexMessage extends SysexMessage>
implements IMessageDeserializer<ConcreteSysexMessage> {
public abstract class BaseSysexMessageReader<ConcreteSysexMessage extends SysexMessage>
implements IMessageReader<ConcreteSysexMessage> {

private Byte sysexCommand;

public BaseSysexMessageDeserializer(Byte sysexCommand) {
public BaseSysexMessageReader(Byte sysexCommand) {
this.sysexCommand = sysexCommand;
}

public boolean canHandle(byte[] buffer, int bufferLength, int command) {
return (bufferLength == 1 && buffer[0] == (byte)SysexMessageSerializer.COMMAND_START) // is sysex message?
public boolean canRead(byte[] buffer, int bufferLength, int command) {
return (bufferLength == 1 && buffer[0] == (byte) SysexMessageWriter.COMMAND_START) // is sysex message?
||
(bufferLength == 2 && (sysexCommand == null || sysexCommand.equals(buffer[1]))) // is needed sysex command
||
Expand All @@ -33,10 +33,10 @@ public void startHandling() {

protected ConcreteSysexMessage message;

public void handle(byte[] buffer, int length) {
public void read(byte[] buffer, int length) {
byte incomingByte = buffer[length-1];

if (incomingByte == (byte)SysexMessageSerializer.COMMAND_END) {
if (incomingByte == (byte) SysexMessageWriter.COMMAND_END) {
isHandling = false;

message = buildSysexMessage(buffer, length);
Expand All @@ -56,7 +56,7 @@ public ConcreteSysexMessage getMessage() {
return message;
}

public boolean finishedHandling() {
public boolean finishedReading() {
return !isHandling;
}

Expand Down

0 comments on commit f04fdca

Please sign in to comment.