/** jNetwork Manager
*
* Created : May 3, 2012
*
* I've decided to replace NetworkManager with my own implementation.
* NetworkManager is a well developed system but interfacing with it from Java is difficult.
*
*/
import java.io.*;
import java.net.*;
import java.util.*;
import javaforce.*;
import javaforce.jbus.*;
public class Server {
private boolean startup;
private String wapList = "";
private Timer wapTimer;
public VPNConnection pendingVPN;
public WAPConnection pendingWAP;
public static Server This;
public JBusClient jbusClient;
public ArrayList<VPNConnection> vpnConnections = new ArrayList<VPNConnection>();
public ArrayList<WAPConnection> wapConnections = new ArrayList<WAPConnection>();
public ArrayList<Interface> interfaceList = new ArrayList<Interface>(); //active interfaces
public ArrayList<DHCPClient> dhcpClients = new ArrayList<DHCPClient>(); //for active interfaces
private static final boolean bluez3 = false; //no longer available
public static void main(String args[]) {
//this is currently not used : unless jnetworkmgr becomes a seperate package
JFLog.init("/var/log/jnetworkmgr.log", true);
new Server().start();
}
public void start() {
try {
This = this;
startup = true;
jbusClient = new JBusClient("org.jflinux.jnetworkmgr", new JBusMethods());
jbusClient.start();
loadConfig();
Interface iface = getInterface("static"); //psuedo-interface for static values
iface.domain_name = config.domain;
iface.domain_name_servers = config.dns1 + " " + config.dns2 + " " + config.dns3;
doDNS(iface);
listIFs();
for(int a=0;a<interfaceList.size();a++) {
startIF(interfaceList.get(a).dev);
}
createWAPTimer();
new NetLinkMonitor().start();
startup = false;
} catch (Exception e) {
JFLog.log(e);
}
}
private void updateLink(Interface iface) {
try {
FileInputStream fis = new FileInputStream("/sys/class/net/" + iface.dev + "/carrier");
char carrier = (char)fis.read();
fis.close();
iface.link = (carrier == '1');
} catch (Exception e) {
JFLog.log(e);
}
}
private void listIFs() {
ShellProcess sp = new ShellProcess();
String ifconfig = sp.run(new String[] {"ifconfig", "-a"}, false);
String lns[] = ifconfig.split("\n");
String iwconfig = sp.run(new String[] {"iwconfig"}, false);
String wlns[] = iwconfig.split("\n");
for(int a=0;a<lns.length;a++) {
if (!lns[a].startsWith(" ")) {
int idx = lns[a].indexOf(" ");
if (idx == -1) continue;
String dev = lns[a].substring(0, idx);
idx = dev.indexOf(":"); //fedora has a ':' after name
if (idx != -1) {
dev = dev.substring(0, idx);
}
if (dev.equals("lo")) continue;
Interface iface = getInterface(dev);
for(int w=0;w<wlns.length;w++) {
if (wlns[w].startsWith(dev)) {
if (wlns[w].indexOf("ESSID") != -1) {
iface.wireless = true;
}
break;
}
}
interfaceList.add(iface);
JFLog.log("interface:" + iface.dev + ":wireless=" + iface.wireless);
}
}
}
public static class Config {
public Interface iface[];
public String dns1, dns2, dns3;
public String hostname, domain;
}
private Config config;
private String configFolder = "/etc/jconfig.d/";
private String configFile = "network.xml";
private Interface highestRoute = null; //interface with highest priority
private Interface highestDNS = null; //interface with highest priority
private void loadConfig() {
defaultConfig();
try {
XML xml = new XML();
FileInputStream fis = new FileInputStream(configFolder + configFile);
xml.read(fis);
xml.writeClass(config);
fis.close();
} catch (FileNotFoundException e1) {
defaultConfig();
} catch (Exception e2) {
JFLog.log(e2);
defaultConfig();
}
}
private void defaultConfig() {
config = new Config();
config.iface = new Interface[0];
config.hostname = "localhost";
config.domain = "localdomain";
config.dns1 = "";
config.dns2 = "";
config.dns3 = "";
}
public void updateInterface(Interface iface) {
//update config options
Interface update = null;
for(int a=0;a<config.iface.length;a++) {
Interface i = config.iface[a];
if (i.dev.equals(iface.dev)) {
update = i;
break;
}
}
if (update == null) return;
iface.dhcp4 = update.dhcp4;
iface.dhcp6 = update.dhcp6;
iface.disableIP6 = update.disableIP6;
iface.ip4 = update.ip4;
iface.mask4 = update.mask4;
iface.gateway4 = update.gateway4;
iface.ip6 = update.ip6;
iface.gateway6 = update.gateway6;
}
public Interface getInterface(String dev) {
Interface iface;
loadConfig(); //redo in case of changes
//try interfaceList first
for(int a=0;a<interfaceList.size();a++) {
iface = interfaceList.get(a);
if (iface.dev.equals(dev)) {
updateInterface(iface);
return iface;
}
}
//try config next
for(int a=0;a<config.iface.length;a++) {
iface = config.iface[a];
if (iface.dev.equals(dev)) {
return iface;
}
}
//return a new empty instance of Interface
iface = new Interface();
iface.dev = dev;
return iface;
}
public static String mask(String ipstr, String maskstr) {
try {
InetAddress ip = InetAddress.getByName(ipstr);
byte ip4[] = ip.getAddress();
InetAddress mask = InetAddress.getByName(maskstr);
byte mask4[] = mask.getAddress();
for(int a=0;a<ip4.length;a++) {
ip4[a] &= mask4[a];
}
InetAddress ret = InetAddress.getByAddress(ip4);
return ret.getHostAddress();
} catch (Exception e) {
JFLog.log(e);
}
return null;
}
private void startIF(String dev) {
JFLog.log("jnetworkmgr:Starting:" + dev);
ShellProcess sp = new ShellProcess();
String output = sp.run(new String[] {"ifconfig", dev, "up"}, true);
if (sp.getErrorLevel() != 0) {
JFLog.log("jnetworkmgr:Failed to start interface:" + dev + ":Output=" + output);
return;
}
Interface iface = getInterface(dev);
iface.active = true;
updateLink(iface);
if (!iface.wireless) { //do not setup wireless interfaces now
setupInterface(iface);
}
}
public void setupInterface(Interface iface) {
//ensure interface link is active
if (!iface.link) {
JFLog.log("Warning:jnetworkmgr:setting up interface but link is down:" + iface.dev);
}
ShellProcess sp = new ShellProcess();
if (iface.dhcp4) {
DHCPClient client = new DHCPClient(iface, true);
client.start();
dhcpClients.add(client);
} else {
//set static IP4
sp.run(new String[] {"ifconfig", iface.dev, iface.ip4, "netmask", iface.mask4}, true);
iface.routers = iface.gateway4;
iface.domain_name = config.domain;
iface.domain_name_servers = config.dns1 + " " + config.dns2 + " " + config.dns3;
doRouting(iface);
doDNS(iface);
if (pendingWAP != null && iface.pack != null) {
This.jbusClient.call(iface.pack, "wapSuccess", "");
pendingWAP = null;
iface.pack = null;
}
}
if (iface.dhcp6) {
DHCPClient client = new DHCPClient(iface, false);
client.start();
dhcpClients.add(client);
} else {
if (!iface.disableIP6) {
//set static IP6
sp.run(new String[] {"ifconfig", iface.dev, "add", iface.ip6 + "/64"}, true);
//TODO : IP6???
// doRouting6(iface);
// doDNS6(iface);
}
}
iface.setup = true;
}
private void stopIF(String dev) {
JFLog.log("jnetworkmgr:Stoping:" + dev);
Interface iface = getInterface(dev);
ShellProcess sp = new ShellProcess();
sp.run(new String[] {"ifconfig", dev, "0.0.0.0"}, true); //remove IP first
String output = sp.run(new String[] {"ifconfig", dev, "down"}, true);
if (sp.getErrorLevel() != 0) {
JFLog.log("jnetworkmgr:Failed to stop interface:" + dev + ":Output=" + output);
}
tearDownInterface(dev);
iface.active = false;
}
public void tearDownInterface(String dev) {
Interface iface = getInterface(dev);
for(int a=0;a<dhcpClients.size();) {
if (dhcpClients.get(a).getDevice().equals(dev)) {
dhcpClients.get(a).close();
dhcpClients.remove(a);
} else {
a++;
}
}
undoRouting(iface, true);
undoDNS(iface, true);
//remove from priority chain
if (iface.higherRoute != null) {
iface.higherRoute.lowerRoute = iface.lowerRoute;
}
if (iface.lowerRoute != null) {
iface.lowerRoute.higherRoute = iface.higherRoute;
}
if (iface.higherDNS != null) {
iface.higherDNS.lowerDNS = iface.lowerDNS;
}
if (iface.lowerDNS != null) {
iface.lowerDNS.higherDNS = iface.higherDNS;
}
iface.setup = false;
}
private boolean isIFactive(String dev) {
for(int a=0;a<interfaceList.size();a++) {
Interface iface = interfaceList.get(a);
if (iface.dev.equals(dev)) {
return iface.active;
}
}
return false;
}
public static void dhcpSuccess(Interface iface) {
if (Server.This.pendingWAP != null && iface.pack != null) {
This.jbusClient.call(iface.pack, "wapSuccess", "");
Server.This.pendingWAP = null;
iface.pack = null;
}
}
private void exec(String args[]) {
try { Runtime.getRuntime().exec(args); } catch (Exception e) {JFLog.log(e);}
}
/** Configures routing table */
public void doRouting(Interface iface) {
if (highestRoute == null) {
highestRoute = iface;
} else {
if (iface.higherRoute != null) {
//is not the highest route
return;
}
if ((iface.lowerRoute == null) && (highestRoute != iface)) {
highestRoute.higherRoute = iface;
iface.lowerRoute = highestRoute;
highestRoute = iface;
}
}
String routers[] = iface.routers.split(" ");
exec(new String[] {"route", "add", "-net", "0.0.0.0", "gw", routers[0]});
if (iface.static_routes != null) {
String staticRoutes[] = iface.static_routes.split(" ");
//TODO : do static routes???
}
}
/** Configures /etc/resolv.conf */
public void doDNS(Interface iface) {
// JFLog.log("doDNS:" + iface.dev + ":highest=" + (highestDNS == null ? "null" : highestDNS.dev) + ":lowerDNS=" + (iface.lowerDNS == null ? "null" : iface.lowerDNS.dev));
if (highestDNS == null) {
highestDNS = iface;
} else {
if (iface.higherDNS != null) {
JFLog.log("doDNS:Not highest DNS");
return;
}
if ((iface.lowerDNS == null) && (highestDNS != iface)) {
highestDNS.higherDNS = iface;
iface.lowerDNS = highestDNS;
highestDNS = iface;
}
}
// JFLog.log("Applying DNS:" + iface.dev + ":" + iface.domain_name_servers);
try {
String dns[] = iface.domain_name_servers.split(" ");
FileOutputStream fos = new FileOutputStream("/etc/resolv.conf");
fos.write(("domain " + iface.domain_name + "\n").getBytes());
fos.write(("search " + iface.domain_name + "\n").getBytes());
for(int a=0;a<dns.length;a++) {
if (dns[a].length() == 0) continue;
fos.write(("nameserver " + dns[a] + "\n").getBytes());
}
fos.close();
} catch (Exception e) {
JFLog.log(e);
}
}
/** Unconfigure routing table */
private void undoRouting(Interface iface, boolean useLower) {
if (highestRoute != iface) return;
String routers[] = iface.routers.split(" ");
exec(new String[] {"route", "del", "-net", "0.0.0.0"});
// String staticRoutes[] = iface.static_routes.split(" ");
//TODO : undo static routes???
//find next interface with lower priority and switch to it's routing
if (useLower) {
if (iface.lowerRoute != null) {
//remove this from chain - never go back up after lowering
iface.lowerRoute.higherRoute = null;
highestRoute = iface.lowerRoute;
doRouting(iface.lowerRoute);
}
}
}
private void removeDNS() {
//no interface available
try {
FileOutputStream fos = new FileOutputStream("/etc/resolv.conf");
fos.write("#no interface currently available".getBytes());
fos.close();
} catch (Exception e) {
JFLog.log(e);
}
}
/** Unconfigure /etc/resolv.conf */
public void undoDNS(Interface iface, boolean useLower) {
// JFLog.log("undoDNS:" + iface.dev + ":highest=" + (highestDNS == null ? "null" : highestDNS.dev) + ":lowerDNS=" + (iface.lowerDNS == null ? "null" : iface.lowerDNS.dev));
if (highestDNS != iface) return;
if (useLower) {
if (iface.lowerDNS != null) {
//remove this from chain - never go back up after lowering
iface.lowerDNS.higherDNS = null;
highestDNS = iface.lowerDNS;
doDNS(iface.lowerDNS);
} else {
removeDNS();
}
} else {
// removeDNS(); //not needed since this change is temporary
}
}
private void processScript(String argString) {
String args[] = argString.split(",");
String reason = null, ifaceName = null, medium = null;
String new_ip_address = null, new_subnet_mask = null, new_domain_name = null, new_domain_name_servers = null, new_routers = null, new_static_routes = null;
String old_ip_address = null, old_subnet_mask = null, old_domain_name = null, old_domain_name_servers = null, old_routers = null, old_static_routes = null;
for(int a=0;a<args.length;a++) {
if (args[a].startsWith("reason=")) {reason = args[a].substring(7); continue;}
if (args[a].startsWith("interface=")) {ifaceName = args[a].substring(10); continue;}
if (args[a].startsWith("medium=")) {medium = args[a].substring(7); continue;}
if (args[a].startsWith("new_ip_address=")) {new_ip_address = args[a].substring(15); continue;}
if (args[a].startsWith("new_subnet_mask=")) {new_subnet_mask = args[a].substring(16); continue;}
if (args[a].startsWith("new_domain_name=")) {new_domain_name = args[a].substring(16); continue;}
if (args[a].startsWith("new_domain_name_servers=")) {new_domain_name_servers = args[a].substring(24); continue;}
if (args[a].startsWith("new_routers=")) {new_routers = args[a].substring(12); continue;}
if (args[a].startsWith("new_static_routes=")) {new_static_routes = args[a].substring(18); continue;}
if (args[a].startsWith("old_ip_address=")) {old_ip_address = args[a].substring(15); continue;}
if (args[a].startsWith("old_subnet_mask=")) {old_subnet_mask = args[a].substring(16); continue;}
if (args[a].startsWith("old_domain_name=")) {old_domain_name = args[a].substring(16); continue;}
if (args[a].startsWith("old_domain_name_servers=")) {old_domain_name_servers = args[a].substring(24); continue;}
if (args[a].startsWith("old_routers=")) {old_routers = args[a].substring(12); continue;}
if (args[a].startsWith("old_static_routes=")) {old_static_routes = args[a].substring(18); continue;}
}
JFLog.log("jnetworkmgr.script:" + reason + " on " + ifaceName);
Interface iface = getInterface(ifaceName);
if (reason.equals("MEDIUM")) {
//ifconfig $interface medium $medium
exec(new String[] {"ifconfig", ifaceName, "medium", medium});
return;
}
if (reason.equals("EXPIRE") || reason.equals("FAIL")) {
undoRouting(iface, true);
undoDNS(iface, true);
reason = "PREINIT";
}
if (reason.equals("PREINIT")) {
//ifconfig $interface 0.0.0.0
exec(new String[] {"ifconfig", ifaceName, "0.0.0.0"});
//ifconfig $interface broadcast
exec(new String[] {"ifconfig", ifaceName, "broadcast"});
return;
}
if (reason.equals("REBIND")) {
//if IP has changed clear ARP table
if (!old_ip_address.equals(new_ip_address)) {
exec(new String[] {"ip", "neigh", "flush", "dev", ifaceName});
}
reason = "RENEW";
}
if (reason.equals("RENEW")) {
//delete anything that has changed new_ -> old_
if ((!old_routers.equals(new_routers) && (old_routers.length() > 0))
|| ((!old_static_routes.equals(new_static_routes)) && (old_static_routes.length() > 0))) {
undoRouting(iface, false);
}
if (!old_domain_name_servers.equals(new_domain_name_servers)) {
undoDNS(iface, false);
}
reason = "BOUND";
}
if (reason.equals("BOUND") || reason.equals("REBOOT")) {
//ifconfig $interface $new_ip_address
exec(new String[] {"ifconfig", ifaceName, new_ip_address});
iface.ip4 = new_ip_address;
//ifconfig $interface netmask $new_subnet_mask
exec(new String[] {"ifconfig", ifaceName, new_subnet_mask});
iface.mask4 = new_subnet_mask;
iface.domain_name = new_domain_name;
iface.domain_name_servers = new_domain_name_servers;
iface.routers = new_routers;
iface.static_routes = new_static_routes;
doRouting(iface);
doDNS(iface);
return;
}
//ignored : STOP, RELEASE, NBI, TIMEOUT
}
private void getWAPList() {
String newWapList = "";
ShellProcess sp = new ShellProcess();
for(int a=0;a<interfaceList.size();a++) {
Interface iface = interfaceList.get(a);
if (!iface.wireless) continue;
String output = sp.run(new String[] {"iwlist", iface.dev, "scan"}, false);
if (output == null) output = "";
output = output.replaceAll("\n", "|");
output = output.replaceAll("\"", "\'");
String wapScan = output;
newWapList += genWAPList(iface.dev, wapScan);
}
wapList = newWapList;
jbusClient.call("org.jflinux.jfsystemmgr", "broadcastWAPList", quote(wapList));
}
private String genWAPList(String dev, String wapScan) {
int cnt = 0;
String list = "";
String lns[] = wapScan.split("[|]");
String wap = null, encType = "?";
for(int a=0;a<lns.length;a++) {
String ln = lns[a].trim();
if (ln.startsWith("Cell ")) {
if (wap != null) {
list += wap;
if (isWAPactive(wap)) list += " *";
list += "|" + encType + "|";
cnt++;
}
wap = null;
encType = "OPEN";
continue;
}
if (ln.startsWith("ESSID:")) {
wap = ln.substring(7,ln.length() - 1); //remove quotes
if (wap.length() == 0) {
wap = null;
encType = null;
continue;
}
continue;
}
if (ln.startsWith("Encryption key:")) {
//comes before ESSID in list
String value = ln.substring(15);
if (value.equals("on")) {
encType = "WEP"; //unless WPA is found later down
}
continue;
}
if (ln.endsWith("WPA Version 1")) {
encType = "WPA";
continue;
}
if (ln.endsWith("WPA2 Version 1")) {
encType = "WPA";
continue;
}
}
if (wap != null) {
list += wap;
if (isWAPactive(wap)) list += " *";
list += "|" + encType + "|";
cnt++;
}
return dev + "|" + cnt + "|" + list;
}
private boolean checkWireless() {
for(int a=0;a<interfaceList.size();a++) {
if (interfaceList.get(a).wireless) return true;
}
return false;
}
private void createWAPTimer() {
wapTimer = new java.util.Timer();
wapTimer.schedule(new TimerTask() {
public void run() {
//update wireless list if not connected to any every minute
if ((wapConnections.isEmpty()) && checkWireless()) getWAPList();
}
}, 0, 60 * 1000);
}
public static class VPN {
public String name;
public String host;
public String caps; //windows = pre-defined, else: pap, mschap, etc.
public String capsOpts; //flags
public String routes; //comma list
public String routeOpts; //flags
public String user, pass, domain;
public String domainsearch;
}
public static class VPNConfig {
public VPN vpn[];
}
private VPNConfig vpnConfig;
private String vpnConfigFile = "/etc/jconfig.d/vpn.xml";
private synchronized void loadVPNConfig() {
defaultVPNConfig();
try {
XML xml = new XML();
FileInputStream fis = new FileInputStream(vpnConfigFile);
xml.read(fis);
xml.writeClass(vpnConfig);
} catch (FileNotFoundException e1) {
defaultVPNConfig();
} catch (Exception e2) {
JFLog.log(e2);
defaultVPNConfig();
}
}
private void defaultVPNConfig() {
vpnConfig = new VPNConfig();
vpnConfig.vpn = new VPN[0];
}
private boolean isVPNactive(String name) {
for(int a=0;a<vpnConnections.size();a++) {
if (vpnConnections.get(a).name.equals(name)) return true;
}
return false;
}
private boolean isWAPactive(String ssid) {
for(int a=0;a<wapConnections.size();a++) {
if (wapConnections.get(a).ssid.equals(ssid)) return true;
}
return false;
}
private static String quote(String str) {
return "\"" + str + "\"";
}
private String bluetoothctlPrompt = ".*\\p{Punct}bluetooth\\p{Punct}.*\\p{Punct}"; //ESC[0;49m[bluetooth]ESC[0m#
public class JBusMethods {
public void notifyUp(String dev) {
if (startup) return;
//TODO : start dhcp client ???
}
public void notifyDown(String dev) {
if (startup) return;
//TODO : stop dhcp client ???
}
public void script(String args) {
processScript(args);
}
public void ifUp(String dev) {
JFLog.log("ifUp:" + dev);
if (isIFactive(dev)) {JFLog.log("already up"); return;}
startIF(dev);
}
public void ifDown(String dev) {
JFLog.log("ifDown:" + dev);
if (!isIFactive(dev)) {JFLog.log("already down"); return;}
stopIF(dev);
}
public void connectVPN(String pack, String id, String host, String user, String pass, String domain,
String caps, String capsOpts, String routes, String routeOpts, String domainsearch) {
VPNConnection conn = new VPNConnection();
conn.id = id;
conn.pack = pack;
conn.host = host;
conn.user = user;
conn.pass = pass;
conn.domain = domain;
conn.caps = caps;
conn.capsOpts = capsOpts;
conn.routes = routes;
conn.routeOpts = routeOpts;
conn.domainsearch = domainsearch;
vpnConnections.add(conn);
conn.start();
}
public void disconnectVPN(String id) {
for(int a=0;a<vpnConnections.size();a++) {
if (vpnConnections.get(a).id.equals(id)) {
vpnConnections.get(a).close();
vpnConnections.remove(a);
return;
}
}
}
public void getWAPList(String pack) {
jbusClient.call(pack, "setWAPList", quote(wapList));
}
public void connectWAP(String pack, String dev, String ssid, String encType, String key) {
if (pendingWAP != null) return;
WAPConnection wap = new WAPConnection();
wap.init(pack,dev,ssid,encType,key);
pendingWAP = wap;
wap.start();
wapConnections.add(wap);
}
public void disconnectWAP(String pack, String dev) {
ShellProcess sp = new ShellProcess();
sp.run(new String[] {"iwconfig", dev, "essid", "any"}, false);
tearDownInterface(dev); //stop dhcp clients (if any)
//stop wpa_supplicant if used
for(int a=0;a<wapConnections.size();) {
if (wapConnections.get(a).dev.equals(dev)) {
wapConnections.get(a).close();
wapConnections.remove(a);
} else {
a++;
}
}
}
public void cancelWAP() {
if (pendingWAP == null) return;
pendingWAP.close();
pendingWAP = null;
}
public void getBTdevices(String pack) {
ShellProcess sp = new ShellProcess();
// ShellProcess.log = true;
// ShellProcess.logPrompt = true;
String list = "";
if (bluez3) {
sp.addRegexResponse(bluetoothctlPrompt, "show\n", false);
sp.addRegexResponse(bluetoothctlPrompt, "exit\n", false);
String output = sp.run(new String[] {"bluetoothctl"}, false);
JFLog.log("output=" + output);
String lns[] = output.split("\n");
for(int a=0;a<lns.length;a++) {
if (lns[a].startsWith("Controller")) {
if (list.length() > 0) list += "|";
list += lns[a].substring(11, 11+17);
} else if (lns[a].indexOf("Powered") != -1) {
if (list.length() > 0) list += "|";
list += lns[a].indexOf("yes") != -1 ? "UP" : "DOWN";
}
}
} else {
String output = sp.run(new String[] {"hciconfig"}, false);
String lns[] = output.split("\n");
for(int a=0;a<lns.length;a++) {
if (lns[a].startsWith(" ")) {
if (lns[a].trim().startsWith("UP")) {
if (list.length() > 0) list += "|";
list += "UP";
}
if (lns[a].trim().startsWith("DOWN")) {
if (list.length() > 0) list += "|";
list += "DOWN";
}
} else {
String dev = lns[a];
int idx = dev.indexOf(" ");
if (idx != -1) dev = dev.substring(0, idx);
idx = dev.indexOf(":");
if (idx != -1) dev = dev.substring(0, idx);
if (list.length() > 0) list += "|";
list += dev;
}
}
}
jbusClient.call(pack, "setBTdevices", quote(list));
}
//enable bluetook controlling device
public void enableBTdevice(String pack, String cmac) {
final ShellProcess sp = new ShellProcess();
if (bluez3) {
sp.addRegexResponse(bluetoothctlPrompt, "select " + cmac + "\n", false);
sp.addRegexResponse(bluetoothctlPrompt, "power on\n", false);
sp.addRegexResponse(bluetoothctlPrompt, "exit\n", false);
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
try {
sp.getOutputStream().write(("exit\n").getBytes());
sp.getOutputStream().flush();
} catch (Exception e) {}
}
}, 5 * 1000, 1000);
String output = sp.run(new String[] {"bluetoothctl"}, false);
//JFLog.log("enableBTdevice.output=" + output);
timer.cancel();
if (output.indexOf("succeeded") != -1) {
jbusClient.call(pack, "btSuccess", "");
} else {
jbusClient.call(pack, "btFailed", "");
}
} else {
String output = sp.run(new String[] {"hciconfig", cmac/*dev*/, "up"}, false);
if (sp.getErrorLevel() == 0) {
jbusClient.call(pack, "btSuccess", "");
} else {
jbusClient.call(pack, "btFailed", "");
}
}
}
//disable bluetook controlling device
public void disableBTdevice(String pack, String cmac) {
final ShellProcess sp = new ShellProcess();
if (bluez3) {
sp.addRegexResponse(bluetoothctlPrompt, "select " + cmac + "\n", false);
sp.addRegexResponse(bluetoothctlPrompt, "power off\n", false);
sp.addRegexResponse(bluetoothctlPrompt, "exit\n", false);
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
try {
sp.getOutputStream().write(("exit\n").getBytes());
sp.getOutputStream().flush();
} catch (Exception e) {}
}
}, 5 * 1000, 1000);
String output = sp.run(new String[] {"bluetoothctl"}, false);
timer.cancel();
if (output.indexOf("succeeded") != -1) {
jbusClient.call(pack, "btSuccess", "");
} else {
jbusClient.call(pack, "btFailed", "");
}
} else {
String output = sp.run(new String[] {"hciconfig", cmac/*dev*/, "down"}, false);
if (sp.getErrorLevel() == 0) {
jbusClient.call(pack, "btSuccess", "");
} else {
jbusClient.call(pack, "btFailed", "");
}
}
}
//connect to end device thru controller
public synchronized void connectBT(String pack, String cmac, final String mmac) {
final ShellProcess sp = new ShellProcess();
if (bluez3) {
//use bluetoothctl
sp.addListener(new ShellProcessListenerAdapter() {
String output = "";
boolean scanComplete = false;
boolean connectComplete = false;
public void shellProcessOutput(String string) {
if (!connectComplete && output.indexOf("Pairing successful") != -1 && output.indexOf("Connection successful") != -1) {
sp.addRegexResponse(bluetoothctlPrompt, "exit\n", false);
connectComplete = true;
//need to wake up ShellProcess to make it process prompt/response again
try {
sp.getOutputStream().write("version\n".getBytes());
sp.getOutputStream().flush();
} catch (Exception e) {}
return;
}
if (scanComplete) return;
output += string;
if (output.indexOf(mmac) != -1) {
sp.addRegexResponse(bluetoothctlPrompt, "trust " + mmac + "\n", false);
sp.addRegexResponse(bluetoothctlPrompt, "pairable on\n", false);
sp.addRegexResponse(bluetoothctlPrompt, "pair " + mmac + "\n", false);
sp.addRegexResponse(bluetoothctlPrompt, "connect " + mmac + "\n", false);
scanComplete = true;
//need to wake up ShellProcess to make it process prompt/response again
try {
sp.getOutputStream().write("version\n".getBytes());
sp.getOutputStream().flush();
} catch (Exception e) {}
}
}
});
sp.addRegexResponse(bluetoothctlPrompt, "select " + cmac + "\n", false);
sp.addRegexResponse(bluetoothctlPrompt, "scan on\n", false);
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
try {
sp.getOutputStream().write(("exit\n").getBytes());
sp.getOutputStream().flush();
} catch (Exception e) {}
}
}, 10 * 1000, 1000);
String output = sp.run(new String [] {"bluetoothctl"}, false);
timer.cancel();
//JFLog.log("connectBT.output=" + output);
if (output.indexOf("Connection successful") != -1) {
jbusClient.call(pack, "btSuccess", "");
} else {
jbusClient.call(pack, "btFailed", "");
}
} else {
//use hcitool (not working yet) [use to use hidd --connect but removed in bluez5.x)
String output = sp.run(new String[] {"hcitool", "cc", mmac}, false);
if (sp.getErrorLevel() == 0) {
jbusClient.call(pack, "btSuccess", "");
} else {
jbusClient.call(pack, "btFailed", "");
}
}
}
//disconnect from end device thru controller
public void disconnectBT(String pack, String cmac, String mmac) {
final ShellProcess sp = new ShellProcess();
if (true) {
//use bluetoothctl
sp.addRegexResponse(bluetoothctlPrompt, "select " + cmac + "\n", false);
sp.addRegexResponse(bluetoothctlPrompt, "remove " + mmac + "\n", false);
sp.addRegexResponse(bluetoothctlPrompt, "exit\n", false);
Timer timer = new Timer();
timer.schedule(new TimerTask() {
public void run() {
try {
sp.getOutputStream().write(("exit\n").getBytes());
sp.getOutputStream().flush();
} catch (Exception e) {}
}
}, 5 * 1000, 1000);
String output = sp.run(new String [] {"bluetoothctl"}, false);
timer.cancel();
//TODO : check output
jbusClient.call(pack, "btSuccess", "");
} else {
String output = sp.run(new String[] {"hcitool", "dc", mmac}, false);
if (sp.getErrorLevel() == 0) {
jbusClient.call(pack, "btSuccess", "");
} else {
jbusClient.call(pack, "btFailed", "");
}
}
}
public void getVPNList(String pack) {
String vpnList = "";
loadVPNConfig();
for(int a=0;a<vpnConfig.vpn.length;a++) {
String name = vpnConfig.vpn[a].name;
if (isVPNactive(name)) name += " *";
vpnList += name + "|";
}
jbusClient.call(pack, "setVPNList", quote(vpnList));
}
public void connectVPN(String pack, String name) {
for(int a=0;a<vpnConfig.vpn.length;a++) {
if (vpnConfig.vpn[a].name.equals(name)) {
if (isVPNactive(name)) {
disconnectVPN(name);
} else {
VPN vpn = vpnConfig.vpn[a];
VPNConnection conn = new VPNConnection();
conn.name = name;
conn.id = "" + Math.abs(new Random().nextInt());
conn.pack = pack;
conn.host = vpn.host;
conn.user = vpn.user;
conn.pass = vpn.pass;
conn.domain = vpn.domain;
conn.caps = vpn.caps;
conn.capsOpts = vpn.capsOpts;
conn.routes = vpn.routes;
conn.routeOpts = vpn.routeOpts;
conn.domainsearch = vpn.domainsearch;
vpnConnections.add(conn);
conn.start();
}
break;
}
}
}
public void cancelVPN() {
if (pendingVPN == null) return;
pendingVPN.close();
pendingVPN = null;
}
public void closeAllVPN() {
while (vpnConnections.size() > 0) {
disconnectVPN(vpnConnections.get(0).name);
}
}
}
}