From f11266972e81a6db65aeecc3f77fe2b47418385c Mon Sep 17 00:00:00 2001 From: unlnown542a Date: Fri, 30 Mar 2018 15:50:30 +0300 Subject: [PATCH 1/3] Change jni to build executable. Clone with minimal changes DaemonUnix into DaemonAndroid --- android/jni/Android.mk | 8 +- android/jni/Application.mk | 8 +- android/jni/DaemonAndroid.cpp | 334 +++++++++++----------- android/jni/DaemonAndroid.h | 129 ++++----- android/jni/i2pd_android.cpp | 66 ----- android/jni/org_purplei2p_i2pd_I2PD_JNI.h | 33 --- 6 files changed, 227 insertions(+), 351 deletions(-) delete mode 100755 android/jni/i2pd_android.cpp delete mode 100644 android/jni/org_purplei2p_i2pd_I2PD_JNI.h diff --git a/android/jni/Android.mk b/android/jni/Android.mk index d5a8f05f..90284995 100755 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -12,15 +12,15 @@ LOCAL_STATIC_LIBRARIES := \ miniupnpc LOCAL_LDLIBS := -lz -LOCAL_SRC_FILES := DaemonAndroid.cpp i2pd_android.cpp $(IFADDRS_PATH)/ifaddrs.c \ +LOCAL_SRC_FILES := DaemonAndroid.cpp $(IFADDRS_PATH)/ifaddrs.c \ $(wildcard $(LIB_SRC_PATH)/*.cpp)\ $(wildcard $(LIB_CLIENT_SRC_PATH)/*.cpp)\ $(DAEMON_SRC_PATH)/Daemon.cpp \ $(DAEMON_SRC_PATH)/UPnP.cpp \ $(DAEMON_SRC_PATH)/HTTPServer.cpp \ - $(DAEMON_SRC_PATH)/I2PControl.cpp - -include $(BUILD_SHARED_LIBRARY) + $(DAEMON_SRC_PATH)/I2PControl.cpp \ + $(DAEMON_SRC_PATH)/i2pd.cpp +include $(BUILD_EXECUTABLE) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) diff --git a/android/jni/Application.mk b/android/jni/Application.mk index 0fa116c2..acc6f895 100755 --- a/android/jni/Application.mk +++ b/android/jni/Application.mk @@ -9,12 +9,14 @@ APP_PLATFORM := android-14 # http://stackoverflow.com/a/21386866/529442 http://stackoverflow.com/a/15616255/529442 to enable c++11 support in Eclipse NDK_TOOLCHAIN_VERSION := 4.9 # APP_STL := stlport_shared --> does not seem to contain C++11 features -APP_STL := gnustl_shared +#APP_STL := gnustl_shared +APP_STL := gnustl_static # Enable c++11 extensions in source code -APP_CPPFLAGS += -std=c++11 +APP_CPPFLAGS += -std=c++11 -fvisibility=default -fPIE APP_CPPFLAGS += -DANDROID -D__ANDROID__ -DUSE_UPNP +APP_LDFLAGS += -rdynamic -fPIE -pie ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) APP_CPPFLAGS += -DANDROID_ARM7A endif @@ -26,7 +28,7 @@ APP_OPTIM := debug # git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git # git clone https://github.com/PurpleI2P/android-ifaddrs.git # change to your own -I2PD_LIBS_PATH = /path/to/libraries +I2PD_LIBS_PATH = /home/u/build/i2p/daemon/static.libs BOOST_PATH = $(I2PD_LIBS_PATH)/Boost-for-Android-Prebuilt OPENSSL_PATH = $(I2PD_LIBS_PATH)/OpenSSL-for-Android-Prebuilt MINIUPNP_PATH = $(I2PD_LIBS_PATH)/MiniUPnP-for-Android-Prebuilt diff --git a/android/jni/DaemonAndroid.cpp b/android/jni/DaemonAndroid.cpp index 75584740..94c679be 100644 --- a/android/jni/DaemonAndroid.cpp +++ b/android/jni/DaemonAndroid.cpp @@ -1,193 +1,193 @@ #include "DaemonAndroid.h" -#include "Daemon.h" -#include -#include -#include -#include -//#include "mainwindow.h" -namespace i2p -{ -namespace android -{ -/* Worker::Worker (DaemonAndroidImpl& daemon): - m_Daemon (daemon) - { - } +#ifndef _WIN32 - void Worker::startDaemon() - { - Log.d(TAG"Performing daemon start..."); - m_Daemon.start(); - Log.d(TAG"Daemon started."); - emit resultReady(); - } - void Worker::restartDaemon() - { - Log.d(TAG"Performing daemon restart..."); - m_Daemon.restart(); - Log.d(TAG"Daemon restarted."); - emit resultReady(); - } - void Worker::stopDaemon() { - Log.d(TAG"Performing daemon stop..."); - m_Daemon.stop(); - Log.d(TAG"Daemon stopped."); - emit resultReady(); - } +#include +#include +#include +#include +#include +#include +#include - Controller::Controller(DaemonAndroidImpl& daemon): - m_Daemon (daemon) - { - Worker *worker = new Worker (m_Daemon); - worker->moveToThread(&workerThread); - connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); - connect(this, &Controller::startDaemon, worker, &Worker::startDaemon); - connect(this, &Controller::stopDaemon, worker, &Worker::stopDaemon); - connect(this, &Controller::restartDaemon, worker, &Worker::restartDaemon); - connect(worker, &Worker::resultReady, this, &Controller::handleResults); - workerThread.start(); - } - Controller::~Controller() - { - Log.d(TAG"Closing and waiting for daemon worker thread..."); - workerThread.quit(); - workerThread.wait(); - Log.d(TAG"Waiting for daemon worker thread finished."); - if(m_Daemon.isRunning()) - { - Log.d(TAG"Stopping the daemon..."); - m_Daemon.stop(); - Log.d(TAG"Stopped the daemon."); - } - } -*/ - DaemonAndroidImpl::DaemonAndroidImpl () - //: - /*mutex(nullptr), */ - //m_IsRunning(false), - //m_RunningChangedCallback(nullptr) - { - } +#include "Config.h" +#include "FS.h" +#include "Log.h" +#include "Tunnel.h" +#include "RouterContext.h" +#include "ClientContext.h" - DaemonAndroidImpl::~DaemonAndroidImpl () - { - //delete mutex; - } - - bool DaemonAndroidImpl::init(int argc, char* argv[]) - { - //mutex=new QMutex(QMutex::Recursive); - //setRunningCallback(0); - //m_IsRunning=false; - return Daemon.init(argc,argv); - } - - void DaemonAndroidImpl::start() - { - //QMutexLocker locker(mutex); - //setRunning(true); - Daemon.start(); +void handle_signal(int sig) +{ + switch (sig) + { + case SIGHUP: + LogPrint(eLogInfo, "Daemon: Got SIGHUP, reopening tunnel configuration..."); + i2p::client::context.ReloadConfig(); + break; + case SIGUSR1: + LogPrint(eLogInfo, "Daemon: Got SIGUSR1, reopening logs..."); + i2p::log::Logger().Reopen (); + break; + case SIGINT: + if (i2p::context.AcceptsTunnels () && !Daemon.gracefulShutdownInterval) + { + i2p::context.SetAcceptsTunnels (false); + Daemon.gracefulShutdownInterval = 10*60; // 10 minutes + LogPrint(eLogInfo, "Graceful shutdown after ", Daemon.gracefulShutdownInterval, " seconds"); + } + else + Daemon.running = 0; + break; + case SIGABRT: + case SIGTERM: + Daemon.running = 0; // Exit loop + break; + case SIGPIPE: + LogPrint(eLogInfo, "SIGPIPE received"); + break; } +} - void DaemonAndroidImpl::stop() +namespace i2p +{ + namespace util { - //QMutexLocker locker(mutex); - Daemon.stop(); - //setRunning(false); - } + bool DaemonAndroid::start() + { + if (isDaemon) + { + pid_t pid; + pid = fork(); + if (pid > 0) // parent + ::exit (EXIT_SUCCESS); - void DaemonAndroidImpl::restart() - { - //QMutexLocker locker(mutex); - stop(); - start(); - } - /* - void DaemonAndroidImpl::setRunningCallback(runningChangedCallback cb) - { - m_RunningChangedCallback = cb; - } + if (pid < 0) // error + { + LogPrint(eLogError, "Daemon: could not fork: ", strerror(errno)); + return false; + } - bool DaemonAndroidImpl::isRunning() - { - return m_IsRunning; - } + // child + umask(S_IWGRP | S_IRWXO); // 0027 + int sid = setsid(); + if (sid < 0) + { + LogPrint(eLogError, "Daemon: could not create process group."); + return false; + } + std::string d = i2p::fs::GetDataDir(); + if (chdir(d.c_str()) != 0) + { + LogPrint(eLogError, "Daemon: could not chdir: ", strerror(errno)); + return false; + } - void DaemonAndroidImpl::setRunning(bool newValue) - { - bool oldValue = m_IsRunning; - if(oldValue!=newValue) - { - m_IsRunning = newValue; - if(m_RunningChangedCallback) - m_RunningChangedCallback(); - } - } -*/ - static DaemonAndroidImpl daemon; - static char* argv[1]={strdup("tmp")}; - /** - * returns error details if failed - * returns "ok" if daemon initialized and started okay - */ - std::string start(/*int argc, char* argv[]*/) - { - try - { - //int result; + // point std{in,out,err} descriptors to /dev/null + freopen("/dev/null", "r", stdin); + freopen("/dev/null", "w", stdout); + freopen("/dev/null", "w", stderr); + } + // set proc limits + struct rlimit limit; + uint16_t nfiles; i2p::config::GetOption("limits.openfiles", nfiles); + getrlimit(RLIMIT_NOFILE, &limit); + if (nfiles == 0) { + LogPrint(eLogInfo, "Daemon: using system limit in ", limit.rlim_cur, " max open files"); + } else if (nfiles <= limit.rlim_max) { + limit.rlim_cur = nfiles; + if (setrlimit(RLIMIT_NOFILE, &limit) == 0) { + LogPrint(eLogInfo, "Daemon: set max number of open files to ", + nfiles, " (system limit is ", limit.rlim_max, ")"); + } else { + LogPrint(eLogError, "Daemon: can't set max number of open files: ", strerror(errno)); + } + } else { + LogPrint(eLogError, "Daemon: limits.openfiles exceeds system limit: ", limit.rlim_max); + } + uint32_t cfsize; i2p::config::GetOption("limits.coresize", cfsize); + if (cfsize) // core file size set { - //Log.d(TAG"Initialising the daemon..."); - bool daemonInitSuccess = daemon.init(1,argv); - if(!daemonInitSuccess) - { - //QMessageBox::critical(0, "Error", "Daemon init failed"); - return "Daemon init failed"; + cfsize *= 1024; + getrlimit(RLIMIT_CORE, &limit); + if (cfsize <= limit.rlim_max) { + limit.rlim_cur = cfsize; + if (setrlimit(RLIMIT_CORE, &limit) != 0) { + LogPrint(eLogError, "Daemon: can't set max size of coredump: ", strerror(errno)); + } else if (cfsize == 0) { + LogPrint(eLogInfo, "Daemon: coredumps disabled"); + } else { + LogPrint(eLogInfo, "Daemon: set max size of core files to ", cfsize / 1024, "Kb"); + } + } else { + LogPrint(eLogError, "Daemon: limits.coresize exceeds system limit: ", limit.rlim_max); } - //Log.d(TAG"Initialised, creating the main window..."); - //MainWindow w; - //Log.d(TAG"Before main window.show()..."); - //w.show (); + } + // Pidfile + // this code is c-styled and a bit ugly + std::string pidfile; i2p::config::GetOption("pidfile", pidfile); + if (pidfile == "") { + pidfile = i2p::fs::DataDirPath("i2pd.pid"); + } + if (pidfile != "") { + pidFH = open(pidfile.c_str(), O_RDWR | O_CREAT, 0600); + if (pidFH < 0) + { + LogPrint(eLogError, "Daemon: could not create pid file ", pidfile, ": ", strerror(errno)); + return false; + } + char pid[10]; + sprintf(pid, "%d\n", getpid()); + ftruncate(pidFH, 0); + if (write(pidFH, pid, strlen(pid)) < 0) { - //i2p::qt::Controller daemonQtController(daemon); - //Log.d(TAG"Starting the daemon..."); - //emit daemonQtController.startDaemon(); - //daemon.start (); - //Log.d(TAG"Starting GUI event loop..."); - //result = app.exec(); - //daemon.stop (); - daemon.start(); + LogPrint(eLogError, "Daemon: could not write pidfile: ", strerror(errno)); + return false; } } + gracefulShutdownInterval = 0; // not specified - //QMessageBox::information(&w, "Debug", "demon stopped"); - //Log.d(TAG"Exiting the application"); - //return result; - } - catch (boost::exception& ex) - { - std::stringstream ss; - ss << boost::diagnostic_information(ex); - return ss.str(); + // Signal handler + struct sigaction sa; + sa.sa_handler = handle_signal; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + sigaction(SIGHUP, &sa, 0); + sigaction(SIGUSR1, &sa, 0); + sigaction(SIGABRT, &sa, 0); + sigaction(SIGTERM, &sa, 0); + sigaction(SIGINT, &sa, 0); + sigaction(SIGPIPE, &sa, 0); + + return Daemon_Singleton::start(); } - catch (std::exception& ex) + + bool DaemonAndroid::stop() { - std::stringstream ss; - ss << ex.what(); - return ss.str(); + i2p::fs::Remove(pidfile); + + return Daemon_Singleton::stop(); } - catch(...) + + void DaemonAndroid::run () { - return "unknown exception"; + while (running) + { + std::this_thread::sleep_for (std::chrono::seconds(1)); + if (gracefulShutdownInterval) + { + gracefulShutdownInterval--; // - 1 second + if (gracefulShutdownInterval <= 0 || i2p::tunnel::tunnels.CountTransitTunnels() <= 0) + { + LogPrint(eLogInfo, "Graceful shutdown"); + return; + } + } + } } - return "ok"; - } - - void stop() - { - daemon.stop(); } } -} + +#endif diff --git a/android/jni/DaemonAndroid.h b/android/jni/DaemonAndroid.h index 9cc8219b..c62d7c76 100644 --- a/android/jni/DaemonAndroid.h +++ b/android/jni/DaemonAndroid.h @@ -1,87 +1,60 @@ -#ifndef DAEMON_ANDROID_H -#define DAEMON_ANDROID_H +#ifndef DAEMON_H__ +#define DAEMON_H__ +#include #include namespace i2p { -namespace android +namespace util { - class DaemonAndroidImpl - { - public: - - DaemonAndroidImpl (); - ~DaemonAndroidImpl (); - - //typedef void (*runningChangedCallback)(); - - /** - * @return success - */ - bool init(int argc, char* argv[]); - void start(); - void stop(); - void restart(); - //void setRunningCallback(runningChangedCallback cb); - //bool isRunning(); - private: - //void setRunning(bool running); - private: - //QMutex* mutex; - //bool m_IsRunning; - //runningChangedCallback m_RunningChangedCallback; - }; - - /** - * returns "ok" if daemon init failed - * returns errinfo if daemon initialized and started okay - */ - std::string start(); - - // stops the daemon - void stop(); - - /* - class Worker : public QObject - { - Q_OBJECT - public: - - Worker (DaemonAndroidImpl& daemon); - - private: - - DaemonAndroidImpl& m_Daemon; - - public slots: - void startDaemon(); - void restartDaemon(); - void stopDaemon(); - - signals: - void resultReady(); - }; - - class Controller : public QObject - { - Q_OBJECT - QThread workerThread; - public: - Controller(DaemonAndroidImpl& daemon); - ~Controller(); - private: - DaemonAndroidImpl& m_Daemon; - - public slots: - void handleResults(){} - signals: - void startDaemon(); - void stopDaemon(); - void restartDaemon(); - }; - */ + class Daemon_Singleton_Private; + class Daemon_Singleton + { + public: + virtual bool init(int argc, char* argv[]); + virtual bool start(); + virtual bool stop(); + virtual void run () {}; + + bool isDaemon; + bool running; + + protected: + Daemon_Singleton(); + virtual ~Daemon_Singleton(); + + bool IsService () const; + + // d-pointer for httpServer, httpProxy, etc. + class Daemon_Singleton_Private; + Daemon_Singleton_Private &d; + }; + +#if defined(ANDROID) +#define Daemon i2p::util::DaemonAndroid::Instance() + class DaemonAndroid : public Daemon_Singleton + { + public: + static DaemonAndroid& Instance() + { + static DaemonAndroid instance; + return instance; + } + + bool start(); + bool stop(); + void run (); + + private: + std::string pidfile; + int pidFH; + + public: + int gracefulShutdownInterval; // in seconds + }; +#endif } } -#endif // DAEMON_ANDROID_H +#endif // DAEMON_H__ diff --git a/android/jni/i2pd_android.cpp b/android/jni/i2pd_android.cpp deleted file mode 100755 index 8791c90b..00000000 --- a/android/jni/i2pd_android.cpp +++ /dev/null @@ -1,66 +0,0 @@ - -//#include -#include -#include "org_purplei2p_i2pd_I2PD_JNI.h" -#include "DaemonAndroid.h" -#include "RouterContext.h" -#include "Transports.h" - -JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith - (JNIEnv * env, jclass clazz) { -#if defined(__arm__) - #if defined(__ARM_ARCH_7A__) - #if defined(__ARM_NEON__) - #if defined(__ARM_PCS_VFP) - #define ABI "armeabi-v7a/NEON (hard-float)" - #else - #define ABI "armeabi-v7a/NEON" - #endif - #else - #if defined(__ARM_PCS_VFP) - #define ABI "armeabi-v7a (hard-float)" - #else - #define ABI "armeabi-v7a" - #endif - #endif - #else - #define ABI "armeabi" - #endif -#elif defined(__i386__) - #define ABI "x86" -#elif defined(__x86_64__) - #define ABI "x86_64" -#elif defined(__mips64) /* mips64el-* toolchain defines __mips__ too */ - #define ABI "mips64" -#elif defined(__mips__) - #define ABI "mips" -#elif defined(__aarch64__) - #define ABI "arm64-v8a" -#else - #define ABI "unknown" -#endif - - return env->NewStringUTF(ABI); -} - -JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon - (JNIEnv * env, jclass clazz) { - return env->NewStringUTF(i2p::android::start().c_str()); -} - -JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon - (JNIEnv * env, jclass clazz) { - i2p::android::stop(); -} - -JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels - (JNIEnv * env, jclass clazz) { - i2p::context.SetAcceptsTunnels (false); -} - -JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged - (JNIEnv * env, jclass clazz, jboolean isConnected) -{ - bool isConnectedBool = (bool) isConnected; - i2p::transport::transports.SetOnline (isConnectedBool); -} diff --git a/android/jni/org_purplei2p_i2pd_I2PD_JNI.h b/android/jni/org_purplei2p_i2pd_I2PD_JNI.h deleted file mode 100644 index 04923d22..00000000 --- a/android/jni/org_purplei2p_i2pd_I2PD_JNI.h +++ /dev/null @@ -1,33 +0,0 @@ -/* DO NOT EDIT THIS FILE - it is machine generated */ -#include -/* Header for class org_purplei2p_i2pd_I2PD_JNI */ - -#ifndef _Included_org_purplei2p_i2pd_I2PD_JNI -#define _Included_org_purplei2p_i2pd_I2PD_JNI -#ifdef __cplusplus -extern "C" { -#endif -/* - * Class: org_purplei2p_i2pd_I2PD_JNI - * Method: stringFromJNI - * Signature: ()Ljava/lang/String; - */ -JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith - (JNIEnv *, jclass); - -JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon - (JNIEnv *, jclass); - -JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon - (JNIEnv *, jclass); - -JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels - (JNIEnv *, jclass); - -JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged - (JNIEnv * env, jclass clazz, jboolean isConnected); - -#ifdef __cplusplus -} -#endif -#endif From 6916147dda4a4b46a1049d38bf81b5c6c9abb264 Mon Sep 17 00:00:00 2001 From: unlnown542a Date: Sat, 21 Apr 2018 21:48:42 +0300 Subject: [PATCH 2/3] Few cents to get fullly console i2pd under Android --- android/i2pd/Android.mk | 74 +++++++++++++++++++++++++++++++++++++ android/i2pd/Application.mk | 42 +++++++++++++++++++++ daemon/Daemon.h | 13 ------- daemon/UnixDaemon.cpp | 3 ++ 4 files changed, 119 insertions(+), 13 deletions(-) create mode 100755 android/i2pd/Android.mk create mode 100755 android/i2pd/Application.mk diff --git a/android/i2pd/Android.mk b/android/i2pd/Android.mk new file mode 100755 index 00000000..ae56110c --- /dev/null +++ b/android/i2pd/Android.mk @@ -0,0 +1,74 @@ +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) +LOCAL_MODULE := i2pd +LOCAL_CPP_FEATURES := rtti exceptions +LOCAL_C_INCLUDES += $(IFADDRS_PATH) $(LIB_SRC_PATH) $(LIB_CLIENT_SRC_PATH) $(DAEMON_SRC_PATH) +LOCAL_STATIC_LIBRARIES := \ + boost_system \ + boost_date_time \ + boost_filesystem \ + boost_program_options \ + crypto ssl \ + miniupnpc +LOCAL_LDLIBS := -lz + +LOCAL_SRC_FILES := $(IFADDRS_PATH)/ifaddrs.c \ + $(wildcard $(LIB_SRC_PATH)/*.cpp)\ + $(wildcard $(LIB_CLIENT_SRC_PATH)/*.cpp)\ + $(DAEMON_SRC_PATH)/UnixDaemon.cpp \ + $(DAEMON_SRC_PATH)/Daemon.cpp \ + $(DAEMON_SRC_PATH)/UPnP.cpp \ + $(DAEMON_SRC_PATH)/HTTPServer.cpp \ + $(DAEMON_SRC_PATH)/I2PControl.cpp \ + $(DAEMON_SRC_PATH)/i2pd.cpp +include $(BUILD_EXECUTABLE) + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) +LOCAL_MODULE := boost_system +LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_system.a +LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include +include $(PREBUILT_STATIC_LIBRARY) + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) +LOCAL_MODULE := boost_date_time +LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_date_time.a +LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include +include $(PREBUILT_STATIC_LIBRARY) + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) +LOCAL_MODULE := boost_filesystem +LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_filesystem.a +LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include +include $(PREBUILT_STATIC_LIBRARY) + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) +LOCAL_MODULE := boost_program_options +LOCAL_SRC_FILES := $(BOOST_PATH)/boost_1_62_0/$(TARGET_ARCH_ABI)/lib/libboost_program_options.a +LOCAL_EXPORT_C_INCLUDES := $(BOOST_PATH)/boost_1_62_0/include +include $(PREBUILT_STATIC_LIBRARY) + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) +LOCAL_MODULE := crypto +LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.0e/$(TARGET_ARCH_ABI)/lib/libcrypto.a +LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.0e/include +include $(PREBUILT_STATIC_LIBRARY) + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) +LOCAL_MODULE := ssl +LOCAL_SRC_FILES := $(OPENSSL_PATH)/openssl-1.1.0e/$(TARGET_ARCH_ABI)/lib/libssl.a +LOCAL_EXPORT_C_INCLUDES := $(OPENSSL_PATH)/openssl-1.1.0e/include +LOCAL_STATIC_LIBRARIES := crypto +include $(PREBUILT_STATIC_LIBRARY) + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) +LOCAL_MODULE := miniupnpc +LOCAL_SRC_FILES := $(MINIUPNP_PATH)/miniupnp-2.0/$(TARGET_ARCH_ABI)/lib/libminiupnpc.a +LOCAL_EXPORT_C_INCLUDES := $(MINIUPNP_PATH)/miniupnp-2.0/include +include $(PREBUILT_STATIC_LIBRARY) diff --git a/android/i2pd/Application.mk b/android/i2pd/Application.mk new file mode 100755 index 00000000..acc6f895 --- /dev/null +++ b/android/i2pd/Application.mk @@ -0,0 +1,42 @@ +#APP_ABI := all +#APP_ABI := armeabi-v7a x86 +#APP_ABI := x86 +#APP_ABI := x86_64 +APP_ABI := armeabi-v7a +#can be android-3 but will fail for x86 since arch-x86 is not present at ndkroot/platforms/android-3/ . libz is taken from there. +APP_PLATFORM := android-14 + +# http://stackoverflow.com/a/21386866/529442 http://stackoverflow.com/a/15616255/529442 to enable c++11 support in Eclipse +NDK_TOOLCHAIN_VERSION := 4.9 +# APP_STL := stlport_shared --> does not seem to contain C++11 features +#APP_STL := gnustl_shared +APP_STL := gnustl_static + +# Enable c++11 extensions in source code +APP_CPPFLAGS += -std=c++11 -fvisibility=default -fPIE + +APP_CPPFLAGS += -DANDROID -D__ANDROID__ -DUSE_UPNP +APP_LDFLAGS += -rdynamic -fPIE -pie +ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) +APP_CPPFLAGS += -DANDROID_ARM7A +endif + +APP_OPTIM := debug + +# git clone https://github.com/PurpleI2P/Boost-for-Android-Prebuilt.git +# git clone https://github.com/PurpleI2P/OpenSSL-for-Android-Prebuilt.git +# git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git +# git clone https://github.com/PurpleI2P/android-ifaddrs.git +# change to your own +I2PD_LIBS_PATH = /home/u/build/i2p/daemon/static.libs +BOOST_PATH = $(I2PD_LIBS_PATH)/Boost-for-Android-Prebuilt +OPENSSL_PATH = $(I2PD_LIBS_PATH)/OpenSSL-for-Android-Prebuilt +MINIUPNP_PATH = $(I2PD_LIBS_PATH)/MiniUPnP-for-Android-Prebuilt +IFADDRS_PATH = $(I2PD_LIBS_PATH)/android-ifaddrs + +# don't change me +I2PD_SRC_PATH = $(PWD)/.. + +LIB_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd +LIB_CLIENT_SRC_PATH = $(I2PD_SRC_PATH)/libi2pd_client +DAEMON_SRC_PATH = $(I2PD_SRC_PATH)/daemon diff --git a/daemon/Daemon.h b/daemon/Daemon.h index 48301e73..f3e72904 100644 --- a/daemon/Daemon.h +++ b/daemon/Daemon.h @@ -44,19 +44,6 @@ namespace util } }; -#elif defined(ANDROID) -#define Daemon i2p::util::DaemonAndroid::Instance() - // dummy, invoked from android/jni/DaemonAndroid.* - class DaemonAndroid: public i2p::util::Daemon_Singleton - { - public: - static DaemonAndroid& Instance() - { - static DaemonAndroid instance; - return instance; - } - }; - #elif defined(_WIN32) #define Daemon i2p::util::DaemonWin32::Instance() class DaemonWin32 : public Daemon_Singleton diff --git a/daemon/UnixDaemon.cpp b/daemon/UnixDaemon.cpp index a9c48fee..3dd38fba 100644 --- a/daemon/UnixDaemon.cpp +++ b/daemon/UnixDaemon.cpp @@ -138,11 +138,14 @@ namespace i2p LogPrint(eLogError, "Daemon: could not create pid file ", pidfile, ": ", strerror(errno)); return false; } + +#ifndef ANDROID if (lockf(pidFH, F_TLOCK, 0) != 0) { LogPrint(eLogError, "Daemon: could not lock pid file ", pidfile, ": ", strerror(errno)); return false; } +#endif char pid[10]; sprintf(pid, "%d\n", getpid()); ftruncate(pidFH, 0); From faac35cd1e868d888bba722164b7b3037af0ce46 Mon Sep 17 00:00:00 2001 From: unlnown542a Date: Sat, 21 Apr 2018 21:55:45 +0300 Subject: [PATCH 3/3] Revert "Change jni to build executable. Clone with minimal changes DaemonUnix into DaemonAndroid" This reverts commit f11266972e81a6db65aeecc3f77fe2b47418385c. --- android/jni/Android.mk | 8 +- android/jni/Application.mk | 8 +- android/jni/DaemonAndroid.cpp | 334 +++++++++++----------- android/jni/DaemonAndroid.h | 129 +++++---- android/jni/i2pd_android.cpp | 66 +++++ android/jni/org_purplei2p_i2pd_I2PD_JNI.h | 33 +++ 6 files changed, 351 insertions(+), 227 deletions(-) create mode 100755 android/jni/i2pd_android.cpp create mode 100644 android/jni/org_purplei2p_i2pd_I2PD_JNI.h diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 90284995..d5a8f05f 100755 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -12,15 +12,15 @@ LOCAL_STATIC_LIBRARIES := \ miniupnpc LOCAL_LDLIBS := -lz -LOCAL_SRC_FILES := DaemonAndroid.cpp $(IFADDRS_PATH)/ifaddrs.c \ +LOCAL_SRC_FILES := DaemonAndroid.cpp i2pd_android.cpp $(IFADDRS_PATH)/ifaddrs.c \ $(wildcard $(LIB_SRC_PATH)/*.cpp)\ $(wildcard $(LIB_CLIENT_SRC_PATH)/*.cpp)\ $(DAEMON_SRC_PATH)/Daemon.cpp \ $(DAEMON_SRC_PATH)/UPnP.cpp \ $(DAEMON_SRC_PATH)/HTTPServer.cpp \ - $(DAEMON_SRC_PATH)/I2PControl.cpp \ - $(DAEMON_SRC_PATH)/i2pd.cpp -include $(BUILD_EXECUTABLE) + $(DAEMON_SRC_PATH)/I2PControl.cpp + +include $(BUILD_SHARED_LIBRARY) LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) diff --git a/android/jni/Application.mk b/android/jni/Application.mk index acc6f895..0fa116c2 100755 --- a/android/jni/Application.mk +++ b/android/jni/Application.mk @@ -9,14 +9,12 @@ APP_PLATFORM := android-14 # http://stackoverflow.com/a/21386866/529442 http://stackoverflow.com/a/15616255/529442 to enable c++11 support in Eclipse NDK_TOOLCHAIN_VERSION := 4.9 # APP_STL := stlport_shared --> does not seem to contain C++11 features -#APP_STL := gnustl_shared -APP_STL := gnustl_static +APP_STL := gnustl_shared # Enable c++11 extensions in source code -APP_CPPFLAGS += -std=c++11 -fvisibility=default -fPIE +APP_CPPFLAGS += -std=c++11 APP_CPPFLAGS += -DANDROID -D__ANDROID__ -DUSE_UPNP -APP_LDFLAGS += -rdynamic -fPIE -pie ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) APP_CPPFLAGS += -DANDROID_ARM7A endif @@ -28,7 +26,7 @@ APP_OPTIM := debug # git clone https://github.com/PurpleI2P/MiniUPnP-for-Android-Prebuilt.git # git clone https://github.com/PurpleI2P/android-ifaddrs.git # change to your own -I2PD_LIBS_PATH = /home/u/build/i2p/daemon/static.libs +I2PD_LIBS_PATH = /path/to/libraries BOOST_PATH = $(I2PD_LIBS_PATH)/Boost-for-Android-Prebuilt OPENSSL_PATH = $(I2PD_LIBS_PATH)/OpenSSL-for-Android-Prebuilt MINIUPNP_PATH = $(I2PD_LIBS_PATH)/MiniUPnP-for-Android-Prebuilt diff --git a/android/jni/DaemonAndroid.cpp b/android/jni/DaemonAndroid.cpp index 94c679be..75584740 100644 --- a/android/jni/DaemonAndroid.cpp +++ b/android/jni/DaemonAndroid.cpp @@ -1,193 +1,193 @@ #include "DaemonAndroid.h" +#include "Daemon.h" +#include +#include +#include +#include +//#include "mainwindow.h" -#ifndef _WIN32 +namespace i2p +{ +namespace android +{ +/* Worker::Worker (DaemonAndroidImpl& daemon): + m_Daemon (daemon) + { + } -#include -#include -#include -#include -#include -#include -#include + void Worker::startDaemon() + { + Log.d(TAG"Performing daemon start..."); + m_Daemon.start(); + Log.d(TAG"Daemon started."); + emit resultReady(); + } + void Worker::restartDaemon() + { + Log.d(TAG"Performing daemon restart..."); + m_Daemon.restart(); + Log.d(TAG"Daemon restarted."); + emit resultReady(); + } + void Worker::stopDaemon() { + Log.d(TAG"Performing daemon stop..."); + m_Daemon.stop(); + Log.d(TAG"Daemon stopped."); + emit resultReady(); + } -#include "Config.h" -#include "FS.h" -#include "Log.h" -#include "Tunnel.h" -#include "RouterContext.h" -#include "ClientContext.h" + Controller::Controller(DaemonAndroidImpl& daemon): + m_Daemon (daemon) + { + Worker *worker = new Worker (m_Daemon); + worker->moveToThread(&workerThread); + connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater); + connect(this, &Controller::startDaemon, worker, &Worker::startDaemon); + connect(this, &Controller::stopDaemon, worker, &Worker::stopDaemon); + connect(this, &Controller::restartDaemon, worker, &Worker::restartDaemon); + connect(worker, &Worker::resultReady, this, &Controller::handleResults); + workerThread.start(); + } + Controller::~Controller() + { + Log.d(TAG"Closing and waiting for daemon worker thread..."); + workerThread.quit(); + workerThread.wait(); + Log.d(TAG"Waiting for daemon worker thread finished."); + if(m_Daemon.isRunning()) + { + Log.d(TAG"Stopping the daemon..."); + m_Daemon.stop(); + Log.d(TAG"Stopped the daemon."); + } + } +*/ + DaemonAndroidImpl::DaemonAndroidImpl () + //: + /*mutex(nullptr), */ + //m_IsRunning(false), + //m_RunningChangedCallback(nullptr) + { + } -void handle_signal(int sig) -{ - switch (sig) - { - case SIGHUP: - LogPrint(eLogInfo, "Daemon: Got SIGHUP, reopening tunnel configuration..."); - i2p::client::context.ReloadConfig(); - break; - case SIGUSR1: - LogPrint(eLogInfo, "Daemon: Got SIGUSR1, reopening logs..."); - i2p::log::Logger().Reopen (); - break; - case SIGINT: - if (i2p::context.AcceptsTunnels () && !Daemon.gracefulShutdownInterval) - { - i2p::context.SetAcceptsTunnels (false); - Daemon.gracefulShutdownInterval = 10*60; // 10 minutes - LogPrint(eLogInfo, "Graceful shutdown after ", Daemon.gracefulShutdownInterval, " seconds"); - } - else - Daemon.running = 0; - break; - case SIGABRT: - case SIGTERM: - Daemon.running = 0; // Exit loop - break; - case SIGPIPE: - LogPrint(eLogInfo, "SIGPIPE received"); - break; + DaemonAndroidImpl::~DaemonAndroidImpl () + { + //delete mutex; } -} -namespace i2p -{ - namespace util + bool DaemonAndroidImpl::init(int argc, char* argv[]) { - bool DaemonAndroid::start() - { - if (isDaemon) - { - pid_t pid; - pid = fork(); - if (pid > 0) // parent - ::exit (EXIT_SUCCESS); + //mutex=new QMutex(QMutex::Recursive); + //setRunningCallback(0); + //m_IsRunning=false; + return Daemon.init(argc,argv); + } - if (pid < 0) // error - { - LogPrint(eLogError, "Daemon: could not fork: ", strerror(errno)); - return false; - } + void DaemonAndroidImpl::start() + { + //QMutexLocker locker(mutex); + //setRunning(true); + Daemon.start(); + } - // child - umask(S_IWGRP | S_IRWXO); // 0027 - int sid = setsid(); - if (sid < 0) - { - LogPrint(eLogError, "Daemon: could not create process group."); - return false; - } - std::string d = i2p::fs::GetDataDir(); - if (chdir(d.c_str()) != 0) - { - LogPrint(eLogError, "Daemon: could not chdir: ", strerror(errno)); - return false; - } + void DaemonAndroidImpl::stop() + { + //QMutexLocker locker(mutex); + Daemon.stop(); + //setRunning(false); + } - // point std{in,out,err} descriptors to /dev/null - freopen("/dev/null", "r", stdin); - freopen("/dev/null", "w", stdout); - freopen("/dev/null", "w", stderr); - } + void DaemonAndroidImpl::restart() + { + //QMutexLocker locker(mutex); + stop(); + start(); + } + /* + void DaemonAndroidImpl::setRunningCallback(runningChangedCallback cb) + { + m_RunningChangedCallback = cb; + } - // set proc limits - struct rlimit limit; - uint16_t nfiles; i2p::config::GetOption("limits.openfiles", nfiles); - getrlimit(RLIMIT_NOFILE, &limit); - if (nfiles == 0) { - LogPrint(eLogInfo, "Daemon: using system limit in ", limit.rlim_cur, " max open files"); - } else if (nfiles <= limit.rlim_max) { - limit.rlim_cur = nfiles; - if (setrlimit(RLIMIT_NOFILE, &limit) == 0) { - LogPrint(eLogInfo, "Daemon: set max number of open files to ", - nfiles, " (system limit is ", limit.rlim_max, ")"); - } else { - LogPrint(eLogError, "Daemon: can't set max number of open files: ", strerror(errno)); - } - } else { - LogPrint(eLogError, "Daemon: limits.openfiles exceeds system limit: ", limit.rlim_max); - } - uint32_t cfsize; i2p::config::GetOption("limits.coresize", cfsize); - if (cfsize) // core file size set - { - cfsize *= 1024; - getrlimit(RLIMIT_CORE, &limit); - if (cfsize <= limit.rlim_max) { - limit.rlim_cur = cfsize; - if (setrlimit(RLIMIT_CORE, &limit) != 0) { - LogPrint(eLogError, "Daemon: can't set max size of coredump: ", strerror(errno)); - } else if (cfsize == 0) { - LogPrint(eLogInfo, "Daemon: coredumps disabled"); - } else { - LogPrint(eLogInfo, "Daemon: set max size of core files to ", cfsize / 1024, "Kb"); - } - } else { - LogPrint(eLogError, "Daemon: limits.coresize exceeds system limit: ", limit.rlim_max); - } - } + bool DaemonAndroidImpl::isRunning() + { + return m_IsRunning; + } - // Pidfile - // this code is c-styled and a bit ugly - std::string pidfile; i2p::config::GetOption("pidfile", pidfile); - if (pidfile == "") { - pidfile = i2p::fs::DataDirPath("i2pd.pid"); - } - if (pidfile != "") { - pidFH = open(pidfile.c_str(), O_RDWR | O_CREAT, 0600); - if (pidFH < 0) + void DaemonAndroidImpl::setRunning(bool newValue) + { + bool oldValue = m_IsRunning; + if(oldValue!=newValue) + { + m_IsRunning = newValue; + if(m_RunningChangedCallback) + m_RunningChangedCallback(); + } + } +*/ + static DaemonAndroidImpl daemon; + static char* argv[1]={strdup("tmp")}; + /** + * returns error details if failed + * returns "ok" if daemon initialized and started okay + */ + std::string start(/*int argc, char* argv[]*/) + { + try + { + //int result; + + { + //Log.d(TAG"Initialising the daemon..."); + bool daemonInitSuccess = daemon.init(1,argv); + if(!daemonInitSuccess) { - LogPrint(eLogError, "Daemon: could not create pid file ", pidfile, ": ", strerror(errno)); - return false; + //QMessageBox::critical(0, "Error", "Daemon init failed"); + return "Daemon init failed"; } - char pid[10]; - sprintf(pid, "%d\n", getpid()); - ftruncate(pidFH, 0); - if (write(pidFH, pid, strlen(pid)) < 0) + //Log.d(TAG"Initialised, creating the main window..."); + //MainWindow w; + //Log.d(TAG"Before main window.show()..."); + //w.show (); + { - LogPrint(eLogError, "Daemon: could not write pidfile: ", strerror(errno)); - return false; + //i2p::qt::Controller daemonQtController(daemon); + //Log.d(TAG"Starting the daemon..."); + //emit daemonQtController.startDaemon(); + //daemon.start (); + //Log.d(TAG"Starting GUI event loop..."); + //result = app.exec(); + //daemon.stop (); + daemon.start(); } } - gracefulShutdownInterval = 0; // not specified - // Signal handler - struct sigaction sa; - sa.sa_handler = handle_signal; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_RESTART; - sigaction(SIGHUP, &sa, 0); - sigaction(SIGUSR1, &sa, 0); - sigaction(SIGABRT, &sa, 0); - sigaction(SIGTERM, &sa, 0); - sigaction(SIGINT, &sa, 0); - sigaction(SIGPIPE, &sa, 0); - - return Daemon_Singleton::start(); + //QMessageBox::information(&w, "Debug", "demon stopped"); + //Log.d(TAG"Exiting the application"); + //return result; } - - bool DaemonAndroid::stop() + catch (boost::exception& ex) { - i2p::fs::Remove(pidfile); - - return Daemon_Singleton::stop(); + std::stringstream ss; + ss << boost::diagnostic_information(ex); + return ss.str(); } - - void DaemonAndroid::run () + catch (std::exception& ex) { - while (running) - { - std::this_thread::sleep_for (std::chrono::seconds(1)); - if (gracefulShutdownInterval) - { - gracefulShutdownInterval--; // - 1 second - if (gracefulShutdownInterval <= 0 || i2p::tunnel::tunnels.CountTransitTunnels() <= 0) - { - LogPrint(eLogInfo, "Graceful shutdown"); - return; - } - } - } + std::stringstream ss; + ss << ex.what(); + return ss.str(); } + catch(...) + { + return "unknown exception"; + } + return "ok"; } -} -#endif + void stop() + { + daemon.stop(); + } +} +} diff --git a/android/jni/DaemonAndroid.h b/android/jni/DaemonAndroid.h index c62d7c76..9cc8219b 100644 --- a/android/jni/DaemonAndroid.h +++ b/android/jni/DaemonAndroid.h @@ -1,60 +1,87 @@ -#ifndef DAEMON_H__ -#define DAEMON_H__ +#ifndef DAEMON_ANDROID_H +#define DAEMON_ANDROID_H -#include #include namespace i2p { -namespace util +namespace android { - class Daemon_Singleton_Private; - class Daemon_Singleton - { - public: - virtual bool init(int argc, char* argv[]); - virtual bool start(); - virtual bool stop(); - virtual void run () {}; - - bool isDaemon; - bool running; - - protected: - Daemon_Singleton(); - virtual ~Daemon_Singleton(); - - bool IsService () const; - - // d-pointer for httpServer, httpProxy, etc. - class Daemon_Singleton_Private; - Daemon_Singleton_Private &d; - }; - -#if defined(ANDROID) -#define Daemon i2p::util::DaemonAndroid::Instance() - class DaemonAndroid : public Daemon_Singleton - { - public: - static DaemonAndroid& Instance() - { - static DaemonAndroid instance; - return instance; - } - - bool start(); - bool stop(); - void run (); - - private: - std::string pidfile; - int pidFH; - - public: - int gracefulShutdownInterval; // in seconds - }; -#endif + class DaemonAndroidImpl + { + public: + + DaemonAndroidImpl (); + ~DaemonAndroidImpl (); + + //typedef void (*runningChangedCallback)(); + + /** + * @return success + */ + bool init(int argc, char* argv[]); + void start(); + void stop(); + void restart(); + //void setRunningCallback(runningChangedCallback cb); + //bool isRunning(); + private: + //void setRunning(bool running); + private: + //QMutex* mutex; + //bool m_IsRunning; + //runningChangedCallback m_RunningChangedCallback; + }; + + /** + * returns "ok" if daemon init failed + * returns errinfo if daemon initialized and started okay + */ + std::string start(); + + // stops the daemon + void stop(); + + /* + class Worker : public QObject + { + Q_OBJECT + public: + + Worker (DaemonAndroidImpl& daemon); + + private: + + DaemonAndroidImpl& m_Daemon; + + public slots: + void startDaemon(); + void restartDaemon(); + void stopDaemon(); + + signals: + void resultReady(); + }; + + class Controller : public QObject + { + Q_OBJECT + QThread workerThread; + public: + Controller(DaemonAndroidImpl& daemon); + ~Controller(); + private: + DaemonAndroidImpl& m_Daemon; + + public slots: + void handleResults(){} + signals: + void startDaemon(); + void stopDaemon(); + void restartDaemon(); + }; + */ } } -#endif // DAEMON_H__ +#endif // DAEMON_ANDROID_H diff --git a/android/jni/i2pd_android.cpp b/android/jni/i2pd_android.cpp new file mode 100755 index 00000000..8791c90b --- /dev/null +++ b/android/jni/i2pd_android.cpp @@ -0,0 +1,66 @@ + +//#include +#include +#include "org_purplei2p_i2pd_I2PD_JNI.h" +#include "DaemonAndroid.h" +#include "RouterContext.h" +#include "Transports.h" + +JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith + (JNIEnv * env, jclass clazz) { +#if defined(__arm__) + #if defined(__ARM_ARCH_7A__) + #if defined(__ARM_NEON__) + #if defined(__ARM_PCS_VFP) + #define ABI "armeabi-v7a/NEON (hard-float)" + #else + #define ABI "armeabi-v7a/NEON" + #endif + #else + #if defined(__ARM_PCS_VFP) + #define ABI "armeabi-v7a (hard-float)" + #else + #define ABI "armeabi-v7a" + #endif + #endif + #else + #define ABI "armeabi" + #endif +#elif defined(__i386__) + #define ABI "x86" +#elif defined(__x86_64__) + #define ABI "x86_64" +#elif defined(__mips64) /* mips64el-* toolchain defines __mips__ too */ + #define ABI "mips64" +#elif defined(__mips__) + #define ABI "mips" +#elif defined(__aarch64__) + #define ABI "arm64-v8a" +#else + #define ABI "unknown" +#endif + + return env->NewStringUTF(ABI); +} + +JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon + (JNIEnv * env, jclass clazz) { + return env->NewStringUTF(i2p::android::start().c_str()); +} + +JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon + (JNIEnv * env, jclass clazz) { + i2p::android::stop(); +} + +JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels + (JNIEnv * env, jclass clazz) { + i2p::context.SetAcceptsTunnels (false); +} + +JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged + (JNIEnv * env, jclass clazz, jboolean isConnected) +{ + bool isConnectedBool = (bool) isConnected; + i2p::transport::transports.SetOnline (isConnectedBool); +} diff --git a/android/jni/org_purplei2p_i2pd_I2PD_JNI.h b/android/jni/org_purplei2p_i2pd_I2PD_JNI.h new file mode 100644 index 00000000..04923d22 --- /dev/null +++ b/android/jni/org_purplei2p_i2pd_I2PD_JNI.h @@ -0,0 +1,33 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_purplei2p_i2pd_I2PD_JNI */ + +#ifndef _Included_org_purplei2p_i2pd_I2PD_JNI +#define _Included_org_purplei2p_i2pd_I2PD_JNI +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_purplei2p_i2pd_I2PD_JNI + * Method: stringFromJNI + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_getABICompiledWith + (JNIEnv *, jclass); + +JNIEXPORT jstring JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_startDaemon + (JNIEnv *, jclass); + +JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopDaemon + (JNIEnv *, jclass); + +JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_stopAcceptingTunnels + (JNIEnv *, jclass); + +JNIEXPORT void JNICALL Java_org_purplei2p_i2pd_I2PD_1JNI_onNetworkStateChanged + (JNIEnv * env, jclass clazz, jboolean isConnected); + +#ifdef __cplusplus +} +#endif +#endif