OpenVPN bandwidth counter for Android
This commit is contained in:
parent
7345f464a5
commit
d417fa58ab
7 changed files with 108 additions and 14 deletions
|
|
@ -31,6 +31,31 @@ class OpenVPNThreadv3(var service: VPNService): ClientAPI_OpenVPNClient(), Runna
|
||||||
private var mAlreadyInitialised = false
|
private var mAlreadyInitialised = false
|
||||||
private var mService: VPNService = service
|
private var mService: VPNService = service
|
||||||
|
|
||||||
|
private var bytesInIndex = -1
|
||||||
|
private var bytesOutIndex = -1
|
||||||
|
|
||||||
|
init {
|
||||||
|
findConfigIndicies()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findConfigIndicies() {
|
||||||
|
val n: Int = stats_n()
|
||||||
|
|
||||||
|
for (i in 0 until n) {
|
||||||
|
val name: String = stats_name(i)
|
||||||
|
if (name == "BYTES_IN") bytesInIndex = i
|
||||||
|
if (name == "BYTES_OUT") bytesOutIndex = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getTotalRxBytes(): Long {
|
||||||
|
return stats_value(bytesInIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getTotalTxBytes(): Long {
|
||||||
|
return stats_value(bytesOutIndex)
|
||||||
|
}
|
||||||
|
|
||||||
override fun run() {
|
override fun run() {
|
||||||
|
|
||||||
val config: ClientAPI_Config = ClientAPI_Config()
|
val config: ClientAPI_Config = ClientAPI_Config()
|
||||||
|
|
|
||||||
|
|
@ -319,17 +319,52 @@ class VPNService : BaseVpnService(), LocalDnsService.Interface {
|
||||||
mBinder.dispatchEvent(VPNServiceBinder.EVENTS.disconnected, "")
|
mBinder.dispatchEvent(VPNServiceBinder.EVENTS.disconnected, "")
|
||||||
mConnectionTime = 0
|
mConnectionTime = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
val status: JSONObject
|
val status: JSONObject
|
||||||
get() {
|
get() {
|
||||||
val deviceIpv4: String = ""
|
val deviceIpv4: String = ""
|
||||||
|
|
||||||
|
val status = when (mProtocol) {
|
||||||
|
"openvpn" -> {
|
||||||
|
if (mOpenVPNThreadv3 == null) {
|
||||||
|
Status(null, null, null, null)
|
||||||
|
} else {
|
||||||
|
val rx = mOpenVPNThreadv3?.getTotalRxBytes() ?: ""
|
||||||
|
val tx = mOpenVPNThreadv3?.getTotalTxBytes() ?: ""
|
||||||
|
|
||||||
|
Status(
|
||||||
|
rx.toString(),
|
||||||
|
tx.toString(),
|
||||||
|
if (mConfig!!.has("server")) { mConfig?.getJSONObject("server")?.getString("ipv4Gateway") } else {""},
|
||||||
|
if (mConfig!!.has("device")) { mConfig?.getJSONObject("device")?.getString("ipv4Address") } else {""}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
Status(
|
||||||
|
getConfigValue("rx_bytes"),
|
||||||
|
getConfigValue("tx_bytes"),
|
||||||
|
mConfig?.getJSONObject("server")?.getString("ipv4Gateway"),
|
||||||
|
mConfig?.getJSONObject("device")?.getString("ipv4Address")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return JSONObject().apply {
|
return JSONObject().apply {
|
||||||
putOpt("rx_bytes", getConfigValue("rx_bytes"))
|
putOpt("rx_bytes", status.rxBytes)
|
||||||
putOpt("tx_bytes", getConfigValue("tx_bytes"))
|
putOpt("tx_bytes", status.txBytes)
|
||||||
putOpt("endpoint", mConfig?.getJSONObject("server")?.getString("ipv4Gateway"))
|
putOpt("endpoint", status.endpoint)
|
||||||
putOpt("deviceIpv4", mConfig?.getJSONObject("device")?.getString("ipv4Address"))
|
putOpt("deviceIpv4", status.device)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data class Status(
|
||||||
|
var rxBytes: String?,
|
||||||
|
var txBytes: String?,
|
||||||
|
var endpoint: String?,
|
||||||
|
var device: String?
|
||||||
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Checks if the VPN Permission is given.
|
* Checks if the VPN Permission is given.
|
||||||
* If the permission is given, returns true
|
* If the permission is given, returns true
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ constexpr auto PERMISSIONHELPER_CLASS =
|
||||||
AndroidController::AndroidController():
|
AndroidController::AndroidController():
|
||||||
m_binder(this)
|
m_binder(this)
|
||||||
{
|
{
|
||||||
|
connect(this, &AndroidController::scheduleStatusCheckSignal, this, &AndroidController::scheduleStatusCheckSlot);
|
||||||
}
|
}
|
||||||
|
|
||||||
AndroidController* AndroidController::instance() {
|
AndroidController* AndroidController::instance() {
|
||||||
|
|
@ -237,6 +237,14 @@ void AndroidController::setVpnConfig(const QJsonObject &newVpnConfig)
|
||||||
m_vpnConfig = newVpnConfig;
|
m_vpnConfig = newVpnConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AndroidController::scheduleStatusCheckSlot()
|
||||||
|
{
|
||||||
|
QTimer::singleShot(1000, [this]() {
|
||||||
|
if (isConnected) {
|
||||||
|
checkStatus();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief AndroidController::VPNBinder::onTransact
|
* @brief AndroidController::VPNBinder::onTransact
|
||||||
|
|
@ -271,22 +279,30 @@ bool AndroidController::VPNBinder::onTransact(int code,
|
||||||
case EVENT_CONNECTED:
|
case EVENT_CONNECTED:
|
||||||
qDebug() << "Transact: connected";
|
qDebug() << "Transact: connected";
|
||||||
emit m_controller->connectionStateChanged(VpnProtocol::Connected);
|
emit m_controller->connectionStateChanged(VpnProtocol::Connected);
|
||||||
|
m_controller->isConnected = true;
|
||||||
|
emit m_controller->scheduleStatusCheckSignal();
|
||||||
break;
|
break;
|
||||||
case EVENT_DISCONNECTED:
|
case EVENT_DISCONNECTED:
|
||||||
qDebug() << "Transact: disconnected";
|
qDebug() << "Transact: disconnected";
|
||||||
emit m_controller->connectionStateChanged(VpnProtocol::Disconnected);
|
emit m_controller->connectionStateChanged(VpnProtocol::Disconnected);
|
||||||
|
m_controller->isConnected = false;
|
||||||
break;
|
break;
|
||||||
case EVENT_STATISTIC_UPDATE:
|
case EVENT_STATISTIC_UPDATE:
|
||||||
|
{
|
||||||
qDebug() << "Transact:: update";
|
qDebug() << "Transact:: update";
|
||||||
|
|
||||||
// Data is here a JSON String
|
|
||||||
doc = QJsonDocument::fromJson(data.readData());
|
doc = QJsonDocument::fromJson(data.readData());
|
||||||
// TODO update counters
|
|
||||||
// emit m_controller->statusUpdated(doc.object()["endpoint"].toString(),
|
QString rx = doc.object()["rx_bytes"].toString();
|
||||||
// doc.object()["deviceIpv4"].toString(),
|
QString tx = doc.object()["tx_bytes"].toString();
|
||||||
// doc.object()["totalTX"].toInt(),
|
QString endpoint = doc.object()["endpoint"].toString();
|
||||||
// doc.object()["totalRX"].toInt());
|
QString deviceIPv4 = doc.object()["deviceIpv4"].toString();
|
||||||
|
|
||||||
|
emit m_controller->statusUpdated(rx, tx, endpoint, deviceIPv4);
|
||||||
|
emit m_controller->scheduleStatusCheckSignal();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case EVENT_BACKEND_LOGS:
|
case EVENT_BACKEND_LOGS:
|
||||||
qDebug() << "Transact: backend logs";
|
qDebug() << "Transact: backend logs";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,11 @@ signals:
|
||||||
void initialized(bool status, bool connected,
|
void initialized(bool status, bool connected,
|
||||||
const QDateTime& connectionDate);
|
const QDateTime& connectionDate);
|
||||||
|
|
||||||
|
void statusUpdated(QString totalRx, QString totalTx, QString endpoint, QString deviceIPv4);
|
||||||
|
void scheduleStatusCheckSignal();
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
|
void scheduleStatusCheckSlot();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|
@ -84,6 +88,10 @@ private:
|
||||||
|
|
||||||
VPNBinder m_binder;
|
VPNBinder m_binder;
|
||||||
|
|
||||||
|
bool isConnected = false;
|
||||||
|
|
||||||
|
void scheduleStatusCheck();
|
||||||
|
|
||||||
static void startActivityForResult(JNIEnv* env, jobject /*thiz*/, jobject intent);
|
static void startActivityForResult(JNIEnv* env, jobject /*thiz*/, jobject intent);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,7 @@
|
||||||
AndroidVpnProtocol::AndroidVpnProtocol(Proto protocol, const QJsonObject &configuration, QObject* parent)
|
AndroidVpnProtocol::AndroidVpnProtocol(Proto protocol, const QJsonObject &configuration, QObject* parent)
|
||||||
: VpnProtocol(configuration, parent),
|
: VpnProtocol(configuration, parent),
|
||||||
m_protocol(protocol)
|
m_protocol(protocol)
|
||||||
{
|
{ }
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ErrorCode AndroidVpnProtocol::start()
|
ErrorCode AndroidVpnProtocol::start()
|
||||||
{
|
{
|
||||||
|
|
@ -39,3 +37,11 @@ void AndroidVpnProtocol::stop()
|
||||||
AndroidController::instance()->stop();
|
AndroidController::instance()->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AndroidVpnProtocol::connectionDataUpdated(QString totalRx, QString totalTx, QString endpoint, QString deviceIPv4)
|
||||||
|
{
|
||||||
|
quint64 rxBytes = totalRx.toLongLong();
|
||||||
|
quint64 txBytes = totalTx.toLongLong();
|
||||||
|
|
||||||
|
setBytesChanged(rxBytes, txBytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,9 @@ public:
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void connectionDataUpdated(QString totalRx, QString totalTx, QString endpoint, QString deviceIPv4);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
||||||
|
|
@ -362,6 +362,7 @@ void VpnConnection::connectToVpn(int serverIndex,
|
||||||
Proto proto = ContainerProps::defaultProtocol(container);
|
Proto proto = ContainerProps::defaultProtocol(container);
|
||||||
AndroidVpnProtocol *androidVpnProtocol = new AndroidVpnProtocol(proto, m_vpnConfiguration);
|
AndroidVpnProtocol *androidVpnProtocol = new AndroidVpnProtocol(proto, m_vpnConfiguration);
|
||||||
connect(AndroidController::instance(), &AndroidController::connectionStateChanged, androidVpnProtocol, &AndroidVpnProtocol::setConnectionState);
|
connect(AndroidController::instance(), &AndroidController::connectionStateChanged, androidVpnProtocol, &AndroidVpnProtocol::setConnectionState);
|
||||||
|
connect(AndroidController::instance(), &AndroidController::statusUpdated, androidVpnProtocol, &AndroidVpnProtocol::connectionDataUpdated);
|
||||||
|
|
||||||
m_vpnProtocol.reset(androidVpnProtocol);
|
m_vpnProtocol.reset(androidVpnProtocol);
|
||||||
#elif defined Q_OS_IOS
|
#elif defined Q_OS_IOS
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue