/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package org.oobd.base.bus;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.oobd.base.*;
import org.oobd.base.port.ComPort_Telnet;
import org.oobd.base.port.OOBDPort;
import org.oobd.base.port.PortInfo;
import org.oobd.base.support.Onion;
import org.json.JSONException;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import java.util.*;
public class BusCom extends OobdBus implements OOBDConstants {
static Enumeration portList;
static boolean outputBufferEmptyFlag = false;
ComReader reader = null;
Hashtable<String, Long> udpBroadcasts;
public BusCom() {
super("Buscom");
}
@Override
public void registerCore(Core thisCore) {
super.registerCore(thisCore);
}
@Override
public String getPluginName() {
return "b:Com";
}
public void run() {
reader = new ComReader();
udpBroadcasts = new Hashtable<String, Long>();
DatagramSocket socket = core.getSystemIF().getUDPBroadcastSocket();
byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
while (keepRunning == true) {
Message msg = getMsgPort().getMsg(500);
if (msg != null) {
Onion on = msg.getContent();
// System.out.println("Buscom Message abgeholt:" +
// on.toString());
String command = on.getOnionString("command");
if ("serWrite".equalsIgnoreCase(command)) {
String data = Base64Coder.decodeString(on
.getOnionString("data"));
Logger.getLogger(BusCom.class.getName()).log(Level.INFO,
"busCom serWrite: >" + data + "<");
reader.write(data);
} else if ("serFlush".equalsIgnoreCase(command)) {
Logger.getLogger(BusCom.class.getName()).log(Level.INFO,
"busCom serFlush ");
reader.flush();
} else if ("serWait".equalsIgnoreCase(command)) {
try {
Integer result = reader.wait(Base64Coder
.decodeString(on.getOnionString("data")), on
.getInt("timeout"));
Logger.getLogger(BusCom.class.getName()).log(
Level.INFO, "busCom serWait: " + result);
replyMsg(
msg,
new Onion("" + "{'type':'" + CM_RES_BUS + "',"
+ "'owner':" + "{'name':'"
+ getPluginName() + "'}," + "'result':"
+ result + "," + "'replyID':"
+ on.getInt("msgID") + "}"));
} catch (JSONException ex) {
Logger.getLogger(BusCom.class.getName()).log(
Level.SEVERE, null, ex);
}
} else if ("connect".equalsIgnoreCase(command)) {
reader.close();
Boolean result = reader.connect((OOBDPort) getCore()
.supplyHardwareHandle(on), on, this);
try {
replyMsg(msg,
new Onion("" + "{'type':'" + CM_RES_BUS + "',"
+ "'owner':" + "{'name':'"
+ getPluginName() + "'}," + "'result':"
+ result.toString() + ","
+ "'replyID':" + on.getInt("msgID")
+ "}"));
} catch (JSONException ex) {
Logger.getLogger(BusCom.class.getName()).log(
Level.SEVERE, null, ex);
}
} else if ("close".equalsIgnoreCase(command)) {
reader.close();
} else if ("serReadLn".equalsIgnoreCase(command)) {
try {
String result = reader.readln(on.getInt("timeout"),
on.optBoolean("ignore"));
Logger.getLogger(BusCom.class.getName()).log(
Level.INFO, "busCom readline: " + result);
replyMsg(
msg,
new Onion("" + "{'type':'" + CM_RES_BUS + "',"
+ "'owner':" + "{'name':'"
+ getPluginName() + "'},"
+ "'replyID':" + on.getInt("msgID")
+ "," + "'result':'"
+ Base64Coder.encodeString(result)
+ "'}"));
} catch (JSONException ex) {
Logger.getLogger(BusCom.class.getName()).log(
Level.SEVERE, null, ex);
}
}
} else { // check the incoming
if (socket != null) {
try {
socket.setSoTimeout(5);
socket.receive(packet);
String broadcastMsg = new String(packet.getData())
.substring(0, packet.getLength());
System.err.println("UPD received:" + broadcastMsg);
boolean listHasChanged = false;
Long acTime = System.currentTimeMillis();
if (!udpBroadcasts.containsValue(broadcastMsg)) {
listHasChanged = true;
}
udpBroadcasts.put(broadcastMsg, acTime);
Enumeration<String> e = udpBroadcasts.keys();
while (e.hasMoreElements()) {
// we go through the keys to get the time to then
// delete
// the entry by the key, if too old
String key = (String) e.nextElement();
if (acTime - udpBroadcasts.get(key) > 30000) { // older
// as
// 30
// secs?
listHasChanged = true;
udpBroadcasts.remove(key);
}
}
if (listHasChanged) {
e = udpBroadcasts.keys();
PortInfo[] udpDeviceList = new PortInfo[udpBroadcasts
.size()];
int i = 0;
while (e.hasMoreElements()) {
// we go through the keys to get the time to
// then
// delete the entry by the key, if too old
String key = (String) e.nextElement();
Onion broadcast = new Onion(key); // using an
// Onion
// object
// just
// for parse
// the
// JSON
// Strng
udpDeviceList[i++] = new PortInfo(
broadcast.getOnionString("ip")
+ ":"
+ broadcast.getInt("port"),
broadcast.getOnionString("device")
);
}
ComPort_Telnet.setPorts(udpDeviceList);
}
} catch (Exception e) {
// general catch up of any receiving problems
}
}
}
}
}
@Override
public void receiveString(String msg) {
if (reader != null) {
reader.receiveString(msg);
}
}
}
// class ComReader implements Runnable {
class ComReader {
public String URL = null;
private StringBuffer inBuffer = new StringBuffer();
OOBDPort comHandle;
public ComReader() {
// new Thread(this).start();
}
public boolean connect(OOBDPort portHandle, Onion options, OobdBus bus) {
if (comHandle != null) {
comHandle.close();
comHandle = null;
}
if (portHandle == null) {
return false;
}
if (portHandle.connect(options, bus)) {
comHandle = portHandle;
return true;
} else {
comHandle = null;
return false;
}
}
public void close() {
if (comHandle != null) {
try {
comHandle.close();
comHandle = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
public synchronized void receiveString(String msg) {
inBuffer.append(msg);
}
// public synchronized void write(char c) {
// if (comHandle != null && comHandle.getOutputStream() != null) {
// try {
// comHandle.getOutputStream().write(c);
// } catch (IOException ex) {
// Logger.getLogger(ComReader.class.getName()).log(Level.WARNING,
// null, ex);
// }
// }
// }
public synchronized void write(String s) {
if (comHandle != null) {
comHandle.write(s);
} else {
System.err.println("NO comhandle:" + s);
}
}
/**
* \todo this routine actual polls, but as e.g. shown in the purejavacomm-
* Demo (), the reveice can also be done as an EventListener
*/
// public void run() {
// while (true) {
//
// int input;
// int n;
//
// try {
// if (false && comHandle != null && comHandle.getInputStream() != null) {
// n = comHandle.getInputStream().available();
// if (n > 0) {
// byte[] buffer = new byte[n];
//
// n = comHandle.getInputStream().read(buffer, 0, n);
//
// for (int i = 0; i < n; ++i) {
// inBuffer.append((char) buffer[i]);
// }
// } else {
// try {
// Thread.sleep(10);
// } catch (InterruptedException ex) {
// // the VM doesn't want us to sleep anymore,
// // so get back to work
// Logger.getLogger(ComReader.class.getName()).log(
// Level.WARNING, null, ex);
//
// }
// }
// } else {
// // as this thread runs in an unstopped endless loop, as
// // long
// // there's no serial port open, we need to slow him down
// // here...
// try {
// Thread.sleep(100);
// } catch (InterruptedException e) {
// // the VM doesn't want us to sleep anymore,
// // so get back to work
// }
// }
//
// } catch (Exception ex) {
// Logger.getLogger(ComReader.class.getName()).log(Level.WARNING,
// "Unexpected error: Close down socket", ex);
// close();
// }
// }
// }
public void flush() {
while (read() > (char) 0)
;
}
public boolean isConnected() {
return comHandle != null;
}
public synchronized int read() {
// if (comHandle != null && comHandle.getInputStream() != null) {
if (inBuffer.length() > 0) {
char c = inBuffer.charAt(0);
inBuffer.deleteCharAt(0);
return (int) c;
} else {
return -1;
} /*
* if (btConnection != null) { return btConnection.read(); }
*/
// }
// return -2; // -2 stands for "no connection"
}
public String readln(int timeout, boolean ignoreEmptyLines) {
String res = "";
if (isConnected()) {
boolean waitForever = timeout < 1;
boolean doLoop = true;
int c;
long timeOutInMillis = System.currentTimeMillis()
+ comHandle.adjustTimeOut(timeout);
int sleepTime = 2;
while (doLoop && isConnected()) {
c = read();
if (c > 0) {
// if (c != 10 && c != 13) {
if (c > 31) {
res += (char) c;
}
if (c == 13) { // CR detected, condition meet - LF (0x10) is
// completely ignored
// res+=".";
doLoop = res.equals("") && ignoreEmptyLines;
}
} else {
if (waitForever) {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
// the VM doesn't want us to sleep anymore,
// so get back to work
}
} else {
if (timeOutInMillis <= System.currentTimeMillis()) {
doLoop = false;
} else {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
// the VM doesn't want us to sleep anymore,
// so get back to work
}
}
}
}
}
}
Logger.getLogger(ComReader.class.getName()).log(Level.INFO,
"Serial input:" + res);
return res;
}
public int wait(String conditions, int timeout) {
int result = 0;
if (isConnected()) {
boolean waitForever = timeout < 1;
boolean doLoop = true;
int c;
int sleepTime = 5;
long timeOutInMillis = System.currentTimeMillis()
+ comHandle.adjustTimeOut(timeout);
Conditions con = new Conditions(conditions);
while (doLoop && isConnected()) {
c = read();
if (c > -1) {
result = con.checkConditions((char) c);
if (result > 0) { // condition meet
doLoop = false;
}
} else {
if (waitForever) {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
// the VM doesn't want us to sleep anymore,
// so get back to work
}
} else {
if (timeOutInMillis <= System.currentTimeMillis()) {
doLoop = false;
} else {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
// the VM doesn't want us to sleep anymore,
// so get back to work
}
}
}
}
}
}
return result;
}
}
class Conditions {
Vector conVector = new Vector();
class SingleCondition {
String text;
int index = 0, pos = 0;
SingleCondition(String text, int index) {
this.text = text;
this.index = index;
}
int check(char c) {
if (text.charAt(pos) == Character.toLowerCase(c)) {
pos++;
if (pos == text.length()) {
return index;
} else {
return 0;
}
} else {
// start again
pos = 0;
return 0;
}
}
}
Conditions(String conString) {
int p = 0;
int index = 1;
String out = "";
if (conString.charAt(conString.length() - 1) != '|') {
conString += '|';
}
while (p < conString.length()) {
if (conString.charAt(p) != '|') {
out += conString.charAt(p);
} else {
if (out.length() > 0) {
conVector.addElement(new SingleCondition(out.toLowerCase(),
index));
out = "";
}
index++;
}
p++;
}
}
int checkConditions(char c) {
int v = 0;
int result = 0;
while (v < conVector.size() && result == 0) {
result = ((SingleCondition) conVector.elementAt(v)).check(c);
v++;
}
return result;
}
}