| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627 | #include "ZT1_jniutils.h"#include <string>#include <assert.h>#ifdef __cplusplusextern "C" {#endifnamespace{    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 createPeerRole(JNIEnv *env, ZT1_PeerRole role){    static jclass peerRoleClass = NULL;    jobject peerRoleObject = NULL;    if(peerRoleClass == NULL)    {        peerRoleClass = env->FindClass("com/zerotierone/sdk/PeerRole");        if(peerRoleClass == NULL)        {            return NULL;        }    }    std::string fieldName;    switch(role)    {    case ZT1_PEER_ROLE_LEAF:        fieldName = "PEER_ROLE_LEAF";        break;    case ZT1_PEER_ROLE_HUB:        fieldName = "PEER_ROLE_HUB";        break;    case ZT1_PEER_ROLE_SUPERNODE:        fieldName = "PEER_ROLE_SUPERNODE";        break;    }    jfieldID enumField = env->GetStaticFieldID(peerRoleClass, fieldName.c_str(), "Lcom/zerotierone/sdk/PeerRole;");    peerRoleObject = env->GetStaticObjectField(peerRoleClass, enumField);    return peerRoleObject;}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;}jobject newPeerPhysicalPath(JNIEnv *env, const ZT1_PeerPhysicalPath &ppp){    static jclass pppClass = NULL;    static jfieldID addressField = NULL;    static jfieldID lastSendField = NULL;    static jfieldID lastReceiveField = NULL;    static jfieldID fixedField = NULL;    static jfieldID activeField = NULL;    static jfieldID preferredField = NULL;    static jmethodID ppp_constructor = NULL;    if(pppClass == NULL)    {        pppClass = env->FindClass("com/zerotierone/sdk/PeerPhysicalPath");        if(pppClass == NULL)        {            return NULL;        }    }    if(addressField == NULL)    {        addressField = env->GetFieldID(pppClass, "address", "Ljava/net/InetAddress;");        if(addressField == NULL)        {            return NULL;        }    }    if(lastSendField == NULL)    {        lastSendField = env->GetFieldID(pppClass, "lastSend", "J");        if(lastSendField == NULL)        {            return NULL;        }    }    if(lastReceiveField == NULL)    {        lastReceiveField = env->GetFieldID(pppClass, "lastReceive", "J");        if(lastReceiveField == NULL)        {            return NULL;        }    }    if(fixedField == NULL)    {        fixedField = env->GetFieldID(pppClass, "fixed", "Z");        if(fixedField == NULL)        {            return NULL;        }    }    if(activeField == NULL)    {        activeField = env->GetFieldID(pppClass, "active", "Z");        if(activeField == NULL)        {            return NULL;        }    }    if(preferredField == NULL)    {        preferredField = env->GetFieldID(pppClass, "preferred", "Z");        if(preferredField == NULL)        {            return NULL;        }    }    if(ppp_constructor == NULL)    {        ppp_constructor = env->GetMethodID(pppClass, "<init>", "()V");        if(ppp_constructor == NULL)        {            return NULL;        }    }    jobject pppObject = env->NewObject(pppClass, ppp_constructor);    if(pppObject == NULL)    {        return NULL; // out of memory    }    jobject addressObject = newInetAddress(env, ppp.address);    env->SetObjectField(pppClass, addressField, addressObject);    env->SetLongField(pppClass, lastSendField, ppp.lastSend);    env->SetLongField(pppClass, lastReceiveField, ppp.lastReceive);    env->SetBooleanField(pppClass, fixedField, ppp.fixed);    env->SetBooleanField(pppClass, activeField, ppp.active);    env->SetBooleanField(pppClass, preferredField, ppp.preferred);    return pppObject;}jobject newPeer(JNIEnv *env, const ZT1_Peer &peer) {    static jclass peerClass = NULL;    static jfieldID addressField = NULL;    static jfieldID lastUnicastFrameField = NULL;    static jfieldID lastMulticastFrameField = NULL;    static jfieldID versionMajorField = NULL;    static jfieldID versionMinorField = NULL;    static jfieldID versionRevField = NULL;    static jfieldID latencyField = NULL;    static jfieldID roleField = NULL;    static jfieldID pathsField = NULL;    static jmethodID peer_constructor = NULL;    if(peerClass == NULL)    {        peerClass = env->FindClass("com/zerotierone/sdk/Peer");        if(peerClass == NULL)        {            return NULL;        }    }    if(addressField == NULL)    {        addressField = env->GetFieldID(peerClass, "address", "J");        if(addressField == NULL)        {            return NULL;        }    }    if(lastUnicastFrameField == NULL)    {        lastUnicastFrameField = env->GetFieldID(peerClass, "lastUnicastFrame", "J");        if(lastUnicastFrameField == NULL)        {            return NULL;        }    }    if(lastMulticastFrameField == NULL)    {        lastMulticastFrameField = env->GetFieldID(peerClass, "lastMulticastFrame", "J");        if(lastMulticastFrameField == NULL)        {            return NULL;        }    }    if(versionMajorField == NULL)    {        versionMajorField = env->GetFieldID(peerClass, "versionMajor", "I");        if(versionMajorField == NULL)        {            return NULL;        }    }    if(versionMinorField == NULL)    {        versionMinorField = env->GetFieldID(peerClass, "versionMinor", "I");        if(versionMinorField == NULL)        {            return NULL;        }    }    if(versionRevField == NULL)    {        versionRevField = env->GetFieldID(peerClass, "versionRev", "I");        if(versionRevField == NULL)        {            return NULL;        }    }    if(latencyField == NULL)    {        latencyField = env->GetFieldID(peerClass, "latency", "I");        if(latencyField == NULL)        {            return NULL;        }    }    if(roleField == NULL)    {        roleField = env->GetFieldID(peerClass, "role", "Lcom/zerotierone/sdk/PeerRole;");        if(roleField == NULL)        {            return NULL;        }    }    if(pathsField == NULL)    {        pathsField = env->GetFieldID(peerClass, "paths", "Ljava.util.ArrayList;");        if(pathsField == NULL)        {            return NULL;        }    }    if(peer_constructor == NULL)    {        peer_constructor = env->GetMethodID(peerClass, "<init>", "()V");        if(peer_constructor == NULL)        {            return NULL;        }    }    jobject peerObject = env->NewObject(peerClass, peer_constructor);    if(peerObject == NULL)    {        return NULL; // out of memory    }    env->SetLongField(peerClass, addressField, (jlong)peer.address);    env->SetLongField(peerClass, lastUnicastFrameField, (jlong)peer.lastUnicastFrame);    env->SetLongField(peerClass, lastMulticastFrameField, (jlong)peer.lastMulticastFrame);    env->SetIntField(peerClass, versionMajorField, peer.versionMajor);    env->SetIntField(peerClass, versionMinorField, peer.versionMinor);    env->SetIntField(peerClass, versionRevField, peer.versionRev);    env->SetIntField(peerClass, latencyField, peer.latency);    env->SetObjectField(peerClass, roleField, createPeerRole(env, peer.role));    jobject arrayObject = newArrayList(env);    for(unsigned int i = 0; i < peer.pathCount; ++i)    {        jobject path = newPeerPhysicalPath(env, peer.paths[i]);        appendItemToArrayList(env, arrayObject, path);    }    env->SetObjectField(peerClass, pathsField, arrayObject);    return peerObject;}#ifdef __cplusplus}#endif
 |