diff --git a/res/values/strings.xml b/res/values/strings.xml
index 608f0ee..68ea69f 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -46,5 +46,6 @@ making a donation if you like this program.
Debug level
Execute as Super User
Auto start on boot
+ Force reconnection on network change
\ No newline at end of file
diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml
index 43cfc4e..a7fa657 100644
--- a/res/xml/preferences.xml
+++ b/res/xml/preferences.xml
@@ -16,6 +16,7 @@
+
diff --git a/src/org/poirsouille/tinc_gui/BootReceiver.java b/src/org/poirsouille/tinc_gui/BootReceiver.java
index 4681b93..db4d459 100644
--- a/src/org/poirsouille/tinc_gui/BootReceiver.java
+++ b/src/org/poirsouille/tinc_gui/BootReceiver.java
@@ -17,7 +17,7 @@ public void onReceive(Context iContext, Intent iIntent)
// Auto start service if enabled
Log.d(Tools.TAG, "Boot notif");
SharedPreferences aSharedPref = iContext.getSharedPreferences("org.poirsouille.tinc_gui_preferences", Context.MODE_PRIVATE);
- Boolean aAutoStart = false;
+ boolean aAutoStart = false;
aAutoStart = aSharedPref.getBoolean("pref_key_autostart_boot", aAutoStart);
if (aAutoStart)
{
diff --git a/src/org/poirsouille/tinc_gui/TincdService.java b/src/org/poirsouille/tinc_gui/TincdService.java
index baa1422..897e40c 100644
--- a/src/org/poirsouille/tinc_gui/TincdService.java
+++ b/src/org/poirsouille/tinc_gui/TincdService.java
@@ -35,11 +35,15 @@
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
+import android.content.Context;
import android.content.Intent;
+import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
import android.os.Binder;
import android.os.IBinder;
import android.preference.PreferenceManager;
@@ -61,6 +65,8 @@ public class TincdService extends Service implements ICallback
SharedPreferences _sharedPref;
public int _maxLogSize = 1000;
private OnSharedPreferenceChangeListener _prefChangeListener;
+ private final ConnectivityroadcastReceiver _broadcastReceiver = new ConnectivityroadcastReceiver();
+ private boolean _reconnectOnNetChange = false;
public ICallback _callback = null;
@@ -81,6 +87,63 @@ TincdService getService()
}
}
+ /**
+ * Network state events receiver.
+ */
+ public class ConnectivityroadcastReceiver extends BroadcastReceiver
+ {
+ /// Ensure we don't try to un-register several times
+ private boolean _receiverRegistered = false;
+
+ /**
+ * Listen for network change events, and force tincd reconnection as soon as connectivity is back.
+ */
+ @Override
+ public void onReceive(Context context, Intent intent)
+ {
+ String aAction = intent.getAction();
+ if(aAction.equals(ConnectivityManager.CONNECTIVITY_ACTION))
+ {
+ // Check if we have connectivity
+ boolean aConnectivity = ! intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
+ Log.d(Tools.TAG, "Network state changed - network available? " + aConnectivity);
+ if (aConnectivity)
+ {
+ Log.i(Tools.TAG, "Network state changed - forcing reconnection");
+ // Send SIGALRM to tincd to force immediate reconnection to other nodes
+ signal("SIGALRM");
+ }
+ }
+ }
+
+ /**
+ * Register a broadcast receiver to get notified on network state change.
+ */
+ public void register()
+ {
+ // Only register if force reconnect is enabled and tincd is started
+ if (_reconnectOnNetChange && _started)
+ {
+ IntentFilter aFilter = new IntentFilter();
+ aFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+ registerReceiver(_broadcastReceiver, aFilter);
+ _receiverRegistered = true;
+ }
+ }
+
+ /**
+ * Unregister broadcast receiver.
+ */
+ public void unregister()
+ {
+ if (_receiverRegistered)
+ {
+ unregisterReceiver(_broadcastReceiver);
+ _receiverRegistered = false;
+ }
+ }
+ };
+
/**
* Execute given command, with either su or sh as shell.
* @param command
@@ -95,6 +158,7 @@ public List run(String command, ICallback ioCallBack)
return Tools.Run(aShell, new String[] {command}, ioCallBack);
}
+
public void startTinc()
{
if (! _started)
@@ -122,10 +186,13 @@ public void run()
_started = true;
_debug = false;
+ // Register a broadcast receiver to get notified on network state change
+ _broadcastReceiver.register();
// Use exec to replace shell with executable. umask is used to ensure pidfile will be world readable.
TincdService.this.run("umask 022; exec " + getFileStreamPath(TINCBIN) + " -D -d" + _debugLvl + " -c " + _configPath + " --pidfile=" + getFileStreamPath(PIDFILE), TincdService.this);
// Process returns only when ended
_started = false;
+ _broadcastReceiver.unregister();
Log.d(Tools.TAG, "End of tincd thread");
TincdService.this.stopTincd();
}
@@ -301,6 +368,9 @@ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Strin
_sharedPref.registerOnSharedPreferenceChangeListener(_prefChangeListener);
// Refresh at startup as well
refreshPrefs("");
+
+ // Re-register if needed
+ _broadcastReceiver.register();
}
/**
@@ -313,11 +383,12 @@ private void refreshPrefs(String iKey)
_maxLogSize = Integer.parseInt(_sharedPref.getString("pref_key_max_log_size", "" + _maxLogSize));
_debugLvl = Integer.parseInt(_sharedPref.getString("pref_key_debug_level", "" + _debugLvl));
_useSU = _sharedPref.getBoolean("pref_key_super_user", _useSU);
+ _reconnectOnNetChange = _sharedPref.getBoolean("pref_key_force_reconnect", _reconnectOnNetChange);
if (iKey.equals("pref_key_autostart_boot"))
{
// Enable/disable boot time notification
- Boolean aAutoStart = false;
+ boolean aAutoStart = false;
aAutoStart = _sharedPref.getBoolean("pref_key_autostart_boot", aAutoStart);
this.getPackageManager().setComponentEnabledSetting(new ComponentName(this, BootReceiver.class),
aAutoStart ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
@@ -329,6 +400,7 @@ private void refreshPrefs(String iKey)
public void onDestroy ()
{
stopTincd();
+ _broadcastReceiver.unregister();
Log.d(Tools.TAG, "Service destroyed");
}
@@ -421,4 +493,5 @@ void checkAndStopSelf()
stopSelf();
}
}
+
}