/**
* Eclipse Public License 1.0
*/
package org.fireblade.easysmsbt;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.TrayIcon.MessageType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.Constructor;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import javax.bluetooth.LocalDevice;
import javax.bluetooth.RemoteDevice;
import javax.bluetooth.UUID;
import javax.imageio.ImageIO;
import javax.microedition.io.Connector;
import javax.microedition.io.StreamConnection;
import javax.swing.UIManager;
/**
* "Proxy" for web browser on pc, mac etc delegating requests via bluetooth
*/
public class BluetoothProxy {
protected static final String WAIT = "<html><head><meta http-equiv=\"Refresh\" content=\"5; URL=$$$\"><style type=\"text/css\" title=\"text/css\"> body { color: red; font-family:\"Arial\", \"Sans serif\";font-size:120%; margin:0; padding:0; cursor:default; }</style><title>Bitte warten - Verbindungsaufbau...</title></head><body><center><b>Bitte bis zu 10 Sekunden warten - Bluetooth Verbindungsaufbau erfolgt...</b></center></body></html>";
protected static String remoteDeviceBluetoothMac = null;
// default timeout
protected static int timeOut = 60;
// defazkt oirt
protected static int port = 1234;
protected static LocalDevice localDevice = null;
protected static RemoteDevice remoteDevice = null;
protected static BTDiscoveryListener listener = null;
protected static StreamConnection btConnection = null;
protected static InputStream btIn = null;
protected static OutputStream btOut = null;
protected static BufferedInputStream btBufferedIn = null;
protected static BufferedOutputStream btBufferedOut = null;
protected static TrayIcon icon;
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
if (args.length != 3) {
System.err.println("3 Parameter: [MAC Adresse des Telefons] [Port] [Idlezeit]");
return;
}
if (args[0].length() != 12) {
System.err.println("MAC Adresse muss aus 12 Zeichen bestehen.");
return;
}
setTray();
remoteDeviceBluetoothMac = args[0];
port = Integer.parseInt(args[1]);
timeOut = Integer.parseInt(args[2]) * 1000;
System.out.println("EasySMS Bluetooth Client V 1.3");
System.out.println("Lade Bluetooth...");
listener = new BTDiscoveryListener();
startServer();
}
static void startServer() {
ServerSocket tcpServerSocket = null;
try {
tcpServerSocket = new ServerSocket(port);
tcpServerSocket.setSoTimeout(timeOut);
Socket tcpClientSocket = null;
int counter = 1;
icon.displayMessage("Bluetooth EasySMS", "Server bereit", MessageType.INFO);
removeDisplayedMessage();
while (true) {
try {
try {
tcpClientSocket = tcpServerSocket.accept();
System.out.println("Proxy Verbindung geoeffnet. Oeffne Bluetooth Verbindung falls noetig.");
boolean online = checkBluetooth();
if (!online) {
handleClientWait(tcpClientSocket);
openBluetooth();
continue;
} else {
openBluetooth();
}
counter++;
} catch (SocketTimeoutException e) {
System.out.println("Proxy Verbindung im Leerlauf. Schliesse Bluetooth Verbindung falls noetig.");
closeBluetooth();
}
} catch (Exception e) {
System.err.println("Fehler: " + e);
icon.displayMessage("Bluetooth EasySMS", "Fehler: " + e, MessageType.ERROR);
e.printStackTrace();
} finally {
if (null != tcpClientSocket) {
try {
tcpClientSocket.close();
} catch (Exception e) {
//ignore
System.out.println("Ignorierter Fehler: " + e);
}
}
}
}
} catch (Exception e) {
System.err.println("Fehler: " + e);
icon.displayMessage("Bluetooth EasySMS", "Fehler! " + e, MessageType.ERROR);
e.printStackTrace();
} finally {
if (null != tcpServerSocket) {
try {
tcpServerSocket.close();
} catch (Exception e) {
System.out.println("Ignorierter Fehler: " + e);
}
}
}
}
static void handleClientWait(Socket tcpClientSocket) throws Exception {
BufferedReader tcpClientIn = new BufferedReader(new InputStreamReader(tcpClientSocket.getInputStream()));
BufferedOutputStream tcpClientOut = new BufferedOutputStream(tcpClientSocket.getOutputStream());
String request = tcpClientIn.readLine();
String requestedURL = "";
tcpClientOut.write(WAIT.replace("$$$", requestedURL).getBytes());
tcpClientOut.flush();
tcpClientSocket.close();
}
static void handleClient(Socket tcpClientSocket) throws Exception {
BufferedReader tcpClientIn = new BufferedReader(new InputStreamReader(tcpClientSocket.getInputStream()));
BufferedOutputStream tcpClientOut = new BufferedOutputStream(tcpClientSocket.getOutputStream());
String line = null;
StringBuffer request = new StringBuffer();
while ((line = tcpClientIn.readLine()) != null) {
request.append(line);
request.append("\r\n");
if (line.equals("")) {
break;
}
}
System.out.println(" Client Request gelesen. Sende an RemoteDevice.");
// write to bluetooth socket
try {
btBufferedOut.write(request.toString().getBytes());
} catch (Exception e) {
// connection closed by mobile. Retry connection-
System.out
.println(" Verbindung durch auen getrennt.\r\n Es erfolgt ein Beenden und Neustart der aktuellen Verbindung.");
btBufferedOut.write(request.toString().getBytes());
}
System.out.println(" Request gesendet. Erwarte Antwort...");
byte[] length = new byte[4];
if (-1 != btBufferedIn.read(length, 0, 4)) {
int len = 0;
byte[] data = new byte[len];
int total = 0;
// TODO: interrupt reader
while (true) {
int count = btBufferedIn.read(data, 0, len);
total += count;
if (total == len) {
System.out.println(" Antwort vollstaendig erhalten.");
break;
}
}
} else {
System.out.println(" FEHLER: konnte kein 4 bytes lesen");
}
}
static boolean checkBluetooth() {
return btConnection != null && btIn != null && btOut != null;
}
static void openBluetooth() throws Exception {
if (null == btConnection) {
icon.displayMessage("Bluetooth EasySMS", "Baue Bluetooth Verbindung auf...", MessageType.INFO);
System.out.println(" Verbinde.");
listener.success = false;
for (int i = 0; i < 2 && !listener.success; i++) {
listener.completed = false;
listener.success = false;
System.out.print(" Discover laeuft: ");
while (!listener.completed) {
Thread.sleep(100);
}
}
if (!listener.success) {
throw new RuntimeException("RemoteDevice nicht verfuegbar.");
}
System.out.println(" Aufbau erfolgt...");
Thread.sleep(500);
int maxRetries = 10;
for (int i = 1; i <= maxRetries; i++) {
try {
icon.displayMessage("Bluetooth EasySMS", "Verbindungsversuch " + i + "/" + maxRetries,
MessageType.INFO);
System.out.println(" Verbindungsversuch " + i + "/" + maxRetries);
btConnection = new Connection();
System.out.println(" Verbindung erfolgreich erstellt in Versuch " + i);
btIn = btConnection.openInputStream();
btOut = btConnection.openOutputStream();
Thread.sleep(1000);
System.out.println(" Verbunden.");
icon.displayMessage("Bluetooth EasySMS", "Verbunden.", MessageType.INFO);
removeDisplayedMessage();
return;
} catch (Exception e) {
icon.displayMessage("Bluetooth EasySMS", "Verbindungsversuch " + i + "/" + maxRetries
+ " fehlgeschlagen. Versuche erneut.", MessageType.INFO);
System.out.println(" Verbindungsversuch " + i + "/" + maxRetries + " fehlgeschlagen.");
Thread.sleep(2000);
}
}
} else {
System.out.println(" Bereits verbunden.");
}
}
static void closeBluetooth() throws Exception {
if (null != btConnection) {
System.out.println(" Trenne.");
icon.displayMessage("Bluetooth EasySMS", "Trenne Verbindung.", MessageType.INFO);
System.gc();
Thread.sleep(1000);
System.out.println(" Getrennt.");
icon.displayMessage("Bluetooth EasySMS", "Getrennt.", MessageType.INFO);
removeDisplayedMessage();
} else {
System.out.println(" Bereits getrennt.");
}
}
static void removeDisplayedMessage() {
new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(1000);
SystemTray.getSystemTray().remove(icon);
SystemTray.getSystemTray().add(icon);
} catch (Exception e) {
System.out.println("Ignorierter Fehler: " + e);
}
}
}).start();
}
static void setTray() throws Exception {
String lf = UIManager.getSystemLookAndFeelClassName();
UIManager.setLookAndFeel(lf);
BufferedImage image = ImageIO.read(new File("sms.png"));
icon = new TrayIcon(image);
icon.setImageAutoSize(true);
SystemTray.getSystemTray().add(icon);
icon.displayMessage("Bluetooth EasySMS", "Initialisiere Anwendung", MessageType.INFO);
PopupMenu menu = new PopupMenu();
MenuItem item = new MenuItem();
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
closeBluetooth();
Thread.sleep(1000);
icon.displayMessage("Bluetooth EasySMS", "Beendet", MessageType.WARNING);
Thread.sleep(1000);
} catch (Exception e) {
icon.displayMessage("Bluetooth EasySMS", "Fehler beim Beenden: " + e, MessageType.WARNING);
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
System.out.println("Ignorierter Fehler: " + e1);
}
}
System.exit(0);
}
});
item.setLabel("Beenden");
menu.add(item);
item = new MenuItem();
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
closeBluetooth();
} catch (Exception e) {
icon.displayMessage("Bluetooth EasySMS", "Fehler beim Trennen: " + e, MessageType.WARNING);
System.out.println("Ignorierter Fehler: " + e);
}
}
});
item.setLabel("Trenne Bluetooth Verbindung");
menu.add(item);
item = new MenuItem();
item.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
openBluetooth();
} catch (Exception e) {
icon.displayMessage("Bluetooth EasySMS", "Fehler beim Verbinden: " + e, MessageType.ERROR);
System.out.println("Ignorierter Fehler: " + e);
}
}
});
item.setLabel("Starte Bluetooth Verbindung");
menu.add(item);
icon.setPopupMenu(menu);
}
}
|