package lejos.nxt.comm;
/**
* Support for LCP commands
*
* @author Lawrie Griffiths/Andy Shaw
*
*/
public class LCPResponder extends Thread {
protected NXTCommConnector connector = null;
protected NXTConnection conn = null;
protected boolean running = true;
/**
* Create a Responder using the provided connector
* The connector is used to create the listening connection used to accept
* remote commands.
* @param connector
*/
public LCPResponder(NXTCommConnector connector)
{
this.connector = connector;
}
/**
* Method called when the responder is waiting for a new connection.
* Default action is to wait for the new connection and return.
*/
protected synchronized void waitConnect()
{
while (running && (conn = connector.waitForConnection(0, NXTConnection.LCP)) == null)
try{wait(500);}catch(Exception e){}
}
/**
* Method called to disconnect the responder connect.
* Default action is to close the underlying connection object.
*/
protected synchronized void disconnect()
{
if (conn != null)
conn.close();
conn = null;
}
/**
* Method called with a newly read command, before it is processed.
* Default action is to detect invalid commands and if detected to drop the
* connection.
* @param inMsg Newly read command
* @param len length of the command
* @return the length of the command
*/
protected int preCommand(byte[] inMsg, int len)
{
if (len < 0) disconnect();
return len;
}
/**
* Process the actual command
* Default action is to call the LCP object to emulate the command
* @param inMsg The command bytes
* @param len length of the command
* @param reply bytes to send back in response to the command
* @return length of the reply
*/
protected int command(byte[] inMsg, int len, byte[] reply)
{
return LCP.emulateCommand(inMsg, len, reply);
}
protected void postCommand(byte[] inMsg, int inLen, byte[] replyMsg, int replyLen)
{
if (inMsg[1] == LCP.NXJ_DISCONNECT)
disconnect();
}
public void run()
{
byte[] inMsg = new byte[64];
byte [] reply = new byte[64];
int len;
while (running)
{
waitConnect();
while (conn != null)
{
len = conn.read(inMsg,64);
len = preCommand(inMsg, len);
if (len > 0)
{
int replyLen = command(inMsg,len, reply);
if ((inMsg[0] & 0x80) == 0 && replyLen > 0) conn.write(reply, replyLen);
postCommand(inMsg, len, reply, replyLen);
}
Thread.yield();
}
}
}
/**
* Terminate the responder. Abort any listening operation and close
* any open connections (this will also abort any current read requests).
*/
public synchronized void shutdown()
{
running = false;
// Abort any listening operation, or in progress read
if (conn == null)
super.interrupt();
else
disconnect();
}
}