kopia lustrzana https://github.com/felHR85/UsbSerial
commit
fbf3b89b9d
|
@ -36,6 +36,14 @@ android {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'com.annimon:stream:1.2.1'
|
implementation 'com.annimon:stream:1.2.1'
|
||||||
|
implementation 'com.squareup.okio:okio:2.1.0'
|
||||||
|
|
||||||
|
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
||||||
|
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
||||||
|
androidTestImplementation 'junit:junit:4.12'
|
||||||
|
|
||||||
|
testImplementation 'junit:junit:4.12'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createJar.dependsOn(deleteJar, build)
|
createJar.dependsOn(deleteJar, build)
|
||||||
|
|
|
@ -0,0 +1,188 @@
|
||||||
|
package com.felhr.tests.usbserial;
|
||||||
|
|
||||||
|
import com.felhr.usbserial.SerialBuffer;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
|
||||||
|
public class SerialBufferTest extends TestCase {
|
||||||
|
|
||||||
|
private static final int BIG_BUFFER_1_SIZE = 64 * 1024;
|
||||||
|
private static final int BIG_BUFFER_2_SIZE = 1024 * 1024;
|
||||||
|
private static final int READ_BUFFER_SIZE = 16 * 1024;
|
||||||
|
|
||||||
|
private static final String text1 = "HOLA";
|
||||||
|
private static final byte[] bigBuffer = new byte[BIG_BUFFER_1_SIZE];
|
||||||
|
private static final byte[] bigBuffer2 = new byte[BIG_BUFFER_2_SIZE];
|
||||||
|
private static final byte[] bigReadBuffer = new byte[READ_BUFFER_SIZE];
|
||||||
|
|
||||||
|
private SerialBuffer serialBuffer;
|
||||||
|
|
||||||
|
// Testing Write buffer
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimpleWriteBuffer(){
|
||||||
|
serialBuffer = new SerialBuffer(true);
|
||||||
|
serialBuffer.putWriteBuffer(text1.getBytes());
|
||||||
|
byte[] dataReceived = serialBuffer.getWriteBuffer();
|
||||||
|
assertEquals(text1, new String(dataReceived));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testBigSimpleWriteBuffer(){
|
||||||
|
try {
|
||||||
|
new Random().nextBytes(bigBuffer);
|
||||||
|
serialBuffer = new SerialBuffer(true);
|
||||||
|
serialBuffer.putWriteBuffer(bigBuffer);
|
||||||
|
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
|
||||||
|
|
||||||
|
while(outputStream.size() < bigBuffer.length){
|
||||||
|
byte[] srcData = serialBuffer.getWriteBuffer();
|
||||||
|
outputStream.write(srcData);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] srcBuffered = outputStream.toByteArray();
|
||||||
|
|
||||||
|
Assert.assertArrayEquals(bigBuffer, srcBuffered);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSuperBigSimpleWriteBuffer(){
|
||||||
|
try {
|
||||||
|
new Random().nextBytes(bigBuffer2);
|
||||||
|
serialBuffer = new SerialBuffer(true);
|
||||||
|
serialBuffer.putWriteBuffer(bigBuffer2);
|
||||||
|
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
|
||||||
|
|
||||||
|
while(outputStream.size() < bigBuffer2.length){
|
||||||
|
byte[] srcData = serialBuffer.getWriteBuffer();
|
||||||
|
outputStream.write(srcData);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] srcBuffered = outputStream.toByteArray();
|
||||||
|
|
||||||
|
Assert.assertArrayEquals(bigBuffer2, srcBuffered);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimpleWriteBufferAsync1(){
|
||||||
|
try {
|
||||||
|
new Random().nextBytes(bigBuffer2);
|
||||||
|
serialBuffer = new SerialBuffer(true);
|
||||||
|
|
||||||
|
WriterThread writerThread = new WriterThread(serialBuffer, bigBuffer2);
|
||||||
|
writerThread.start();
|
||||||
|
|
||||||
|
while(writerThread.getState() != Thread.State.TERMINATED){/*Busy waiting*/}
|
||||||
|
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
|
||||||
|
|
||||||
|
while(outputStream.size() < bigBuffer2.length){
|
||||||
|
byte[] srcData = serialBuffer.getWriteBuffer();
|
||||||
|
outputStream.write(srcData);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] dataReceived = outputStream.toByteArray();
|
||||||
|
|
||||||
|
Assert.assertArrayEquals(bigBuffer2, dataReceived);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSimpleWriteBufferAsync2(){
|
||||||
|
try {
|
||||||
|
new Random().nextBytes(bigBuffer2);
|
||||||
|
serialBuffer = new SerialBuffer(true);
|
||||||
|
|
||||||
|
WriterThread writerThread = new WriterThread(serialBuffer, bigBuffer2, Thread.currentThread());
|
||||||
|
writerThread.start();
|
||||||
|
|
||||||
|
ByteArrayOutputStream outputStream = new ByteArrayOutputStream( );
|
||||||
|
|
||||||
|
while(outputStream.size() < bigBuffer2.length){
|
||||||
|
byte[] srcData = serialBuffer.getWriteBuffer();
|
||||||
|
outputStream.write(srcData);
|
||||||
|
}
|
||||||
|
|
||||||
|
byte[] dataReceived = outputStream.toByteArray();
|
||||||
|
|
||||||
|
Assert.assertArrayEquals(bigBuffer2, dataReceived);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Testing ReadBuffer
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReadBuffer(){
|
||||||
|
new Random().nextBytes(bigReadBuffer);
|
||||||
|
serialBuffer = new SerialBuffer(true);
|
||||||
|
|
||||||
|
ByteBuffer readBuffer = serialBuffer.getReadBuffer();
|
||||||
|
readBuffer.put(bigReadBuffer);
|
||||||
|
|
||||||
|
byte[] buffered = serialBuffer.getDataReceived();
|
||||||
|
Assert.assertArrayEquals(bigReadBuffer, buffered);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReadBufferCompatible(){
|
||||||
|
new Random().nextBytes(bigReadBuffer);
|
||||||
|
serialBuffer = new SerialBuffer(false);
|
||||||
|
|
||||||
|
byte[] readBuffer = serialBuffer.getBufferCompatible();
|
||||||
|
System.arraycopy(bigReadBuffer, 0, readBuffer, 0, bigReadBuffer.length);
|
||||||
|
|
||||||
|
byte[] buffered = serialBuffer.getDataReceivedCompatible(bigReadBuffer.length);
|
||||||
|
Assert.assertArrayEquals(bigReadBuffer, buffered);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private class WriterThread extends Thread{
|
||||||
|
|
||||||
|
private SerialBuffer serialBuffer;
|
||||||
|
private byte[] data;
|
||||||
|
private Thread callerThread;
|
||||||
|
|
||||||
|
public WriterThread(SerialBuffer serialBuffer, byte[] data){
|
||||||
|
this.serialBuffer = serialBuffer;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WriterThread(SerialBuffer serialBuffer, byte[] data, Thread callerThread){
|
||||||
|
this.serialBuffer = serialBuffer;
|
||||||
|
this.data = data;
|
||||||
|
this.callerThread = callerThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if(callerThread == null) {
|
||||||
|
serialBuffer.putWriteBuffer(data);
|
||||||
|
}else{
|
||||||
|
while(callerThread.getState() != State.WAITING){/*Busy waiting*/ }
|
||||||
|
serialBuffer.putWriteBuffer(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,214 @@
|
||||||
|
package com.felhr.tests.utils;
|
||||||
|
|
||||||
|
import com.felhr.utils.ProtocolBuffer;
|
||||||
|
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
|
||||||
|
public class ProtocolBufferTest extends TestCase {
|
||||||
|
|
||||||
|
private final String onePacket = "$GPAAM,A,A,0.10,N,WPTNME*32\r\n";
|
||||||
|
private final String twoPackets = "$GPAAM,A,A,0.10,N,WPTNME*32\r\n$GPGGA,092750.000,5321.6802,N,00630.3372,W,1,8,1.03,61.7,M,55.2,M,,*76\r\n";
|
||||||
|
private final String splitPacket = "$GPAAM,A,A,0.10,N,WPTN";
|
||||||
|
private final String oneHalfPacket = "$GPAAM,A,A,0.10,N,WPTNME*32\r\n$GPGGA,092750.000";
|
||||||
|
|
||||||
|
private final String[] verySplit ={"$GPAAM,",
|
||||||
|
"A",
|
||||||
|
",",
|
||||||
|
"A,",
|
||||||
|
"0",
|
||||||
|
".",
|
||||||
|
"10,N",
|
||||||
|
",WPTNME*32\r\n"};
|
||||||
|
|
||||||
|
private final byte[] rawPacket = new byte[]{0x21, 0x3b, 0x20, 0x40};
|
||||||
|
private final byte[] twoRawPackets = new byte[]{0x21, 0x3b, 0x20, 0x40, 0x4a, 0x20, 0x40};
|
||||||
|
private final byte[] splitRawPacket = new byte[]{0x21, 0x3b, 0x20, 0x40, 0x4a};
|
||||||
|
|
||||||
|
private final byte[][] verySplitRawPacket = {
|
||||||
|
new byte[]{0x21},
|
||||||
|
new byte[]{0x3b},
|
||||||
|
new byte[]{0x20},
|
||||||
|
new byte[]{0x40}};
|
||||||
|
|
||||||
|
private ProtocolBuffer protocolBuffer;
|
||||||
|
private final String modeText = ProtocolBuffer.TEXT;
|
||||||
|
private final String modeBinary = ProtocolBuffer.BINARY;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOnePacket(){
|
||||||
|
protocolBuffer = new ProtocolBuffer(modeText);
|
||||||
|
protocolBuffer.setDelimiter("\r\n");
|
||||||
|
protocolBuffer.appendData(onePacket.getBytes());
|
||||||
|
|
||||||
|
boolean hasMoreData = protocolBuffer.hasMoreCommands();
|
||||||
|
assertTrue(hasMoreData);
|
||||||
|
String nextCommand = protocolBuffer.nextTextCommand();
|
||||||
|
assertEquals(onePacket, nextCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTwoPackets(){
|
||||||
|
protocolBuffer = new ProtocolBuffer(modeText);
|
||||||
|
protocolBuffer.setDelimiter("\r\n");
|
||||||
|
protocolBuffer.appendData(twoPackets.getBytes());
|
||||||
|
|
||||||
|
StringBuilder builder = new StringBuilder();
|
||||||
|
|
||||||
|
while(protocolBuffer.hasMoreCommands()){
|
||||||
|
builder.append(protocolBuffer.nextTextCommand());
|
||||||
|
}
|
||||||
|
assertEquals(twoPackets, builder.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSplitPackets(){
|
||||||
|
protocolBuffer = new ProtocolBuffer(modeText);
|
||||||
|
protocolBuffer.setDelimiter("\r\n");
|
||||||
|
protocolBuffer.appendData(splitPacket.getBytes());
|
||||||
|
|
||||||
|
boolean hasMoreData = protocolBuffer.hasMoreCommands();
|
||||||
|
assertFalse(hasMoreData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOneHalfPacket(){
|
||||||
|
protocolBuffer = new ProtocolBuffer(modeText);
|
||||||
|
protocolBuffer.setDelimiter("\r\n");
|
||||||
|
protocolBuffer.appendData(oneHalfPacket.getBytes());
|
||||||
|
|
||||||
|
boolean hasMoreData = protocolBuffer.hasMoreCommands();
|
||||||
|
assertTrue(hasMoreData);
|
||||||
|
String nextCommand = protocolBuffer.nextTextCommand();
|
||||||
|
assertEquals("$GPAAM,A,A,0.10,N,WPTNME*32\r\n", nextCommand);
|
||||||
|
|
||||||
|
hasMoreData = protocolBuffer.hasMoreCommands();
|
||||||
|
assertFalse(hasMoreData);
|
||||||
|
|
||||||
|
nextCommand = protocolBuffer.nextTextCommand();
|
||||||
|
assertNull(nextCommand);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVerySplit(){
|
||||||
|
protocolBuffer = new ProtocolBuffer(modeText);
|
||||||
|
protocolBuffer.setDelimiter("\r\n");
|
||||||
|
|
||||||
|
protocolBuffer.appendData(verySplit[0].getBytes());
|
||||||
|
boolean hasMoreData = protocolBuffer.hasMoreCommands();
|
||||||
|
assertFalse(hasMoreData);
|
||||||
|
|
||||||
|
protocolBuffer.appendData(verySplit[1].getBytes());
|
||||||
|
hasMoreData = protocolBuffer.hasMoreCommands();
|
||||||
|
assertFalse(hasMoreData);
|
||||||
|
|
||||||
|
protocolBuffer.appendData(verySplit[2].getBytes());
|
||||||
|
hasMoreData = protocolBuffer.hasMoreCommands();
|
||||||
|
assertFalse(hasMoreData);
|
||||||
|
|
||||||
|
protocolBuffer.appendData(verySplit[3].getBytes());
|
||||||
|
hasMoreData = protocolBuffer.hasMoreCommands();
|
||||||
|
assertFalse(hasMoreData);
|
||||||
|
|
||||||
|
protocolBuffer.appendData(verySplit[4].getBytes());
|
||||||
|
hasMoreData = protocolBuffer.hasMoreCommands();
|
||||||
|
assertFalse(hasMoreData);
|
||||||
|
|
||||||
|
protocolBuffer.appendData(verySplit[5].getBytes());
|
||||||
|
hasMoreData = protocolBuffer.hasMoreCommands();
|
||||||
|
assertFalse(hasMoreData);
|
||||||
|
|
||||||
|
protocolBuffer.appendData(verySplit[6].getBytes());
|
||||||
|
hasMoreData = protocolBuffer.hasMoreCommands();
|
||||||
|
assertFalse(hasMoreData);
|
||||||
|
|
||||||
|
protocolBuffer.appendData(verySplit[7].getBytes());
|
||||||
|
hasMoreData = protocolBuffer.hasMoreCommands();
|
||||||
|
assertTrue(hasMoreData);
|
||||||
|
|
||||||
|
String command = protocolBuffer.nextTextCommand();
|
||||||
|
assertEquals("$GPAAM,A,A,0.10,N,WPTNME*32\r\n", command);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testRawPacket(){
|
||||||
|
protocolBuffer = new ProtocolBuffer(modeBinary);
|
||||||
|
protocolBuffer.setDelimiter(new byte[]{0x20, 0x40});
|
||||||
|
protocolBuffer.appendData(rawPacket);
|
||||||
|
|
||||||
|
boolean hasMoreData = protocolBuffer.hasMoreCommands();
|
||||||
|
assertTrue(hasMoreData);
|
||||||
|
|
||||||
|
byte[] command = protocolBuffer.nextBinaryCommand();
|
||||||
|
Assert.assertArrayEquals(command, rawPacket);
|
||||||
|
|
||||||
|
command = protocolBuffer.nextBinaryCommand();
|
||||||
|
assertNull(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTwoRawPackets(){
|
||||||
|
protocolBuffer = new ProtocolBuffer(modeBinary);
|
||||||
|
protocolBuffer.setDelimiter(new byte[]{0x20, 0x40});
|
||||||
|
protocolBuffer.appendData(twoRawPackets);
|
||||||
|
|
||||||
|
boolean hasMoreData = protocolBuffer.hasMoreCommands();
|
||||||
|
assertTrue(hasMoreData);
|
||||||
|
|
||||||
|
byte[] command1 = protocolBuffer.nextBinaryCommand();
|
||||||
|
Assert.assertArrayEquals(command1, new byte[]{0x21, 0x3b, 0x20, 0x40});
|
||||||
|
|
||||||
|
hasMoreData = protocolBuffer.hasMoreCommands();
|
||||||
|
assertTrue(hasMoreData);
|
||||||
|
|
||||||
|
byte[] command2 = protocolBuffer.nextBinaryCommand();
|
||||||
|
Assert.assertArrayEquals(command2, new byte[]{0x4a, 0x20, 0x40});
|
||||||
|
|
||||||
|
command2 = protocolBuffer.nextBinaryCommand();
|
||||||
|
assertNull(command2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSplitRawPacket(){
|
||||||
|
protocolBuffer = new ProtocolBuffer(modeBinary);
|
||||||
|
protocolBuffer.setDelimiter(new byte[]{0x20, 0x40});
|
||||||
|
protocolBuffer.appendData(splitRawPacket);
|
||||||
|
|
||||||
|
boolean hasMoreData = protocolBuffer.hasMoreCommands();
|
||||||
|
assertTrue(hasMoreData);
|
||||||
|
|
||||||
|
byte[] command1 = protocolBuffer.nextBinaryCommand();
|
||||||
|
Assert.assertArrayEquals(command1, new byte[]{0x21, 0x3b, 0x20, 0x40});
|
||||||
|
|
||||||
|
hasMoreData = protocolBuffer.hasMoreCommands();
|
||||||
|
assertFalse(hasMoreData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testVerySplitRawPacket(){
|
||||||
|
protocolBuffer = new ProtocolBuffer(modeBinary);
|
||||||
|
protocolBuffer.setDelimiter(new byte[]{0x20, 0x40});
|
||||||
|
|
||||||
|
protocolBuffer.appendData(verySplitRawPacket[0]);
|
||||||
|
boolean hasMoreData = protocolBuffer.hasMoreCommands();
|
||||||
|
assertFalse(hasMoreData);
|
||||||
|
|
||||||
|
protocolBuffer.appendData(verySplitRawPacket[1]);
|
||||||
|
hasMoreData = protocolBuffer.hasMoreCommands();
|
||||||
|
assertFalse(hasMoreData);
|
||||||
|
|
||||||
|
protocolBuffer.appendData(verySplitRawPacket[2]);
|
||||||
|
hasMoreData = protocolBuffer.hasMoreCommands();
|
||||||
|
assertFalse(hasMoreData);
|
||||||
|
|
||||||
|
protocolBuffer.appendData(verySplitRawPacket[3]);
|
||||||
|
hasMoreData = protocolBuffer.hasMoreCommands();
|
||||||
|
assertTrue(hasMoreData);
|
||||||
|
|
||||||
|
byte[] command = protocolBuffer.nextBinaryCommand();
|
||||||
|
Assert.assertArrayEquals(command, new byte[]{0x21, 0x3b, 0x20, 0x40});
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,16 +1,19 @@
|
||||||
package com.felhr.usbserial;
|
package com.felhr.usbserial;
|
||||||
|
|
||||||
import java.nio.BufferOverflowException;
|
import java.io.EOFException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import okio.Buffer;
|
||||||
|
|
||||||
public class SerialBuffer
|
public class SerialBuffer
|
||||||
{
|
{
|
||||||
public static final int DEFAULT_READ_BUFFER_SIZE = 16 * 1024;
|
static final int DEFAULT_READ_BUFFER_SIZE = 16 * 1024;
|
||||||
public static final int DEFAULT_WRITE_BUFFER_SIZE = 16 * 1024;
|
static final int MAX_BULK_BUFFER = 16 * 1024;
|
||||||
private ByteBuffer readBuffer;
|
private ByteBuffer readBuffer;
|
||||||
private final SynchronizedBuffer writeBuffer;
|
|
||||||
private byte[] readBuffer_compatible; // Read buffer for android < 4.2
|
private SynchronizedBuffer writeBuffer;
|
||||||
|
private byte[] readBufferCompatible; // Read buffer for android < 4.2
|
||||||
private boolean debugging = false;
|
private boolean debugging = false;
|
||||||
|
|
||||||
public SerialBuffer(boolean version)
|
public SerialBuffer(boolean version)
|
||||||
|
@ -22,7 +25,7 @@ public class SerialBuffer
|
||||||
|
|
||||||
}else
|
}else
|
||||||
{
|
{
|
||||||
readBuffer_compatible = new byte[DEFAULT_READ_BUFFER_SIZE];
|
readBufferCompatible = new byte[DEFAULT_READ_BUFFER_SIZE];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,20 +37,6 @@ public class SerialBuffer
|
||||||
debugging = value;
|
debugging = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void putReadBuffer(ByteBuffer data)
|
|
||||||
{
|
|
||||||
synchronized(this)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
readBuffer.put(data);
|
|
||||||
}catch(BufferOverflowException e)
|
|
||||||
{
|
|
||||||
// TO-DO
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ByteBuffer getReadBuffer()
|
public ByteBuffer getReadBuffer()
|
||||||
{
|
{
|
||||||
synchronized(this)
|
synchronized(this)
|
||||||
|
@ -89,57 +78,39 @@ public class SerialBuffer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void resetWriteBuffer()
|
|
||||||
{
|
|
||||||
writeBuffer.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getBufferCompatible()
|
public byte[] getBufferCompatible()
|
||||||
{
|
{
|
||||||
return readBuffer_compatible;
|
return readBufferCompatible;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getDataReceivedCompatible(int numberBytes)
|
public byte[] getDataReceivedCompatible(int numberBytes)
|
||||||
{
|
{
|
||||||
byte[] tempBuff = Arrays.copyOfRange(readBuffer_compatible, 0, numberBytes);
|
return Arrays.copyOfRange(readBufferCompatible, 0, numberBytes);
|
||||||
return tempBuff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SynchronizedBuffer
|
private class SynchronizedBuffer
|
||||||
{
|
{
|
||||||
private final byte[] buffer;
|
private Buffer buffer;
|
||||||
private int position;
|
|
||||||
|
|
||||||
public SynchronizedBuffer()
|
SynchronizedBuffer()
|
||||||
{
|
{
|
||||||
this.buffer = new byte[DEFAULT_WRITE_BUFFER_SIZE];
|
this.buffer = new Buffer();
|
||||||
position = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void put(byte[] src)
|
synchronized void put(byte[] src)
|
||||||
{
|
{
|
||||||
if(src == null || src.length == 0) return;
|
if(src == null || src.length == 0) return;
|
||||||
if(position == -1)
|
|
||||||
position = 0;
|
|
||||||
if(debugging)
|
if(debugging)
|
||||||
UsbSerialDebugger.printLogPut(src, true);
|
UsbSerialDebugger.printLogPut(src, true);
|
||||||
if(position + src.length > DEFAULT_WRITE_BUFFER_SIZE - 1) //Checking bounds. Source data does not fit in buffer
|
|
||||||
{
|
buffer.write(src);
|
||||||
if(position < DEFAULT_WRITE_BUFFER_SIZE)
|
notify();
|
||||||
System.arraycopy(src, 0, buffer, position, DEFAULT_WRITE_BUFFER_SIZE - position);
|
|
||||||
position = DEFAULT_WRITE_BUFFER_SIZE;
|
|
||||||
notify();
|
|
||||||
}else // Source data fits in buffer
|
|
||||||
{
|
|
||||||
System.arraycopy(src, 0, buffer, position, src.length);
|
|
||||||
position += src.length;
|
|
||||||
notify();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized byte[] get()
|
synchronized byte[] get()
|
||||||
{
|
{
|
||||||
if(position == -1)
|
if(buffer.size() == 0)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -149,17 +120,22 @@ public class SerialBuffer
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(position <= -1 ) return new byte[0];
|
byte[] dst;
|
||||||
byte[] dst = Arrays.copyOfRange(buffer, 0, position);
|
if(buffer.size() <= MAX_BULK_BUFFER){
|
||||||
|
dst = buffer.readByteArray();
|
||||||
|
}else{
|
||||||
|
try {
|
||||||
|
dst = buffer.readByteArray(MAX_BULK_BUFFER);
|
||||||
|
} catch (EOFException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return new byte[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(debugging)
|
if(debugging)
|
||||||
UsbSerialDebugger.printLogGet(dst, true);
|
UsbSerialDebugger.printLogGet(dst, true);
|
||||||
position = -1;
|
|
||||||
return dst;
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void reset()
|
return dst;
|
||||||
{
|
|
||||||
position = -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ public abstract class UsbSerialDevice implements UsbSerialInterface
|
||||||
protected final UsbDevice device;
|
protected final UsbDevice device;
|
||||||
protected final UsbDeviceConnection connection;
|
protected final UsbDeviceConnection connection;
|
||||||
|
|
||||||
protected static final int USB_TIMEOUT = 5000;
|
protected static final int USB_TIMEOUT = 0;
|
||||||
|
|
||||||
protected SerialBuffer serialBuffer;
|
protected SerialBuffer serialBuffer;
|
||||||
|
|
||||||
|
@ -506,7 +506,6 @@ public abstract class UsbSerialDevice implements UsbSerialInterface
|
||||||
{
|
{
|
||||||
writeThread.stopThread();
|
writeThread.stopThread();
|
||||||
writeThread = null;
|
writeThread = null;
|
||||||
serialBuffer.resetWriteBuffer();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -176,7 +176,6 @@ public abstract class UsbSpiDevice implements UsbSpiInterface
|
||||||
{
|
{
|
||||||
writeThread.stopThread();
|
writeThread.stopThread();
|
||||||
writeThread = null;
|
writeThread = null;
|
||||||
serialBuffer.resetWriteBuffer();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,153 @@
|
||||||
|
package com.felhr.utils;
|
||||||
|
|
||||||
|
import com.annimon.stream.IntStream;
|
||||||
|
import com.annimon.stream.function.IntPredicate;
|
||||||
|
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class ProtocolBuffer {
|
||||||
|
|
||||||
|
public static final String BINARY = "binary";
|
||||||
|
public static final String TEXT = "text";
|
||||||
|
|
||||||
|
private String mode;
|
||||||
|
|
||||||
|
private static final int DEFAULT_BUFFER_SIZE = 16 * 1024;
|
||||||
|
|
||||||
|
private byte[] rawBuffer;
|
||||||
|
private int bufferPointer = 0;
|
||||||
|
|
||||||
|
private byte[] separator;
|
||||||
|
private String delimiter;
|
||||||
|
private StringBuilder stringBuffer;
|
||||||
|
|
||||||
|
private List<String> commands = new ArrayList<>();
|
||||||
|
private List<byte[]> rawCommands = new ArrayList<>();
|
||||||
|
|
||||||
|
public ProtocolBuffer(String mode){
|
||||||
|
this.mode = mode;
|
||||||
|
if(mode.equals(BINARY)){
|
||||||
|
rawBuffer = new byte[DEFAULT_BUFFER_SIZE];
|
||||||
|
}else{
|
||||||
|
stringBuffer = new StringBuilder(DEFAULT_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProtocolBuffer(String mode, int bufferSize){
|
||||||
|
this.mode = mode;
|
||||||
|
if(mode.equals(BINARY)){
|
||||||
|
rawBuffer = new byte[bufferSize];
|
||||||
|
}else{
|
||||||
|
stringBuffer = new StringBuilder(bufferSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDelimiter(String delimiter){
|
||||||
|
this.delimiter = delimiter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDelimiter(byte[] delimiter){
|
||||||
|
this.separator = delimiter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void appendData(byte[] data){
|
||||||
|
if(mode.equals(TEXT)){
|
||||||
|
try {
|
||||||
|
String dataStr = new String(data, "UTF-8");
|
||||||
|
stringBuffer.append(dataStr);
|
||||||
|
|
||||||
|
String buffer = stringBuffer.toString();
|
||||||
|
int prevIndex = 0;
|
||||||
|
int index = buffer.indexOf(delimiter);
|
||||||
|
while (index >= 0) {
|
||||||
|
String tempStr = buffer.substring(prevIndex, index + delimiter.length());
|
||||||
|
commands.add(tempStr);
|
||||||
|
prevIndex = index + delimiter.length();
|
||||||
|
index = stringBuffer.toString().indexOf(delimiter, prevIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(prevIndex < buffer.length()
|
||||||
|
&& prevIndex > 0){
|
||||||
|
String tempStr = buffer.substring(prevIndex, buffer.length());
|
||||||
|
stringBuffer.setLength(0);
|
||||||
|
stringBuffer.append(tempStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (UnsupportedEncodingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}else if(mode.equals(BINARY)){
|
||||||
|
appendRawData(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasMoreCommands(){
|
||||||
|
if(mode.equals(TEXT)) {
|
||||||
|
return commands.size() > 0;
|
||||||
|
}else {
|
||||||
|
return rawCommands.size() > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String nextTextCommand(){
|
||||||
|
if(commands.size() > 0){
|
||||||
|
return commands.remove(0);
|
||||||
|
}else{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] nextBinaryCommand(){
|
||||||
|
if(rawCommands.size() > 0){
|
||||||
|
return rawCommands.remove(0);
|
||||||
|
}else{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendRawData(byte[] rawData){
|
||||||
|
|
||||||
|
System.arraycopy(rawData, 0, rawBuffer, bufferPointer, rawData.length);
|
||||||
|
bufferPointer += rawData.length;
|
||||||
|
|
||||||
|
SeparatorPredicate predicate = new SeparatorPredicate();
|
||||||
|
int[] indexes =
|
||||||
|
IntStream.range(0, bufferPointer)
|
||||||
|
.filter(predicate)
|
||||||
|
.toArray();
|
||||||
|
|
||||||
|
int prevIndex = 0;
|
||||||
|
for(Integer i : indexes){
|
||||||
|
byte[] command = Arrays.copyOfRange(rawBuffer, prevIndex, i + separator.length);
|
||||||
|
rawCommands.add(command);
|
||||||
|
prevIndex = i + separator.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(prevIndex < rawBuffer.length
|
||||||
|
&& prevIndex > 0){
|
||||||
|
byte[] tempBuffer = Arrays.copyOfRange(rawBuffer, prevIndex, rawBuffer.length);
|
||||||
|
bufferPointer = 0;
|
||||||
|
System.arraycopy(tempBuffer, 0, rawBuffer, bufferPointer, rawData.length);
|
||||||
|
bufferPointer += rawData.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SeparatorPredicate implements IntPredicate{
|
||||||
|
@Override
|
||||||
|
public boolean test(int value) {
|
||||||
|
if(rawBuffer[value] == separator[0]){
|
||||||
|
for(int i=1;i<=separator.length-1;i++){
|
||||||
|
if(rawBuffer[value + i] != separator[i]){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Ładowanie…
Reference in New Issue