summaryrefslogtreecommitdiff
path: root/src/de/blinkt/openvpn
diff options
context:
space:
mode:
Diffstat (limited to 'src/de/blinkt/openvpn')
-rw-r--r--src/de/blinkt/openvpn/LogWindow.java39
-rw-r--r--src/de/blinkt/openvpn/NetworkSateReceiver.java16
-rw-r--r--src/de/blinkt/openvpn/OpenVPN.java9
-rw-r--r--src/de/blinkt/openvpn/OpenVPNThreadv3.java106
-rw-r--r--src/de/blinkt/openvpn/OpenVpnManagementThread.java39
-rw-r--r--src/de/blinkt/openvpn/OpenVpnService.java86
6 files changed, 202 insertions, 93 deletions
diff --git a/src/de/blinkt/openvpn/LogWindow.java b/src/de/blinkt/openvpn/LogWindow.java
index 88615e12..69d1f859 100644
--- a/src/de/blinkt/openvpn/LogWindow.java
+++ b/src/de/blinkt/openvpn/LogWindow.java
@@ -7,14 +7,17 @@ import android.app.AlertDialog.Builder;
import android.app.ListActivity;
import android.content.ClipData;
import android.content.ClipboardManager;
+import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
+import android.content.ServiceConnection;
import android.database.DataSetObserver;
import android.os.Bundle;
import android.os.Handler;
import android.os.Handler.Callback;
+import android.os.IBinder;
import android.os.Message;
import android.view.Menu;
import android.view.MenuInflater;
@@ -30,10 +33,31 @@ import android.widget.Toast;
import de.blinkt.openvpn.OpenVPN.LogItem;
import de.blinkt.openvpn.OpenVPN.LogListener;
import de.blinkt.openvpn.OpenVPN.StateListener;
+import de.blinkt.openvpn.OpenVpnService.LocalBinder;
public class LogWindow extends ListActivity implements StateListener {
private static final int START_VPN_CONFIG = 0;
private String[] mBconfig=null;
+ protected OpenVpnService mService;
+ private ServiceConnection mConnection = new ServiceConnection() {
+
+
+
+ @Override
+ public void onServiceConnected(ComponentName className,
+ IBinder service) {
+ // We've bound to LocalService, cast the IBinder and get LocalService instance
+ LocalBinder binder = (LocalBinder) service;
+ mService = binder.getService();
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName arg0) {
+ mService =null;
+ }
+
+ };
+
class LogWindowListAdapter implements ListAdapter, LogListener, Callback {
@@ -198,6 +222,7 @@ public class LogWindow extends ListActivity implements StateListener {
private LogWindowListAdapter ladapter;
private TextView mSpeedView;
+
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(item.getItemId()==R.id.clearlog) {
@@ -213,7 +238,8 @@ public class LogWindow extends ListActivity implements StateListener {
@Override
public void onClick(DialogInterface dialog, int which) {
ProfileManager.setConntectedVpnProfileDisconnected(getApplicationContext());
- OpenVpnManagementThread.stopOpenVPN();
+ if(mService.getManagement()!=null)
+ mService.getManagement().stopVPN();
}
});
@@ -324,6 +350,12 @@ public class LogWindow extends ListActivity implements StateListener {
lv.setAdapter(ladapter);
mSpeedView = (TextView) findViewById(R.id.speed);
+
+ Intent intent = new Intent(getBaseContext(), OpenVpnService.class);
+ intent.setAction(OpenVpnService.START_SERVICE);
+
+ bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+
}
@Override
@@ -335,6 +367,8 @@ public class LogWindow extends ListActivity implements StateListener {
String prefix=getString(resid) + ":";
if (status.equals("BYTECOUNT") || status.equals("NOPROCESS") )
prefix="";
+ if (resid==R.string.unknown_state)
+ prefix+=status;
mSpeedView.setText(prefix + logmessage);
}
});
@@ -343,8 +377,9 @@ public class LogWindow extends ListActivity implements StateListener {
@Override
protected void onDestroy() {
- super.onDestroy();
+ unbindService(mConnection);
OpenVPN.removeLogListener(ladapter);
+ super.onDestroy();
}
}
diff --git a/src/de/blinkt/openvpn/NetworkSateReceiver.java b/src/de/blinkt/openvpn/NetworkSateReceiver.java
index e20c8e52..487639a9 100644
--- a/src/de/blinkt/openvpn/NetworkSateReceiver.java
+++ b/src/de/blinkt/openvpn/NetworkSateReceiver.java
@@ -11,13 +11,13 @@ import android.preference.PreferenceManager;
public class NetworkSateReceiver extends BroadcastReceiver {
private int lastNetwork=-1;
- private OpenVpnManagementThread mManangement;
+ private OpenVPNMangement mManangement;
private String lastStateMsg=null;
- public NetworkSateReceiver(OpenVpnManagementThread managementThread) {
+ public NetworkSateReceiver(OpenVPNMangement magnagement) {
super();
- mManangement = managementThread;
+ mManangement = magnagement;
}
@Override
@@ -57,15 +57,19 @@ public class NetworkSateReceiver extends BroadcastReceiver {
if(networkInfo!=null && networkInfo.getState() == State.CONNECTED) {
int newnet = networkInfo.getType();
- if(sendusr1 && lastNetwork!=newnet)
- mManangement.reconnect();
+ if(sendusr1 && lastNetwork!=newnet) {
+ if (lastNetwork==-1)
+ mManangement.resume();
+ else
+ mManangement.reconnect();
+ }
lastNetwork = newnet;
} else if (networkInfo==null) {
// Not connected, stop openvpn, set last connected network to no network
lastNetwork=-1;
if(sendusr1)
- mManangement.signalusr1();
+ mManangement.pause();
}
if(!netstatestring.equals(lastStateMsg))
diff --git a/src/de/blinkt/openvpn/OpenVPN.java b/src/de/blinkt/openvpn/OpenVPN.java
index c1616f2d..2ca2d259 100644
--- a/src/de/blinkt/openvpn/OpenVPN.java
+++ b/src/de/blinkt/openvpn/OpenVPN.java
@@ -173,6 +173,8 @@ public class OpenVPN {
return R.string.state_add_routes;
else if (state.equals("CONNECTED"))
return R.string.state_connected;
+ else if (state.equals("DISCONNECTED"))
+ return R.string.state_disconnected;
else if (state.equals("RECONNECTING"))
return R.string.state_reconnecting;
else if (state.equals("EXITING"))
@@ -257,7 +259,12 @@ public class OpenVPN {
newlogItem(new LogItem(LogItem.ERROR, ressourceId,args));
}
- public static void updateByteCount(long in, long out, long diffin, long diffout) {
+ public static void updateByteCount(long in, long out) {
+ long lastIn = mlastByteCount[0];
+ long lastOut = mlastByteCount[1];
+ long diffin = in - lastIn;
+ long diffout = out - lastOut;
+
mlastByteCount = new long[] {in,out,diffin,diffout};
for(ByteCountListener bcl:byteCountListener){
bcl.updateByteCount(in, out, diffin,diffout);
diff --git a/src/de/blinkt/openvpn/OpenVPNThreadv3.java b/src/de/blinkt/openvpn/OpenVPNThreadv3.java
index 36fcc985..39c7640f 100644
--- a/src/de/blinkt/openvpn/OpenVPNThreadv3.java
+++ b/src/de/blinkt/openvpn/OpenVPNThreadv3.java
@@ -9,8 +9,9 @@ import net.openvpn.ovpn3.ClientAPI_LogInfo;
import net.openvpn.ovpn3.ClientAPI_OpenVPNClient;
import net.openvpn.ovpn3.ClientAPI_ProvideCreds;
import net.openvpn.ovpn3.ClientAPI_Status;
+import net.openvpn.ovpn3.ClientAPI_TransportStats;
-public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable {
+public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable, OpenVPNMangement {
static {
System.loadLibrary("crypto");
@@ -21,6 +22,34 @@ public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable
private VpnProfile mVp;
private OpenVpnService mService;
+ class StatusPoller implements Runnable
+ {
+ private long mSleeptime;
+
+ boolean mStopped=false;
+
+ public StatusPoller(long sleeptime) {
+ mSleeptime=sleeptime;
+ }
+
+ public void run() {
+ while(!mStopped) {
+ try {
+ Thread.sleep(mSleeptime);
+ } catch (InterruptedException e) {
+ }
+ ClientAPI_TransportStats t = transport_stats();
+ long in = t.getBytesIn();
+ long out = t.getBytesOut();
+ OpenVPN.updateByteCount(in, out);
+ }
+ }
+
+ public void stop() {
+ mStopped=true;
+ }
+ }
+
@Override
public void run() {
String configstr = mVp.getConfigFile(mService,true);
@@ -28,20 +57,25 @@ public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable
return;
setUserPW();
OpenVPN.logInfo(copyright());
+
+ StatusPoller statuspoller = new StatusPoller(5000);
+ new Thread(statuspoller,"Status Poller").start();
+
ClientAPI_Status status = connect();
if(status.getError()) {
OpenVPN.logError(String.format("connect() error: %s: %s",status.getStatus(),status.getMessage()));
} else {
- OpenVPN.logInfo(String.format("connect() error: %s: %s",status.getStatus(),status.getMessage()));
+ OpenVPN.logInfo("OpenVPN3 thread finished");
}
+ statuspoller.stop();
}
-
+
@Override
public boolean tun_builder_set_remote_address(String address, boolean ipv6) {
mService.setMtu(1500);
return true;
}
-
+
@Override
public boolean tun_builder_set_mtu(int mtu) {
mService.setMtu(mtu);
@@ -52,36 +86,39 @@ public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable
mService.addDNS(address);
return true;
}
-
+
@Override
public boolean tun_builder_add_route(String address, int prefix_length,
boolean ipv6) {
+ if (address.equals("remote_host"))
+ return false;
+
if(ipv6)
mService.addRoutev6(address + "/" + prefix_length);
else
mService.addRoute(new CIDRIP(address, prefix_length));
return true;
}
-
+
@Override
public boolean tun_builder_add_search_domain(String domain) {
mService.setDomain(domain);
return true;
}
-
+
@Override
public int tun_builder_establish() {
return mService.openTun().detachFd();
}
-
+
@Override
public boolean tun_builder_set_session_name(String name) {
OpenVPN.logInfo("We should call this session" + name);
return true;
}
-
-
+
+
@Override
public boolean tun_builder_add_address(String address, int prefix_length,
boolean ipv6) {
@@ -91,20 +128,20 @@ public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable
mService.setLocalIPv6(address+ "/" + prefix_length);
return true;
}
-
+
@Override
public boolean tun_builder_new() {
-
+
return true;
}
-
+
@Override
public boolean tun_builder_reroute_gw(String server_address,
boolean server_address_ipv6, boolean ipv4, boolean ipv6, long flags) {
// ignore
return true;
}
-
+
@Override
public boolean tun_builder_exclude_route(String address, int prefix_length,
boolean ipv6) {
@@ -114,15 +151,15 @@ public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable
private boolean setConfig(String vpnconfig) {
-
+
ClientAPI_Config config = new ClientAPI_Config();
if(mVp.getPasswordPrivateKey()!=null)
config.setPrivateKeyPassword(mVp.getPasswordPrivateKey());
-
+
config.setContent(vpnconfig);
config.setTunPersist(mVp.mPersistTun);
config.setExternalPkiAlias("extpki");
-
+
ClientAPI_EvalConfig ec = eval_config(config);
if(ec.getExternalPki()) {
OpenVPN.logError("OpenVPN seem to think as external PKI");
@@ -135,7 +172,7 @@ public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable
return true;
}
}
-
+
@Override
public void external_pki_cert_request(ClientAPI_ExternalPKICertRequest certreq) {
OpenVPN.logError("EXT PKI CERT");
@@ -145,15 +182,14 @@ public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable
certreq.setErrorText("Error in pki cert request");
return;
}
-
+
certreq.setSupportingChain(ks[0]);
certreq.setCert(ks[1]);
certreq.setError(false);
}
-
+
@Override
public void external_pki_sign_request(ClientAPI_ExternalPKISignRequest signreq) {
- OpenVPN.logError("EXT PKI Sign");
signreq.setSig(mVp.getSignedData(signreq.getData()));
}
@@ -170,9 +206,8 @@ public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable
@Override
public boolean socket_protect(int socket) {
boolean b= mService.protect(socket);
- OpenVPN.logInfo("protect from v3: " + b);
- return true;
-
+ return b;
+
}
public OpenVPNThreadv3(OpenVpnService openVpnService, VpnProfile vp) {
@@ -186,7 +221,7 @@ public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable
String logmsg =arg0.getText();
while (logmsg.endsWith("\n"))
logmsg = logmsg.substring(0, logmsg.length()-1);
-
+
OpenVPN.logInfo(logmsg);
}
@@ -197,9 +232,26 @@ public class OpenVPNThreadv3 extends ClientAPI_OpenVPNClient implements Runnable
OpenVPN.logError(String.format("EVENT(Error): %s: %s",event.getName(),event.getInfo()));
}
- public void stopVPN() {
+
+ // When a connection is close to timeout, the core will call this
+ // method. If it returns false, the core will disconnect with a
+ // CONNECTION_TIMEOUT event. If true, the core will enter a PAUSE
+ // state.
+
+ @Override
+ public boolean pause_on_connection_timeout() {
+ OpenVPN.logInfo("pause on connection timeout?! ");
+ return true;
+ }
+
+ public boolean stopVPN() {
stop();
-
+ return true;
+ }
+
+ @Override
+ public void reconnect() {
+ reconnect(1);
}
}
diff --git a/src/de/blinkt/openvpn/OpenVpnManagementThread.java b/src/de/blinkt/openvpn/OpenVpnManagementThread.java
index 538079e8..e4528132 100644
--- a/src/de/blinkt/openvpn/OpenVpnManagementThread.java
+++ b/src/de/blinkt/openvpn/OpenVpnManagementThread.java
@@ -7,28 +7,18 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
import java.util.LinkedList;
import java.util.Locale;
import java.util.Vector;
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-
import android.content.SharedPreferences;
import android.net.LocalServerSocket;
import android.net.LocalSocket;
-import android.os.Build;
import android.os.ParcelFileDescriptor;
import android.preference.PreferenceManager;
-import android.util.Base64;
import android.util.Log;
-public class OpenVpnManagementThread implements Runnable {
+public class OpenVpnManagementThread implements Runnable, OpenVPNMangement {
private static final String TAG = "openvpn";
private LocalSocket mSocket;
@@ -36,8 +26,6 @@ public class OpenVpnManagementThread implements Runnable {
private OpenVpnService mOpenVPNService;
private LinkedList<FileDescriptor> mFDList=new LinkedList<FileDescriptor>();
private int mBytecountinterval=2;
- private long mLastIn=0;
- private long mLastOut=0;
private LocalServerSocket mServerSocket;
private boolean mReleaseHold=true;
private boolean mWaitingForRelease=false;
@@ -284,13 +272,7 @@ public class OpenVpnManagementThread implements Runnable {
long in = Long.parseLong(argument.substring(0, comma));
long out = Long.parseLong(argument.substring(comma+1));
- long diffin = in - mLastIn;
- long diffout = out - mLastOut;
-
- mLastIn=in;
- mLastOut=out;
-
- OpenVPN.updateByteCount(in,out,diffin, diffout);
+ OpenVPN.updateByteCount(in,out);
}
@@ -448,7 +430,7 @@ public class OpenVpnManagementThread implements Runnable {
}
- public static boolean stopOpenVPN() {
+ private static boolean stopOpenVPN() {
boolean sendCMD=false;
for (OpenVpnManagementThread mt: active){
mt.managmentCommand("signal SIGINT\n");
@@ -481,4 +463,19 @@ public class OpenVpnManagementThread implements Runnable {
managmentCommand(signed_string);
managmentCommand("\nEND\n");
}
+
+ @Override
+ public void pause() {
+ signalusr1();
+ }
+
+ @Override
+ public void resume() {
+ releaseHold();
+ }
+
+ @Override
+ public boolean stopVPN() {
+ return stopOpenVPN();
+ }
}
diff --git a/src/de/blinkt/openvpn/OpenVpnService.java b/src/de/blinkt/openvpn/OpenVpnService.java
index 675e44b9..d5d75589 100644
--- a/src/de/blinkt/openvpn/OpenVpnService.java
+++ b/src/de/blinkt/openvpn/OpenVpnService.java
@@ -62,9 +62,6 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
private CIDRIP mLocalIP=null;
- private OpenVpnManagementThread mManagementThread;
-
- private Thread mSocketManagerThread;
private int mMtu;
private String mLocalIPv6=null;
private NetworkSateReceiver mNetworkStateReceiver;
@@ -90,6 +87,8 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
private final IBinder mBinder = new LocalBinder();
private boolean mOvpn3;
private OpenVPNThreadv3 mOpenVPN3;
+ private Thread mSocketManagerThread;
+ private OpenVPNMangement mManagement;
public class LocalBinder extends Binder {
public OpenVpnService getService() {
@@ -109,10 +108,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
@Override
public void onRevoke() {
- if(!mOvpn3)
- OpenVpnManagementThread.stopOpenVPN();
- else
- mOpenVPN3.stopVPN();
+ mManagement.stopVPN();
endVpnService();
}
@@ -126,6 +122,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
OpenVPN.logBuilderConfig(null);
OpenVPN.removeStateListener(this);
OpenVPN.removeByteCountListener(this);
+ unregisterNetworkStateReceiver();
ProfileManager.setConntectedVpnProfileDisconnected(this);
if(!mStarting) {
stopForeground(!mNotificationalwaysVisible);
@@ -180,9 +177,9 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
// PRIORITY_MIN == -2
setpriority.invoke(nbuilder, -2 );
- Method setUsesChronometer = nbuilder.getClass().getMethod("setPriority", boolean.class);
+ Method setUsesChronometer = nbuilder.getClass().getMethod("setUsesChronometer", boolean.class);
setUsesChronometer.invoke(nbuilder,true);
-
+
/* PendingIntent cancelconnet=null;
nbuilder.addAction(android.R.drawable.ic_menu_close_clear_cancel,
@@ -240,14 +237,20 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
}
- void registerNetworkStateReceiver() {
+ void registerNetworkStateReceiver(OpenVPNMangement magnagement) {
// Registers BroadcastReceiver to track network connection changes.
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
- mNetworkStateReceiver = new NetworkSateReceiver(mManagementThread);
+ mNetworkStateReceiver = new NetworkSateReceiver(magnagement);
this.registerReceiver(mNetworkStateReceiver, filter);
}
-
+ void unregisterNetworkStateReceiver() {
+ if(mNetworkStateReceiver!=null)
+ this.unregisterReceiver(mNetworkStateReceiver);
+ mNetworkStateReceiver=null;
+ }
+
+
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
@@ -274,19 +277,27 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
showNotification("Starting VPN " + mProfile.mName,"Starting VPN " + mProfile.mName, false,0,LEVEL_NOTCONNECTED);
-
-
// Set a flag that we are starting a new VPN
mStarting=true;
// Stop the previous session by interrupting the thread.
- if(OpenVpnManagementThread.stopOpenVPN()){
- // an old was asked to exit, wait 2s
+ if(mManagement!=null && mManagement.stopVPN())
+ // an old was asked to exit, wait 1s
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+
+
+ if(mOpenVPN3!=null) {
+ mOpenVPN3.stopVPN();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
+
}
+
if (mProcessThread!=null) {
mProcessThread.interrupt();
try {
@@ -299,18 +310,19 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
// Open the Management Interface
- LocalServerSocket mgmtsocket = openManagmentInterface(8);
-
- if(mgmtsocket!=null) {
- // start a Thread that handles incoming messages of the managment socket
- mManagementThread=new OpenVpnManagementThread(mProfile,mgmtsocket,this);
- mSocketManagerThread = new Thread(mManagementThread,"OpenVPNMgmtThread");
- mSocketManagerThread.start();
- OpenVPN.logInfo("started Socket Thread");
- registerNetworkStateReceiver();
+ if(!mOvpn3) {
+ LocalServerSocket mgmtsocket = openManagmentInterface(8);
+
+ if(mgmtsocket!=null) {
+ // start a Thread that handles incoming messages of the managment socket
+ OpenVpnManagementThread ovpnmgmthread = new OpenVpnManagementThread(mProfile,mgmtsocket,this);
+ mSocketManagerThread = new Thread(ovpnmgmthread,"OpenVPNMgmtThread");
+ mSocketManagerThread.start();
+ mManagement= ovpnmgmthread;
+ OpenVPN.logInfo("started Socket Thread");
+ }
}
-
// Start a new session by creating a new thread.
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
@@ -318,19 +330,21 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
Runnable processThread;
if(mOvpn3) {
-
mOpenVPN3 = new OpenVPNThreadv3(this,mProfile);
-
processThread = mOpenVPN3;
+ mManagement = mOpenVPN3;
+
} else {
-
processThread = new OpenVPNThread(this, argv,nativelibdir);
-
}
+
mProcessThread = new Thread(processThread, "OpenVPNProcessThread");
mProcessThread.start();
+ registerNetworkStateReceiver(mManagement);
+
+
ProfileManager.setConnectedVpnProfile(this, mProfile);
return START_NOT_STICKY;
@@ -339,7 +353,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
@Override
public void onDestroy() {
if (mProcessThread != null) {
- mManagementThread.managmentCommand("signal SIGINT\n");
+ mManagement.stopVPN();
mProcessThread.interrupt();
}
@@ -500,13 +514,13 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
public void setMtu(int mtu) {
mMtu=mtu;
}
-
+
public void setLocalIP(CIDRIP cdrip)
{
mLocalIP=cdrip;
}
-
-
+
+
public void setLocalIP(String local, String netmask,int mtu, String mode) {
mLocalIP = new CIDRIP(local, netmask);
mMtu = mtu;
@@ -597,7 +611,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac
}
}
- public OpenVpnManagementThread getManagementThread() {
- return mManagementThread;
+ public OpenVPNMangement getManagement() {
+ return mManagement;
}
}