|
@@ -0,0 +1,270 @@
|
|
|
+package de.nplusc.izc.MegatronBridge;
|
|
|
+
|
|
|
+
|
|
|
+import com.fazecast.jSerialComm.SerialPort;
|
|
|
+
|
|
|
+import javax.sql.rowset.serial.SQLOutputImpl;
|
|
|
+import java.io.*;
|
|
|
+import java.util.LinkedList;
|
|
|
+import java.util.Queue;
|
|
|
+
|
|
|
+enum NextChunkAction
|
|
|
+{
|
|
|
+ WAIT,
|
|
|
+ REPEAT,
|
|
|
+ CONTINUE,
|
|
|
+ FINISHED
|
|
|
+}
|
|
|
+
|
|
|
+public class SerialSpammer
|
|
|
+{
|
|
|
+
|
|
|
+
|
|
|
+ private InputStream in = null;
|
|
|
+ private OutputStream o = null;
|
|
|
+ private NextChunkAction nextChunkReady = NextChunkAction.WAIT;
|
|
|
+ private int waitCtr = 0;
|
|
|
+ private Object workaround = new Object();
|
|
|
+
|
|
|
+ private Queue<CommandQueueItem> queue= new LinkedList<>();
|
|
|
+ private boolean startedStreamPlayback = false;
|
|
|
+
|
|
|
+ public Queue<CommandQueueItem> getQueue()
|
|
|
+ {
|
|
|
+ return queue;
|
|
|
+ }
|
|
|
+
|
|
|
+ private final char[] hex = "0123456789ABCDEF".toCharArray();
|
|
|
+ private RandomAccessFile streamfile = null;
|
|
|
+ public SerialSpammer(String comPortName)
|
|
|
+ {
|
|
|
+
|
|
|
+ System.out.println("Gobblygob");
|
|
|
+
|
|
|
+ int sendOffset = 0;
|
|
|
+ SerialPort comPort = SerialPort.getCommPort(comPortName);
|
|
|
+ comPort.openPort();
|
|
|
+ comPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 0, 0);
|
|
|
+ in = comPort.getInputStream();
|
|
|
+ o = comPort.getOutputStream();
|
|
|
+ new Thread(()->
|
|
|
+
|
|
|
+ {
|
|
|
+ System.out.println("MunchMunchMunch");
|
|
|
+ try
|
|
|
+ {
|
|
|
+ while (true)
|
|
|
+ {
|
|
|
+ if(in.available()<1)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ int read = in.read();
|
|
|
+ if (read == '~')
|
|
|
+ {
|
|
|
+ System.out.println("RSME");
|
|
|
+ nextChunkReady = NextChunkAction.CONTINUE;
|
|
|
+ synchronized (workaround)
|
|
|
+ {
|
|
|
+ System.out.println("POKE");
|
|
|
+ workaround.notify();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ if (read == '<')
|
|
|
+ {
|
|
|
+ nextChunkReady = NextChunkAction.REPEAT;
|
|
|
+ synchronized (workaround)
|
|
|
+ {
|
|
|
+ System.out.println("POKE");
|
|
|
+ workaround.notify();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ System.out.write(read);
|
|
|
+ System.out.flush();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (IOException e)
|
|
|
+ {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }).start();
|
|
|
+
|
|
|
+ new Thread(()->
|
|
|
+
|
|
|
+ {
|
|
|
+ while(true)
|
|
|
+ {
|
|
|
+ CommandQueueItem itm = queue.poll();
|
|
|
+ if(itm != null)
|
|
|
+ {
|
|
|
+ switch (itm.type)
|
|
|
+ {
|
|
|
+ case ServoAction:
|
|
|
+ if(itm.argument>15&&itm.argument<0)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ try
|
|
|
+ {
|
|
|
+ o.write('*');
|
|
|
+ o.write('S');
|
|
|
+ o.write(hex[itm.argument]);
|
|
|
+ o.write('G');
|
|
|
+ } catch (IOException e)
|
|
|
+ {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case OnboardAudio:
|
|
|
+ if(itm.argument>15&&itm.argument<0)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ try
|
|
|
+ {
|
|
|
+ o.write('*');
|
|
|
+ o.write('T');
|
|
|
+ o.write(hex[itm.argument]);
|
|
|
+ o.write('G');
|
|
|
+ } catch (IOException e)
|
|
|
+ {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case CustomAudio:
|
|
|
+ if(itm.argument<0)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ LinkedList<Character> reverser = new LinkedList<>();
|
|
|
+ int arg = itm.argument;
|
|
|
+ while(arg>15)
|
|
|
+ {
|
|
|
+ reverser.add(hex[arg%16]);
|
|
|
+ arg>>=4;
|
|
|
+ }
|
|
|
+ try
|
|
|
+ {
|
|
|
+ o.write('*');
|
|
|
+ while(true)
|
|
|
+ {
|
|
|
+ Character c = reverser.pollLast();
|
|
|
+ if(c==null)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ o.write(c);
|
|
|
+ }
|
|
|
+ o.write('v');
|
|
|
+ } catch (IOException e)
|
|
|
+ {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+
|
|
|
+ case StreamAudio:
|
|
|
+ String path = itm.patharg;
|
|
|
+ System.out.println("Streaming: "+path);
|
|
|
+ if(new File(path).exists())
|
|
|
+ {
|
|
|
+ try
|
|
|
+ {
|
|
|
+ streamfile = new RandomAccessFile(path,"r");
|
|
|
+ nextChunkReady=NextChunkAction.CONTINUE;
|
|
|
+ synchronized (workaround)
|
|
|
+ {
|
|
|
+ System.out.println("POKE");
|
|
|
+ workaround.notify();
|
|
|
+ }
|
|
|
+ } catch (FileNotFoundException e)
|
|
|
+ {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case MundwerkToggle:
|
|
|
+ try
|
|
|
+ {
|
|
|
+ o.write('M');
|
|
|
+ try
|
|
|
+ {
|
|
|
+ Thread.sleep(10);
|
|
|
+ } catch (InterruptedException e)
|
|
|
+ {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ } catch (IOException e)
|
|
|
+ {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(streamfile!=null)
|
|
|
+ {
|
|
|
+ try{
|
|
|
+ if(streamfile.getFilePointer()>=streamfile.length())
|
|
|
+ {
|
|
|
+ System.out.println("FINI");
|
|
|
+ System.err.println("FINI");
|
|
|
+ streamfile.close();
|
|
|
+ streamfile=null;
|
|
|
+ startedStreamPlayback=false;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if((!startedStreamPlayback)&&(streamfile.getFilePointer()==8192||streamfile.getFilePointer()==streamfile.length()))
|
|
|
+ {
|
|
|
+ System.out.println("PLAY");
|
|
|
+ o.write('|');
|
|
|
+ startedStreamPlayback=true;
|
|
|
+ }
|
|
|
+ switch(nextChunkReady)
|
|
|
+ {
|
|
|
+ case REPEAT:
|
|
|
+ System.out.println("RTRY=("+streamfile.getFilePointer()+")");
|
|
|
+ waitCtr=0;
|
|
|
+ if(streamfile.getFilePointer()>=64)
|
|
|
+ {
|
|
|
+ streamfile.seek(streamfile.getFilePointer()-64);
|
|
|
+ }
|
|
|
+ case CONTINUE:
|
|
|
+ waitCtr=0;
|
|
|
+ System.out.println("STR=("+streamfile.getFilePointer()+")");
|
|
|
+ byte[] readbfr = new byte[64];
|
|
|
+ streamfile.read(readbfr);
|
|
|
+ o.write('>');
|
|
|
+ nextChunkReady=NextChunkAction.WAIT;
|
|
|
+ o.write(readbfr);
|
|
|
+
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ synchronized (workaround)
|
|
|
+ {
|
|
|
+ if(nextChunkReady==NextChunkAction.WAIT)
|
|
|
+ {
|
|
|
+ System.out.println("GOTO WAIT");
|
|
|
+ try
|
|
|
+ {
|
|
|
+ workaround.wait();
|
|
|
+ } catch (InterruptedException e)
|
|
|
+ {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ catch (IOException e)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }).start();
|
|
|
+ }
|
|
|
+}
|