@Override public void onCreate() { super.onCreate(); singleton = this; wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); connManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); try { mStartForeground = getClass().getMethod("startForeground", new Class[] {int.class, Notification.class}); } catch (NoSuchMethodException e) { mStartForeground = null; } state = STATE_STOPPED; filteringEnabled = false; app = (BarnacleApp) getApplication(); app.serviceStarted(this); PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "BarnacleService"); wakeLock.acquire(); IntentFilter filter = new IntentFilter(); filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); registerReceiver(connectivityReceiver, filter); }
@Override public void onDestroy() { if (state != STATE_STOPPED) Log.e(TAG, "service destroyed while running!"); // ensure we clean up stopProcess(); state = STATE_STOPPED; app.processStopped(); wakeLock.release(); try { unregisterReceiver(connectivityReceiver); } catch (Exception e) { // ignore } singleton = null; super.onDestroy(); }
private void stopProcess() { if (process != null) { // first, just close the stream if (state != STATE_STOPPED) { try { process.getOutputStream().close(); } catch (Exception e) { Log.w(TAG, "Exception while closing process"); } } try { process.waitFor(); // blocking! } catch (InterruptedException e) { Log.e(TAG, ""); } try { int exit_status = process.exitValue(); Log.i(TAG, "Process exited with status: " + exit_status); } catch (IllegalThreadStateException e) { // this is not good log(true, getString(R.string.dirtystop)); } process.destroy(); process = null; threads[0].interrupt(); threads[1].interrupt(); nat_ctrl = null; } try { Process kill; ProcessBuilder pbKill = new ProcessBuilder(); pbKill.command("./shutdown_olsr").directory(getFilesDir()); // TODO: consider putting brncl.ini in pb.environment() instead of using ./setup kill = pbKill.start(); // Runtime.getRuntime().exec(cmd); } catch (Exception e) { log(true, String.format(getString(R.string.execerr), "Olsrd Kill")); Log.v(TAG, "Failed to kill OLSRD", e.fillInStackTrace()); } app.buttonOff(); }
private void clientAdded(ClientData cd) { boolean firstConnect = true; for (int i = 0; i < clients.size(); ++i) { ClientData c = clients.get(i); if (c.mac.equals(cd.mac)) { if (c.ip.equals(cd.ip)) { log(false, String.format(getString(R.string.renewed), cd.toNiceString())); return; // no change } cd.allowed = c.allowed; clients.remove(i); // we'll add it at the end firstConnect = false; break; } } clients.add(cd); if (nat_ctrl == null) connectToNat(); // re-attempt to connect log(false, String.format(getString(R.string.connected), cd.toNiceString())); app.clientAdded(cd); }
private void handle(Message msg) { Log.e(TAG, "Message= " + Integer.toString(msg.what)); switch (msg.what) { case MSG_EXCEPTION: if (state == STATE_STOPPED) return; Throwable thr = (Throwable) msg.obj; log(true, getString(R.string.exception) + " " + thr.getMessage()); Log.e(TAG, "Exception " + thr.getMessage() + " " + Log.getStackTraceString(thr)); stopProcess(); state = STATE_STOPPED; break; case MSG_ERROR: if (state == STATE_STOPPED) return; if (process == null) return; // don't kill it again... if (msg.obj != null) { String line = (String) msg.obj; log(true, line); // just dump it and ignore it if (line.startsWith("dnsmasq: DHCPACK")) { String[] vals = line.split(" +"); if (vals.length > 3) { ClientData cd = new ClientData(vals[3], vals[2], vals.length > 4 ? vals[4] : null); clientAdded(cd); } } } else { // no message, means process died log(true, getString(R.string.unexpected)); stopProcess(); if ((state == STATE_STARTING)) { String err = log.toString(); if (isRootError(err)) { app.failed(BarnacleApp.ERROR_ROOT); } else if (isSupplicantError(err)) { app.failed(BarnacleApp.ERROR_SUPPLICANT); } else { app.failed(BarnacleApp.ERROR_OTHER); } } else { app.failed(BarnacleApp.ERROR_OTHER); } state = STATE_STOPPED; } break; case MSG_OUTPUT: if (state == STATE_STOPPED) return; if (process == null) return; // cut the gibberish String line = (String) msg.obj; if (line == null) { // ignore it, wait for MSG_ERROR(null) break; } if (line.startsWith("DHCP: ACK")) { // DHCP: ACK <MAC> <IP> [<HOSTNAME>] String[] vals = line.split(" +"); ClientData cd = new ClientData(vals[2], vals[3], vals.length > 4 ? vals[4] : null); clientAdded(cd); } else if (line.startsWith("WIFI: OK")) { // WIFI: OK <IFNAME> <MAC> String[] parts = line.split(" +"); if_lan = parts[2]; if_mac = Util.MACAddress.parse(parts[3]); if (state == STATE_STARTING) { connectToNat(); state = STATE_RUNNING; log(false, getString(R.string.running)); clients.clear(); stats.init(Util.fetchTrafficData(if_lan)); // app.foundIfLan(if_lan); // this will allow 3G <-> 4G with simple restart app.processStarted(); mHandler.sendEmptyMessage(MSG_ASSOC); } } else { log(false, line); } break; case MSG_START: if (state != STATE_STOPPED) return; log.clear(); log(false, getString(R.string.starting)); if (!app.prepareBinaries()) { log(true, getString(R.string.unpackerr)); state = STATE_STOPPED; break; } state = STATE_STARTING; // FALL THROUGH! case MSG_NETSCHANGE: int wifiState = wifiManager.getWifiState(); Log.e( TAG, String.format( "NETSCHANGE: %d %d %s", wifiState, state, process == null ? "null" : "proc")); if (wifiState == WifiManager.WIFI_STATE_DISABLED) { Log.v(TAG, "Wifi State Disabled"); // wifi is good (or lost), we can start now... if (app.prefs.getBoolean("wan_start", false) && checkUplink() == false) { // Insert to fix checkupLink Toast.makeText( getApplicationContext(), "Umts interfaced is not connected!", Toast.LENGTH_LONG) .show(); log(true, "HSPA interface is disabled. Stopping...."); state = STATE_STOPPED; break; } else if ((state == STATE_STARTING) && (process == null) && checkUplink()) { log(false, getString(R.string.dataready)); if (app.prefs.getBoolean("wan_start", false) && !app.findIfWan()) { // se la wan è down non vado in findIfWan log(true, getString(R.string.wanerr)); state = STATE_STOPPED; break; } if (!app.prepareIni()) { log(true, getString(R.string.inierr)); state = STATE_STOPPED; break; } log(false, getString(R.string.iniok)); if (!startProcess()) { Log.e(TAG, "startProcess()=False"); log(true, getString(R.string.starterr)); state = STATE_STOPPED; break; } } // if not checkUpLink then we simply wait... } else { Log.v(TAG, "Wifi State is not Disabled"); if (state == STATE_RUNNING) { // this is super bad, will have to restart! app.updateToast(getString(R.string.conflictwifi), true); log(true, getString(R.string.conflictwifi)); log(false, getString(R.string.restarting)); stopProcess(); // this tears down wifi wifiManager.setWifiEnabled(false); // this will send MSG_NETSCHANGE // we should wait until wifi is disabled... state = STATE_STARTING; } else if (state == STATE_STARTING) { if ((wifiState == WifiManager.WIFI_STATE_ENABLED) || (wifiState == WifiManager.WIFI_STATE_ENABLING)) { app.updateToast(getString(R.string.disablewifi), false); wifiManager.setWifiEnabled(false); log(false, getString(R.string.waitwifi)); } } } break; case MSG_STOP: if ((state == STATE_STOPPED) && (process == null)) return; stopProcess(); log(false, getString(R.string.stopped)); state = STATE_STOPPED; break; case MSG_ASSOC: if (state != STATE_RUNNING) return; if (tellProcess("WLAN")) { app.updateToast(getString(R.string.beaconing), true); } if (clients.isEmpty() && app.prefs.getBoolean("lan_autoassoc", false)) { mHandler.removeMessages(MSG_ASSOC); // rebeacon, in 5 seconds mHandler.sendEmptyMessageDelayed(MSG_ASSOC, 5000); } break; case MSG_FILTER: if (state != STATE_RUNNING) return; if (tellNat((String) msg.obj)) { app.updateToast(getString(R.string.filterupdated), false); } break; case MSG_STATS: mHandler.removeMessages(MSG_STATS); if (state != STATE_RUNNING || if_lan.length() == 0) return; stats.update(Util.fetchTrafficData(if_lan)); break; } app.updateStatus(); if (state == STATE_STOPPED) app.processStopped(); }