/*
* Communicator.java , Creates a serial port connection Uses RxTxComm java library
*/
import gnu.io.CommPort;
import gnu.io.CommPortIdentifier;
import gnu.io.PortInUseException;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import java.awt.Color;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.TooManyListenersException;
import javax.xml.bind.DatatypeConverter;
public class Communicator implements SerialPortEventListener {
// passed from main GUI
GUI window = null;
// for containing the ports that will be found
private Enumeration<?> ports = null;
// map the port names to CommPortIdentifiers
private HashMap<String, CommPortIdentifier> portMap = new HashMap<String, CommPortIdentifier>();
// this is the object that contains the opened port
private CommPortIdentifier selectedPortIdentifier = null;
private SerialPort serialPort = null;
// input and output streams for sending and receiving data
private InputStream input = null;
private OutputStream output = null;
private BufferedReader buffer = null;
// just a boolean flag that i use for enabling
// and disabling buttons depending on whether the program
// is connected to a serial port or not
private boolean bConnected = false;
private boolean canSend = true;
// the timeout value for connecting with the port
final static int TIMEOUT = 2000;
// Special characters
final static int CMD_TERMINATE_CHAR = 255;
final static int ENTER_ASCII = 32;
final static int DASH_ASCII = 45;
final static int NEW_LINE_ASCII = 10;
final static int INVALID_COMMAND = 244;
// a string for recording what goes on in the program
// this string is written to the GUI
String logText = "";
public Communicator(GUI window) {
this.window = window;
}
// search for all the serial ports
// pre: none
// post: adds all the found ports to a combo box on the GUI
public void searchForPorts() {
ports = CommPortIdentifier.getPortIdentifiers();
while (ports.hasMoreElements()) {
CommPortIdentifier curPort = (CommPortIdentifier) ports
.nextElement();
// get only serial ports
if (curPort.getPortType() == CommPortIdentifier.PORT_SERIAL) {
window.cBoxPorts.addItem(curPort.getName());
portMap.put(curPort.getName(), curPort);
}
}
}
// connect to the selected port in the combo box
// pre: ports are already found by using the searchForPorts method
// post: the connected comm port is stored in commPort, otherwise,
// an exception is generated
public void connect() {
String selectedPort = (String) window.cBoxPorts.getSelectedItem();
selectedPortIdentifier = portMap.get(selectedPort);
CommPort commPort = null;
try {
// the method below returns an object of type CommPort
commPort = selectedPortIdentifier.open("SYSC 2003 Robot Debug",
TIMEOUT);
// the CommPort object can be casted to a SerialPort object
serialPort = (SerialPort) commPort;
// for controlling GUI elements
setConnected(true);
// logging
window.txtLog.setForeground(Color.black);
// CODE ON SETTING BAUD RATE ETC ...
} catch (PortInUseException e) {
logText = selectedPort + " is in use. (" + e.toString() + ")";
window.txtLog.setForeground(Color.RED);
window.txtLog.append(logText + "\n");
} catch (Exception e) {
logText = "Failed to open " + selectedPort + "(" + e.toString()
+ ")";
window.txtLog.append(logText + "\n");
window.txtLog.setForeground(Color.RED);
}
}
// open the input and output streams
// pre: an open port
// post: initialized intput and output streams for use to communicate data
public boolean initIOStream() {
// return value for whather opening the streams is successful or not
boolean successful = false;
try {
//
input = serialPort.getInputStream();
output = serialPort.getOutputStream();
buffer = new BufferedReader(new InputStreamReader(input));
successful = true;
return successful;
} catch (IOException e) {
logText = "I/O Streams failed to open. (" + e.toString() + ")";
window.txtLog.setForeground(Color.red);
window.txtLog.append(logText + "\n");
return successful;
}
}
// starts the event listener that knows whenever data is available to be
// read
// pre: an open serial port
// post: an event listener for the serial port that knows when data is
// recieved
public void initListener() {
try {
serialPort.addEventListener(this);
serialPort.notifyOnDataAvailable(true);
} catch (TooManyListenersException e) {
logText = "Too many listeners. (" + e.toString() + ")";
window.txtLog.setForeground(Color.red);
window.txtLog.append(logText + "\n");
}
}
// disconnect the serial port
// pre: an open serial port
// post: clsoed serial port
public void disconnect() {
// close the serial port
try {
serialPort.removeEventListener();
serialPort.close();
input.close();
output.close();
setConnected(false);
// window.keybindingController.toggleControls();
window.lblStatusLabel.setText("Disconnected");
window.txtLog.setForeground(Color.red);
} catch (Exception e) {
logText = "Failed to close " + serialPort.getName() + "("
+ e.toString() + ")";
window.txtLog.setForeground(Color.red);
window.txtLog.append(logText + "\n");
}
}
final public boolean getConnected() {
return bConnected;
}
public void setConnected(boolean bConnected) {
this.bConnected = bConnected;
}
public boolean canSend() {
return canSend;
}
public SerialPort getSerialPort() {
return serialPort;
}
// what happens when data is received
// pre: serial event is triggered
// post: processing on the data it reads
public void serialEvent(SerialPortEvent evt) {
String incoming = "";
if (evt.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
incoming = buffer.readLine();
parseRecieved(incoming);
//System.out.println(incoming);
window.txtLog.setCaretPosition(window.txtLog.getDocument()
.getLength());
} catch (Exception e) {
logText = "Failed to read data. (" + e.toString() + ")";
window.txtLog.setForeground(Color.red);
window.txtLog.append(logText + "\n");
}
}
}
private void parseRecieved(String incomingData) {
// TODO Auto-generated method stub
System.out.println(incomingData);
if(incomingData.length()>0){
switch (incomingData.charAt(0)) {
case ('O'):
window.txtLog.append("\nOK\n");
break;
case ('I'):
window.txtLog.append("\nInvalid Command\n");
break;
case ('P'):
window.txtLog.append("\nInvalid Param\n");
break;
case ('K'):
window.txtLog.append("\nOK\n");
window.lblKeypad.setText(incomingData.charAt(1)+"");
window.btnPullKeypad.setEnabled(true);
break;
case ('F'):
window.lblRps.setText("RPS: " + Integer.parseInt(DatatypeConverter.printHexBinary((incomingData.charAt(1)+ "").getBytes()), 16)/2);
}
}
//this.incomingData = "";*/
}
// method that can be called to send data
// pre: open serial port
// post: data sent to the other device
public void writeData(String data) {
try {
for (byte b : data.getBytes("US-ASCII")) {
output.write(b);
}
output.write(CMD_TERMINATE_CHAR);
output.flush();
window.txtLog.append("\n->" + data + "\n");
} catch (Exception e) {
logText = "Failed to write data. (" + "Connection not established"
+ ")";
window.txtLog.setForeground(Color.red);
window.txtLog.append(logText + "\n");
e.printStackTrace();
}
}
}