diff options
Diffstat (limited to 'java/jni/ZT1_jniutils.cpp')
-rw-r--r-- | java/jni/ZT1_jniutils.cpp | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/java/jni/ZT1_jniutils.cpp b/java/jni/ZT1_jniutils.cpp new file mode 100644 index 00000000..87340f12 --- /dev/null +++ b/java/jni/ZT1_jniutils.cpp @@ -0,0 +1,347 @@ +#include "ZT1_jniutils.h" +#include <string> +#include <assert.h> + +#ifdef __cplusplus +extern "C" { +#endif + +namespace +{ + static jclass arrayListClass = NULL; + static jmethodID arrayList_constructor = NULL; + static jmethodID arrayList_add = NULL; + + static jclass inetAddressClass = NULL; + static jmethodID inetAddress_getByAddress = NULL; +} + +jobject createResultObject(JNIEnv *env, ZT1_ResultCode code) +{ + // cache the class so we don't have to + // look it up every time we need to create a java + // ResultCode object + static jclass resultClass = NULL; + + jobject resultObject = NULL; + + if(resultClass == NULL) + { + resultClass = env->FindClass("com/zerotierone/sdk/ResultCode"); + if(resultClass == NULL) + { + return NULL; // exception thrown + } + } + + std::string fieldName; + switch(code) + { + case ZT1_RESULT_OK: + fieldName = "ZT1_RESULT_OK"; + break; + case ZT1_RESULT_FATAL_ERROR_OUT_OF_MEMORY: + fieldName = "ZT1_RESULT_FATAL_ERROR_OUT_OF_MEMORY"; + break; + case ZT1_RESULT_FATAL_ERROR_DATA_STORE_FAILED: + fieldName = "ZT1_RESULT_FATAL_ERROR_DATA_STORE_FAILED"; + break; + case ZT1_RESULT_ERROR_NETWORK_NOT_FOUND: + fieldName = "ZT1_RESULT_ERROR_NETWORK_NOT_FOUND"; + break; + case ZT1_RESULT_FATAL_ERROR_INTERNAL: + default: + fieldName = "ZT1_RESULT_FATAL_ERROR_INTERNAL"; + break; + } + + jfieldID enumField = env->GetStaticFieldID(resultClass, fieldName.c_str(), "Lcom/zerotierone/sdk/ResultCode;"); + + resultObject = env->GetStaticObjectField(resultClass, enumField); + + return resultObject; +} + + +jobject createVirtualNetworkStatus(JNIEnv *env, ZT1_VirtualNetworkStatus status) +{ + static jclass statusClass = NULL; + + jobject statusObject = NULL; + + if(statusClass == NULL) + { + statusClass = env->FindClass("com/zerotierone/sdk/VirtualNetworkStatus"); + if(statusClass == NULL) + { + return NULL; // exception thrown + } + } + + std::string fieldName; + switch(status) + { + case ZT1_NETWORK_STATUS_REQUESTING_CONFIGURATION: + fieldName = "NETWORK_STATUS_REQUESTING_CONFIGURATION"; + break; + case ZT1_NETWORK_STATUS_OK: + fieldName = "NETWORK_STATUS_OK"; + break; + case ZT1_NETWORK_STATUS_ACCESS_DENIED: + fieldName = "NETWORK_STATUS_ACCESS_DENIED"; + break; + case ZT1_NETWORK_STATUS_NOT_FOUND: + fieldName = "NETWORK_STATUS_NOT_FOUND"; + break; + case ZT1_NETWORK_STATUS_PORT_ERROR: + fieldName = "NETWORK_STATUS_PORT_ERROR"; + break; + case ZT1_NETWORK_STATUS_CLIENT_TOO_OLD: + fieldName = "NETWORK_STATUS_CLIENT_TOO_OLD"; + break; + } + + jfieldID enumField = env->GetStaticFieldID(statusClass, fieldName.c_str(), "Lcom/zerotierone/sdk/VirtualNetworkStatus;"); + + statusObject = env->GetStaticObjectField(statusClass, enumField); + + return statusObject; +} + +jobject createEvent(JNIEnv *env, ZT1_Event event) +{ + static jclass eventClass = NULL; + jobject eventObject = NULL; + + if(eventClass == NULL) + { + eventClass = env->FindClass("com/zerotierone/sdk/Event"); + if(eventClass == NULL) + { + return NULL; + } + } + + std::string fieldName; + switch(event) + { + case ZT1_EVENT_UP: + fieldName = "EVENT_UP"; + break; + case ZT1_EVENT_OFFLINE: + fieldName = "EVENT_OFFLINE"; + break; + case ZT1_EVENT_DOWN: + fieldName = "EVENT_DOWN"; + break; + case ZT1_EVENT_FATAL_ERROR_IDENTITY_COLLISION: + fieldName = "EVENT_FATAL_ERROR_IDENTITY_COLLISION"; + break; + case ZT1_EVENT_AUTHENTICATION_FAILURE: + fieldName = "EVENT_AUTHENTICATION_FAILURE"; + break; + case ZT1_EVENT_INVALID_PACKET: + fieldName = "EVENT_INVALID_PACKET"; + break; + case ZT1_EVENT_TRACE: + fieldName = "EVENT_TRACE"; + break; + } + + jfieldID enumField = env->GetStaticFieldID(eventClass, fieldName.c_str(), "Lcom/zerotierone/sdk/Event;"); + + eventObject = env->GetStaticObjectField(eventClass, enumField); + + return eventObject; +} + +jobject createVirtualNetworkType(JNIEnv *env, ZT1_VirtualNetworkType type) +{ + static jclass vntypeClass = NULL; + jobject vntypeObject = NULL; + + if(vntypeClass == NULL) + { + vntypeClass = env->FindClass("com/zerotierone/sdk/VirtualNetworkType"); + if(vntypeClass == NULL) + { + return NULL; + } + } + + std::string fieldName; + switch(type) + { + case ZT1_NETWORK_TYPE_PRIVATE: + fieldName = "NETWORK_TYPE_PRIVATE"; + break; + case ZT1_NETWORK_TYPE_PUBLIC: + fieldName = "NETWORK_TYPE_PUBLIC"; + break; + } + + jfieldID enumField = env->GetStaticFieldID(vntypeClass, fieldName.c_str(), "Lcom/zerotierone/sdk/VirtyalNetworkType;"); + vntypeObject = env->GetStaticObjectField(vntypeClass, enumField); + return vntypeObject; +} + +jobject newArrayList(JNIEnv *env) +{ + if(arrayListClass == NULL) + { + arrayListClass = env->FindClass("java/util/ArrayList"); + if(arrayListClass == NULL) + { + return NULL; + } + } + + if(arrayList_constructor == NULL) + { + arrayList_constructor = env->GetMethodID( + arrayListClass, "<init>", "()V"); + if(arrayList_constructor == NULL) + { + return NULL; + } + } + + jobject arrayListObj = env->NewObject(arrayListClass, arrayList_constructor); + + return arrayListObj; +} + +bool appendItemToArrayList(JNIEnv *env, jobject array, jobject object) +{ + assert(array != NULL); + assert(object != NULL); + + if(arrayList_add == NULL) + { + arrayList_add = env->GetMethodID(arrayListClass, "add", "(Ljava.lang.Object;)Z"); + if(arrayList_add == NULL) + { + return false; + } + } + + return env->CallBooleanMethod(array, arrayList_add, object); +} + +jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr) +{ + if(inetAddressClass == NULL) + { + inetAddressClass = env->FindClass("java/net/InetAddress"); + if(inetAddressClass == NULL) + { + return NULL; + } + } + + if(inetAddress_getByAddress == NULL) + { + inetAddress_getByAddress = env->GetStaticMethodID( + inetAddressClass, "getByAddress", "([B)Ljava/net/InetAddress;"); + if(inetAddress_getByAddress == NULL) + { + return NULL; + } + } + + jobject inetAddressObj = NULL; + switch(addr.ss_family) + { + case AF_INET6: + { + sockaddr_in6 *ipv6 = (sockaddr_in6*)&addr; + jbyteArray buff = env->NewByteArray(16); + if(buff == NULL) + { + return NULL; + } + + env->SetByteArrayRegion(buff, 0, 16, (jbyte*)ipv6->sin6_addr.s6_addr); + inetAddressObj = env->CallStaticObjectMethod( + inetAddressClass, inetAddress_getByAddress, buff); + } + break; + case AF_INET: + { + sockaddr_in *ipv4 = (sockaddr_in*)&addr; + jbyteArray buff = env->NewByteArray(4); + if(buff == NULL) + { + return NULL; + } + + env->SetByteArrayRegion(buff, 0, 4, (jbyte*)&ipv4->sin_addr); + inetAddressObj = env->CallStaticObjectMethod( + inetAddressClass, inetAddress_getByAddress, buff); + } + break; + } + + return inetAddressObj; +} + +jobject newMulticastGroup(JNIEnv *env, const ZT1_MulticastGroup &mc) +{ + static jclass multicastGroupClass = NULL; + static jmethodID multicastGroup_constructor = NULL; + + static jfieldID macField = NULL; + static jfieldID adiField = NULL; + + if(multicastGroupClass == NULL) + { + multicastGroupClass = env->FindClass("com/zerotierone/sdk/MulticastGroup"); + if(multicastGroupClass == NULL) + { + return NULL; + } + } + + if(multicastGroup_constructor == NULL) + { + multicastGroup_constructor = env->GetMethodID( + multicastGroupClass, "<init>", "()V"); + if(multicastGroup_constructor == NULL) + { + return NULL; + } + } + + jobject multicastGroupObj = env->NewObject(multicastGroupClass, multicastGroup_constructor); + if(multicastGroupObj == NULL) + { + return NULL; + } + + if(macField == NULL) + { + macField = env->GetFieldID(multicastGroupClass, "mac", "J"); + if(macField == NULL) + { + return NULL; + } + } + + if(adiField == NULL) + { + adiField = env->GetFieldID(multicastGroupClass, "adi", "J"); + if(adiField == NULL) + { + return NULL; + } + } + + env->SetLongField(multicastGroupObj, macField, mc.mac); + env->SetLongField(multicastGroupObj, adiField, mc.adi); + + return multicastGroupObj; +} + +#ifdef __cplusplus +} +#endif
\ No newline at end of file |