32 package com.neuronrobotics.sdk.common;
34 import java.io.DataInputStream;
35 import java.io.DataOutputStream;
36 import java.io.IOException;
37 import java.util.ArrayList;
38 import java.util.concurrent.locks.ReentrantLock;
40 import javax.management.RuntimeErrorException;
42 import com.neuronrobotics.sdk.commands.bcs.core.NamespaceCommand;
43 import com.neuronrobotics.sdk.commands.bcs.core.PingCommand;
44 import com.neuronrobotics.sdk.commands.bcs.core.RpcArgumentsCommand;
45 import com.neuronrobotics.sdk.commands.bcs.core.RpcCommand;
46 import com.neuronrobotics.sdk.util.ThreadUtil;
80 private ArrayList<IBowlerDatagramListener>
listeners =
new ArrayList<IBowlerDatagramListener>();
83 ArrayList<IConnectionEventListener> disconnectListeners =
new ArrayList<IConnectionEventListener> ();
172 Log.
error(
"Can not send message because the engine is not connected.");
178 long send = System.currentTimeMillis();
182 Log.
info(
"Transmit took: "+(System.currentTimeMillis()-
send)+
" ms");
183 }
catch (IOException e1) {
185 throw new RuntimeException(e1);
187 long startOfReciveTime = System.currentTimeMillis();
197 long rcvTime = (System.currentTimeMillis()-startOfReciveTime);
202 Log.
info(
"Receive took: "+rcvTime +
" ms");
206 Log.
error(
"No response from device, no response in "+(System.currentTimeMillis()-startOfReciveTime)+
" ms");
211 Log.
error(
"Switching to legacy parser");
239 sendable.setUpstream(
true);
241 write(sendable.getBytes());
242 }
catch (IOException e1) {
243 Log.
error(
"No response from device...");
256 Log.
info(
"Disconnecting Bowler Connection");
263 }
catch (NullPointerException e) {
266 }
catch (IOException e) {
271 Log.
info(
"Shutting down streams");
321 Log.
info(
"Setting connection to "+c);
342 Runtime.getRuntime().addShutdownHook(
new Thread() {
357 }
catch (Exception e) {
363 }
catch (Exception e) {
419 Log.
info(
"Added packet to the response queue");
457 Log.
info(
"\nASYNC listener: "+l.getClass());
461 }
catch (Exception ex){
462 ex.printStackTrace();
524 public DataInputStream
getDataIns() throws NullPointerException{
526 throw new NullPointerException();
546 public DataOutputStream
getDataOuts() throws NullPointerException{
548 throw new NullPointerException();
560 Log.
info(
"Waiting for connection...");
561 long start = System.currentTimeMillis() ;
563 if(System.currentTimeMillis()> (start + 20000)){
602 this.asyncQueue.start();
603 asyncQueue.setName(
"Bowler Platform Asynchronus Queue");
615 this.syncQueue.start();
616 syncQueue.setName(
"Bowler Platform Synchronus Queue");
652 if(b.isSyncronous()){
671 if(!disconnectListeners.contains(l)) {
672 disconnectListeners.add(l);
682 if(disconnectListeners.contains(l)) {
683 disconnectListeners.remove(l);
692 l.onDisconnect(
this);
716 throw new RuntimeException(
"There is already a listener "+
syncListen);
728 throw new RuntimeException(
"There is a different listener "+
syncListen);
744 if(ns.getNamespace().toLowerCase().contains(
namespace.toLowerCase())){
747 if( rpc.getRpc().toLowerCase().contains(rpcString.toLowerCase()) &&
748 rpc.getDownstreamMethod() == method){
791 return new Object [0];
822 Object [] en =
parseResponse(
namespace, method, rpcString,dg);
827 Log.
error(
"No method found, attempted "+
namespace+
" RPC: "+rpcString);
831 throw new DeviceConnectionException(
"Device does not contain command NS="+
namespace+
" Method="+method+
" RPC="+rpcString+
"'");
867 if(tmpNs.length() == namespacePacket.
getData().
size()){
875 Log.
error(
"Not enougn namespaces!"+namespacePacket);
879 Log.
warning(
"This is an older implementation of core, depricated");
883 Log.
error(
"Not enougn namespaces!"+namespacePacket);
887 Log.
info(
"This is the new core");
897 for (
int i=0;i<num;i++){
903 Log.
debug(
"Adding Namespace: "+space);
907 Log.
debug(
"There are "+num+
" namespaces on this device");
914 Log.
error(
"Invalid response from Namespace");
919 Log.
error(
"No connection is available.");
922 }
catch (Exception e) {
926 throw new RuntimeException(e);
958 if(ns.getNamespace().contains(
string))
972 int namespaceIndex = 0;
973 boolean hasCoreRpcNS =
false;
979 if(
namespaceList.get(i).getNamespace().contains(
"bcs.rpc.*")){
985 Log.
info(
"Device has no RPC identification namespace");
986 return new ArrayList<RpcEncapsulation>();
997 if(!b.
getRPC().contains(
"_rpc")){
998 System.err.println(b);
999 throw new RuntimeException(
"This RPC index request has failed");
1006 }
catch(IndexOutOfBoundsException e){
1007 e.printStackTrace();
1008 throw new RuntimeException(e.getMessage()+
"\r\n"+b);
1011 Log.
error(
"RPC request failed:\n"+b);
1013 Log.
info(
"Number of RPC's = "+numRpcs);
1015 Log.
debug(
"There are "+numRpcs+
" RPC's in "+
namespace);
1016 namespaceList.get(namespaceIndex).setRpcList(
new ArrayList<RpcEncapsulation>());
1017 for (
int i=0;i<numRpcs;i++){
1019 if(!b.
getRPC().contains(
"_rpc")){
1020 System.err.println(b);
1021 throw new RuntimeException(
"This RPC section failed");
1027 if(!b.
getRPC().contains(
"args")){
1028 System.err.println(b);
1029 throw new RuntimeException(
"This RPC section failed");
1034 int numDownArgs = data[1];
1036 int numUpArgs = data[numDownArgs+3];
1041 for(
int k=0;k<numDownArgs;k++){
1044 for(
int k=0;k<numUpArgs;k++){
1050 tmpRpc =
new RpcEncapsulation(namespaceIndex,
namespace, rpcStr, downstreamMethod,downArgs,upstreamMethod,upArgs);
1051 }
catch (RuntimeException e){
1052 Log.
error(
"Argumet parsing failure!\r\n"+b);
1062 Log.
debug(
"Older version of core, discovery disabled");
1078 return send(command,addr,retry,
false);
1093 for(
int i=0;i<retry;i++){
1098 ret =
send( command,addr,switchParser);
1107 Log.
error(
"Sending Synchronus packet and there was a failure, will retry "+(retry-i-1)+
" more times");
1111 Log.
error(
"Sending Synchronus packet and there was a failure, will retry "+(retry-i-1)+
" more times");
1113 }
catch (NullPointerException e) {
1114 Log.
error(
"Sending Synchronus packet and there was a failure, will retry "+(retry-i-1)+
" more times");
1137 return send(command,addr,
false);
1161 return command.validate(back);
1190 return ping( mac,
false);
1211 Log.
error(
"Invalid response from Ping ");
1213 }
catch (Exception e) {
1214 Log.
error(
"No connection is available.");
1234 if (msHeartBeatTime<10)
1235 msHeartBeatTime = 10;
1255 Log.
debug(
"Ping failed, disconnecting");
1258 }
catch(Exception e){
1259 Log.
debug(
"Ping failed, disconnecting");
1309 private ArrayList<BowlerDatagram>
queueBuffer =
new ArrayList<BowlerDatagram>();
1338 long start = System.currentTimeMillis();
1346 long packetUpdate = System.currentTimeMillis();
1355 long pulledPacket = System.currentTimeMillis();
1358 long pushedPacket = System.currentTimeMillis();
1362 "\nPacket Update\t"+(packetUpdate- start)+
"" +
1363 "\nPulled Packet\t"+(pulledPacket-packetUpdate)+
"" +
1364 "\nPushed Packet\t"+(pushedPacket-pulledPacket));
1367 }
catch(Exception e){
1368 e.printStackTrace();
1412 }
catch (Exception e) {
1415 Log.
error(
"Data read failed "+e.getMessage());
1416 e.printStackTrace();
1497 }
catch (IOException e){
1499 Log.
error(
"IO Error "+e.getMessage());
1503 for(b=0;b<have;b++){
1505 Log.
error(
"Adding "+(have-b-1)+
" after packet found");
1511 Log.
error(
"Stream is broken - unexpected: claimed to have "+have+
" bytes, read in "+b);
1514 new RuntimeException(
" Buffer attempted to read "+have+
" got "+b).printStackTrace();
1517 bytesToPacketBuffer.add(ret);
1542 public void write(
byte[] data)
throws IOException {
1550 while(outgoing.
size()>0){
1556 }
catch (Exception e){
1558 Log.
error(
"Write failed. "+e.getMessage());
1562 Log.
error(
"No data sent, stream closed");
void setMethod(BowlerMethod method)
void setOpCode(String opCode)
void addDatagram(BowlerDatagram dg)
ByteList bytesToPacketBuffer
ArrayList< BowlerDatagram > queueBuffer
boolean runPacketUpdate()
void fireDisconnectEvent()
void setAsyncQueue(QueueManager asyncQueue)
BowlerDatagram loadPacketFromPhy(ByteList bytesToPacketBuffer)
boolean ping(MACAddress mac, boolean switchParser)
void setChunkSize(int chunkSize)
Object[] send(MACAddress addr, String namespace, BowlerMethod method, String rpcString, Object[] arguments, int retry)
ArrayList< String > getNamespaces(MACAddress addr)
void setLastWrite(long lastWrite)
void addDatagramListener(IBowlerDatagramListener listener)
void removeSynchronousDatagramListener(ISynchronousDatagramListener l)
boolean hasNamespace(String string, MACAddress addr)
ArrayList< IBowlerDatagramListener > listeners
DataOutputStream getDataOuts()
void pushUp(BowlerDatagram b)
DataOutputStream dataOuts
void setDataOuts(DataOutputStream dataOuts)
void setBeater(boolean beater)
RpcEncapsulation locateRpc(String namespace, BowlerMethod method, String rpcString)
ArrayList< String > nameSpaceStrings
void setDataIns(DataInputStream dataIns)
boolean isUseThreadedStack()
Object[] parseResponse(String namespace, BowlerMethod method, String rpcString, BowlerDatagram dg)
void setPercentagePrint(double percentagePrint)
void onDataReceived(BowlerDatagram data)
ISynchronousDatagramListener syncListen
void setUseThreadedStack(boolean useThreadedStack)
static BowlerAbstractCommand getCommand(String namespace, BowlerMethod method, String rpcString, Object[] arguments, RpcEncapsulation rpc)
void setSynchronusPacketTimeoutTime(int sleepTime)
double getPercentagePrint()
void addConnectionEventListener(IConnectionEventListener l)
void startHeartBeat(long msHeartBeatTime)
void removeDatagramListener(IBowlerDatagramListener listener)
synchronized void setConnected(boolean c)
boolean namespacesFinishedInitializing
BowlerDatagram send(BowlerAbstractCommand command, MACAddress addr, int retry)
abstract boolean waitingForConnection()
void setSynchronousDatagramListener(ISynchronousDatagramListener l)
void removeConnectionEventListener(IConnectionEventListener l)
void clearLastSyncronousResponse()
abstract boolean connect()
BowlerDatagram send(BowlerAbstractCommand command, MACAddress addr, int retry, boolean switchParser)
boolean ping(MACAddress mac)
ArrayList< RpcEncapsulation > getRpcList(String namespace, MACAddress addr)
BowlerDatagram getLastSyncronousResponse()
QueueManager getAsyncQueue()
BowlerDatagram send(BowlerAbstractCommand command, MACAddress addr)
void waitForConnectioToBeReady()
void setSyncQueue(QueueManager syncQueue)
BowlerDatagram fireSyncOnReceive(BowlerDatagram datagram)
void setThreadedUpstreamPackets(boolean up)
void fireAsyncOnResponse(BowlerDatagram datagram)
synchronized BowlerDatagram sendSynchronusly(BowlerDatagram sendable, boolean switchParser)
QueueManager getSyncQueue()
BowlerDatagram sendSynchronusly(BowlerDatagram sendable)
BowlerDatagram send(BowlerAbstractCommand command, MACAddress addr, boolean switchParser)
void sendAsync(BowlerDatagram sendable)
DataInputStream getDataIns()
boolean isInitializedNamespaces()
ArrayList< NamespaceEncapsulation > namespaceList
void setUpstream(boolean upstream)
static void setUseBowlerV4(boolean useBowlerV4)
static boolean isUseBowlerV4()
byte[] popList(int index)
static void enableErrorPrint()
static void info(String message)
static void error(String message)
static void setMinimumPrintLevel(int level)
static void warning(String message)
static void debug(String message)
static int getMinimumPrintLevel()
Object[] parseResponse(BowlerDatagram datagram)
BowlerAbstractCommand getCommand(Object[] doswnstreamData)
void setStartTime(long startTime)
static void wait(int time)
static BowlerDataType get(byte code)
static BowlerMethod get(byte code)
void onAsyncResponse(BowlerDatagram data)
BowlerDatagram onSyncReceive(BowlerDatagram data)