lokinet/jni/lokinet_android.cpp

238 lines
5.1 KiB
C++
Raw Normal View History

#include <llarp.h>
2019-07-24 14:17:54 +00:00
#include <config/config.hpp>
#include <util/fs.hpp>
#include <llarp.hpp>
#include <router/router.hpp>
2018-08-05 23:49:23 +00:00
#include <jni.h>
#include <signal.h>
2018-08-06 00:06:00 +00:00
#include <memory>
2018-08-05 23:49:23 +00:00
#include <thread>
2018-08-06 00:06:00 +00:00
struct AndroidMain
2018-08-05 23:49:23 +00:00
{
2018-08-06 00:06:00 +00:00
llarp_main* m_impl = nullptr;
std::thread* m_thread = nullptr;
2018-11-26 14:31:52 +00:00
std::string configFile;
2018-08-05 23:49:23 +00:00
2018-11-26 14:31:52 +00:00
/// set configuration and ensure files
bool
Configure(const char* conf, const char* basedir)
2018-11-26 14:31:52 +00:00
{
configFile = conf;
return llarp_ensure_config(conf, basedir, false, false);
}
/// reload config on runtime
bool
ReloadConfig()
{
if(!m_impl)
2018-11-26 14:31:52 +00:00
return false;
llarp_main_signal(m_impl, SIGHUP);
return true;
}
/// start daemon thread
2018-08-06 01:48:15 +00:00
bool
2018-11-26 14:31:52 +00:00
Start()
2018-08-05 23:49:23 +00:00
{
if(m_impl || m_thread)
2018-08-06 01:52:46 +00:00
return true;
2018-11-26 14:31:52 +00:00
m_impl = llarp_main_init(configFile.c_str(), true);
2018-08-06 01:48:15 +00:00
if(m_impl == nullptr)
return false;
2019-07-24 14:17:54 +00:00
if(llarp_main_setup(m_impl, false))
{
llarp_main_free(m_impl);
m_impl = nullptr;
return false;
}
2018-08-05 23:49:23 +00:00
m_thread = new std::thread(std::bind(&AndroidMain::Run, this));
2018-08-06 01:48:15 +00:00
return true;
2018-08-05 23:49:23 +00:00
}
2018-11-26 14:31:52 +00:00
/// return true if we are running
2018-08-06 00:12:19 +00:00
bool
Running() const
{
2018-11-26 14:31:52 +00:00
return m_impl != nullptr && m_thread != nullptr;
2018-08-06 00:12:19 +00:00
}
2018-11-26 14:31:52 +00:00
/// blocking run
2018-08-06 00:06:00 +00:00
void
Run()
2018-08-05 23:49:23 +00:00
{
if(llarp_main_run(m_impl))
{
// on error
llarp::LogError("daemon run fail");
llarp_main* ptr = m_impl;
m_impl = nullptr;
llarp_main_signal(ptr, SIGINT);
llarp_main_free(ptr);
}
}
const char*
GetIfAddr()
{
std::string addr;
if(m_impl)
{
auto* ctx = llarp_main_get_context(m_impl);
if(!ctx)
return "";
ctx->router->hiddenServiceContext().ForEachService(
[&addr](const std::string&,
const llarp::service::Endpoint_ptr& ep) -> bool {
if(addr.empty())
{
if(ep->HasIfAddr())
{
// TODO: v4
const auto ip = ep->GetIfAddr();
if(ip.h)
{
addr = ip.ToString();
return false;
}
}
}
return true;
});
}
return addr.c_str();
}
int
GetIfRange() const
{
if(m_impl)
{
auto* ctx = llarp_main_get_context(m_impl);
if(!ctx)
return -1;
}
return -1;
}
void
2019-04-08 15:54:19 +00:00
SetVPN_FD(int rfd, int wfd)
{
(void)rfd;
(void)wfd;
// if(m_impl)
// llarp_main_inject_vpn_fd(m_impl, rfd, wfd);
2018-08-05 23:49:23 +00:00
}
2018-11-26 14:31:52 +00:00
/// stop daemon thread
2018-08-06 00:06:00 +00:00
void
Stop()
2018-08-05 23:49:23 +00:00
{
if(m_impl)
llarp_main_signal(m_impl, SIGINT);
2018-08-06 00:12:19 +00:00
m_thread->join();
delete m_thread;
m_thread = nullptr;
if(m_impl)
llarp_main_free(m_impl);
2018-08-06 00:12:19 +00:00
m_impl = nullptr;
2018-08-05 23:49:23 +00:00
}
2018-08-06 00:06:00 +00:00
typedef std::unique_ptr< AndroidMain > Ptr;
2018-08-06 00:13:08 +00:00
};
2018-08-05 23:49:23 +00:00
2019-04-08 15:54:19 +00:00
static AndroidMain::Ptr daemon_ptr(new AndroidMain());
2018-08-06 00:12:19 +00:00
2018-08-05 23:49:23 +00:00
extern "C"
{
2018-08-06 00:06:00 +00:00
JNIEXPORT jstring JNICALL
2018-08-06 00:12:19 +00:00
Java_network_loki_lokinet_Lokinet_1JNI_getABICompiledWith(JNIEnv* env, jclass)
2018-08-06 00:06:00 +00:00
{
// TODO: fixme
2018-08-06 00:14:39 +00:00
return env->NewStringUTF("android");
2018-08-06 00:06:00 +00:00
}
2018-08-05 23:49:23 +00:00
2018-08-06 00:12:19 +00:00
JNIEXPORT jstring JNICALL
Java_network_loki_lokinet_Lokinet_1JNI_startLokinet(JNIEnv* env, jclass,
2018-08-06 01:48:15 +00:00
jstring configfile)
2018-08-05 23:49:23 +00:00
{
2019-04-08 15:54:19 +00:00
if(daemon_ptr->Running())
2018-08-06 00:14:39 +00:00
return env->NewStringUTF("already running");
2018-08-06 01:48:15 +00:00
std::string conf;
2018-11-06 14:06:09 +00:00
fs::path basepath;
2018-08-06 00:06:00 +00:00
{
2018-08-06 04:24:25 +00:00
const char* nativeString = env->GetStringUTFChars(configfile, JNI_FALSE);
2018-08-06 04:23:08 +00:00
conf += std::string(nativeString);
2018-08-06 04:24:25 +00:00
env->ReleaseStringUTFChars(configfile, nativeString);
2018-11-06 14:06:09 +00:00
basepath = fs::path(conf).parent_path();
2018-08-06 00:06:00 +00:00
}
2019-04-08 15:54:19 +00:00
if(daemon_ptr->Configure(conf.c_str(), basepath.string().c_str()))
2018-11-26 14:31:52 +00:00
{
2019-04-08 15:54:19 +00:00
if(daemon_ptr->Start())
2018-11-26 14:31:52 +00:00
return env->NewStringUTF("ok");
else
2018-11-26 14:31:52 +00:00
return env->NewStringUTF("failed to start daemon");
}
else
return env->NewStringUTF("failed to configure daemon");
2018-08-06 00:06:00 +00:00
}
2018-08-06 01:54:24 +00:00
JNIEXPORT void JNICALL
Java_network_loki_lokinet_Lokinet_1JNI_stopLokinet(JNIEnv*, jclass)
2018-08-06 00:06:00 +00:00
{
2019-04-08 15:54:19 +00:00
if(daemon_ptr->Running())
2018-08-06 01:54:24 +00:00
{
2019-04-08 15:54:19 +00:00
daemon_ptr->Stop();
2018-08-06 01:54:24 +00:00
}
2018-08-06 00:06:00 +00:00
}
JNIEXPORT void JNICALL
Java_network_loki_lokinet_Lokinet_1JNI_setVPNFileDescriptor(JNIEnv*, jclass,
2019-04-08 15:54:19 +00:00
jint rfd,
jint wfd)
{
2019-04-08 15:54:19 +00:00
daemon_ptr->SetVPN_FD(rfd, wfd);
}
JNIEXPORT jstring JNICALL
Java_network_loki_lokinet_Lokinet_1JNI_getIfAddr(JNIEnv* env, jclass)
{
2019-04-08 15:54:19 +00:00
if(daemon_ptr)
return env->NewStringUTF(daemon_ptr->GetIfAddr());
else
return env->NewStringUTF("");
}
JNIEXPORT jint JNICALL
Java_network_loki_lokinet_Lokinet_1JNI_getIfRange(JNIEnv*, jclass)
{
2019-04-08 15:54:19 +00:00
if(daemon_ptr)
return daemon_ptr->GetIfRange();
else
return -1;
}
2018-08-06 01:48:15 +00:00
2018-08-06 01:54:24 +00:00
JNIEXPORT void JNICALL
Java_network_loki_lokinet_Lokinet_1JNI_onNetworkStateChanged(
JNIEnv*, jclass, jboolean isConnected)
2018-08-06 01:54:24 +00:00
{
2018-11-26 14:31:52 +00:00
if(isConnected)
{
2019-04-08 15:54:19 +00:00
if(!daemon_ptr->Running())
2018-11-26 14:31:52 +00:00
{
2019-04-08 15:54:19 +00:00
if(!daemon_ptr->Start())
2018-11-26 14:31:52 +00:00
{
// TODO: do some kind of callback here
}
}
}
2019-04-08 15:54:19 +00:00
else if(daemon_ptr->Running())
2018-11-26 14:31:52 +00:00
{
2019-04-08 15:54:19 +00:00
daemon_ptr->Stop();
2018-11-26 14:31:52 +00:00
}
2018-08-06 01:54:24 +00:00
}
}