Browse Source

node.networkConfig() now creates ArrayLists of multicast subscriptions and assigned addresses

Signed-off-by: Grant Limberg <[email protected]>
Grant Limberg 10 years ago
parent
commit
7f6556eba0

+ 155 - 11
java/jni/ZT1_jniutils.cpp

@@ -1,9 +1,21 @@
 #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
@@ -172,30 +184,162 @@ jobject createVirtualNetworkType(JNIEnv *env, ZT1_VirtualNetworkType type)
     vntypeObject = env->GetStaticObjectField(vntypeClass, enumField);
     return vntypeObject;
 }
-    
+
 jobject newArrayList(JNIEnv *env)
 {
-    return NULL;
-}
+    if(arrayListClass == NULL)
+    {
+        arrayListClass = env->FindClass("java/util/ArrayList");
+        if(arrayListClass == NULL)
+        {
+            return NULL;
+        }
+    }
 
-jobject appendItemToArrayList(JNIEnv *env, jobject object)
-{
-    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;
 }
 
-jobject newIPV6Address(JNIEnv *env, char *addr)
+bool appendItemToArrayList(JNIEnv *env, jobject array, jobject object)
 {
-    return NULL;
+    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 newIPV4Address(JNIEnv *env, char *addr)
+jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr)
 {
-    return NULL;
+    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)
 {
-    return NULL;
+    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

+ 3 - 3
java/jni/ZT1_jniutils.h

@@ -9,13 +9,13 @@ extern "C" {
 
 jobject createResultObject(JNIEnv *env, ZT1_ResultCode code);
 jobject createVirtualNetworkStatus(JNIEnv *env, ZT1_VirtualNetworkStatus status);
+jobject createVirtualNetworkType(JNIEnv *env, ZT1_VirtualNetworkType type);
 jobject createEvent(JNIEnv *env, ZT1_Event event);
 
 jobject newArrayList(JNIEnv *env);
-jobject appendItemToArrayList(JNIEnv *env, jobject object);
+bool appendItemToArrayList(JNIEnv *env, jobject array, jobject object);
 
-jobject newIPV6Address(JNIEnv *env, char *addr);
-jobject newIPV4Address(JNIEnv *env, char *addr);
+jobject newInetAddress(JNIEnv *env, const sockaddr_storage &addr);
 
 jobject newMulticastGroup(JNIEnv *env, const ZT1_MulticastGroup &mc);
 #ifdef __cplusplus

+ 15 - 4
java/jni/com_zerotierone_sdk_Node.cpp

@@ -933,16 +933,27 @@ JNIEXPORT jobject JNICALL Java_com_zerotierone_sdk_Node_networkConfig
     env->SetBooleanField(vnetConfigObj, portErrorField, vnetConfig->portError);
 
 
-    jobject mcastSubsArrayObj = NULL;
-    jobject assignedAddrArrayObj = NULL;
+    jobject mcastSubsArrayObj = newArrayList(env);
+    for(unsigned int i = 0; i < vnetConfig->multicastSubscriptionCount; ++i)
+    {
+        jobject mcastObj = newMulticastGroup(env, vnetConfig->multicastSubscriptions[i]);
+        appendItemToArrayList(env, mcastSubsArrayObj, mcastObj);
+    }
+    env->SetObjectField(vnetConfigObj, multicastSubscriptionsField, mcastSubsArrayObj);
 
 
-    env->SetObjectField(vnetConfigObj, multicastSubscriptionsField, mcastSubsArrayObj);
+    jobject assignedAddrArrayObj = newArrayList(env);
+    for(unsigned int i = 0; i < vnetConfig->assignedAddressCount; ++i)
+    {
+        jobject inetAddrObj = newInetAddress(env, vnetConfig->assignedAddresses[i]);
+        appendItemToArrayList(env, assignedAddrArrayObj, inetAddrObj);
+    }
+
     env->SetObjectField(vnetConfigObj, assignedAddressesField, assignedAddrArrayObj);
 
     ZT1_Node_freeQueryResult(node, vnetConfig);
     vnetConfig = NULL;
-    
+
     return vnetConfigObj;
 }
 

+ 2 - 0
java/src/com/zerotierone/sdk/MulticastGroup.java

@@ -28,6 +28,8 @@ package com.zerotierone.sdk;
 
 
 public class MulticastGroup {
+    private MulticastGroup() {}
+
     private long mac;
     private long adi;
 }