#include #include #include #include #include "securec.h" #include "softbus_bus_center.h" #include "com_jg_softbus_naservice_LNNService.h" static INodeStateCb g_stateCb; // 全局变量,用于保存Java虚拟机的引用 JavaVM *jvm; //全局引用变量,用于保存java对象 jobject lNNCallback; jobject leaveCallback; jobject nodeStateCb; int parseConnectAddr(JNIEnv *env, jobject targetAddr, ConnectionAddr *addr) { jclass addrClass = (*env)->GetObjectClass(env, targetAddr); //地址类型 jmethodID getAddrTypeMethod = (*env)->GetMethodID(env, addrClass, "getType", "()Lcom/jg/softbus/network/protocol/ConnectionAddrType;"); jobject addrType = (*env)->CallObjectMethod(env, targetAddr, getAddrTypeMethod); jclass addrTypeClass = (*env)->GetObjectClass(env, addrType); jmethodID getModeMethod = (*env)->GetMethodID(env, addrTypeClass, "valueOf", "()I"); jint type = (*env)->CallIntMethod(env, addrType, getModeMethod); addr->type = type; printf("addr->peerUid:%d\n", addr->type); (*env)->DeleteLocalRef(env, addrType); //开始解析写入info对象 jmethodID getInfoMethod = (*env)->GetMethodID(env, addrClass, "getInfo", "()Lcom/jg/softbus/network/protocol/ConnectionAddrInfo;"); jobject addrInfo = (*env)->CallObjectMethod(env, targetAddr, getInfoMethod); if(addrInfo != NULL) { //解析infoclass jclass addrInfoClass = (*env)->GetObjectClass(env, addrInfo); //获取getBr jmethodID getBrMethod = (*env)->GetMethodID(env, addrInfoClass, "getBr", "()Lcom/jg/softbus/network/protocol/BrAddr;"); jobject brAddr = (*env)->CallObjectMethod(env, addrInfo, getBrMethod); if (brAddr != NULL) { jclass brAddrClass = (*env)->GetObjectClass(env, brAddr); //获取getBrMac jmethodID getBrMacMethod = (*env)->GetMethodID(env, brAddrClass, "getBrMac", "()Ljava/lang/String;"); jstring brMac = (*env)->CallObjectMethod(env, brAddr, getBrMacMethod); if(brMac != NULL) { const char *brMacStr = (*env)->GetStringUTFChars(env, brMac, 0); if (brMacStr != NULL) { // 获取字符串长度 jsize length = (*env)->GetStringUTFLength(env, brMac); // 将字符串转换为char数组 char brMacArray[length+1]; for (int i = 0; i < length; i++) { brMacArray[i] = brMacStr[i]; } // 添加字符串结束符 brMacArray[length] = '\0'; strcpy(addr->info.br.brMac, brMacArray); printf("addr->info.br.brMac:%s\n", brMacStr); } (*env)->ReleaseStringUTFChars(env, brMac, brMacStr); } } (*env)->DeleteLocalRef(env, brAddr); //获取BleAddr jmethodID getBleMethod = (*env)->GetMethodID(env, addrInfoClass, "getBle", "()Lcom/jg/softbus/network/protocol/BleAddr;"); jobject bleAddr = (*env)->CallObjectMethod(env, addrInfo, getBleMethod); if(bleAddr != NULL) { jclass bleAddrClass = (*env)->GetObjectClass(env, bleAddr); //获取getProtocol jmethodID getProtocolMethod = (*env)->GetMethodID(env, bleAddrClass, "getProtocol", "()Lcom/jg/softbus/network/protocol/BleProtocolType;"); // jobject protocol = (*env)->CallObjectMethod(env, bleAddr, getProtocolMethod); // if(protocol != NULL) { // jclass protocolClass = (*env)->GetObjectClass(env, protocol); // jmethodID getProtocolValueMethod = (*env)->GetMethodID(env, protocolClass, "valueOf", "()I"); // jint protocolValue = (*env)->CallIntMethod(env, protocol, getProtocolValueMethod); // addr->info.ble.protocol = protocolValue; // printf("addr->info.ble.protocol:%d\n", addr->info.ble.protocol); // } // (*env)->DeleteLocalRef(env, protocol); //获取bleMac jmethodID getBleMacMethod = (*env)->GetMethodID(env, bleAddrClass, "getBleMac", "()Ljava/lang/String;"); jstring bleMac = (*env)->CallObjectMethod(env, bleAddr, getBleMacMethod); if(bleMac != NULL) { const char *bleMacStr = (*env)->GetStringUTFChars(env, bleMac, 0); if (bleMac != NULL) { // 获取字符串长度 jsize length = (*env)->GetStringUTFLength(env, bleMac); // 将字符串转换为char数组 char bleMacArray[length+1]; for (int i = 0; i < length; i++) { bleMacArray[i] = bleMacStr[i]; } // 添加字符串结束符 bleMacArray[length] = '\0'; strcpy(addr->info.ble.bleMac, bleMacArray); printf("addr->info.ble.bleMac:%s\n", bleMacStr); } (*env)->ReleaseStringUTFChars(env, bleMac, bleMacStr); } //获取udidHash jmethodID getUdidHashMethod = (*env)->GetMethodID(env, bleAddrClass, "getUdidHash", "()[B"); jobject udidHashValue = (*env)->CallObjectMethod(env, bleAddr, getUdidHashMethod); if(udidHashValue != NULL) { jclass udidHashValueClass = (*env)->GetObjectClass(env, udidHashValue); jobject classObj = (*env)->ToReflectedMethod(env, udidHashValueClass, 0, 0); jclass classClass = (*env)->GetObjectClass(env, classObj); jmethodID mid = (*env)->GetMethodID(env, classClass, "getName", "()Ljava/lang/String;"); jstring className = (*env)->CallObjectMethod(env, classObj, mid); const char *classSig = (*env)->GetStringUTFChars(env, className, NULL); if (classSig[0] == '[') { jsize length = (*env)->GetArrayLength(env, udidHashValue); jbyteArray array = (*env)->NewByteArray(env, length); // 将数据复制到jArray中 jbyte *buffer = (*env)->GetByteArrayElements(env, array, NULL); if (buffer == NULL) { return -1; // 返回null表示失败 } for (jsize i = 0; i < length; i++) { // 从jobject中获取元素并复制到buffer中 buffer[i] = (uint8_t)((*env)->CallIntMethod(env, udidHashValue, (*env)->GetMethodID(env, udidHashValueClass, "get", "(I)B"), i)); } (*env)->ReleaseByteArrayElements(env, array, buffer, 0); // 释放本地引用 // 获取jbyteArray的指针和长度 jbyte *elements = (*env)->GetByteArrayElements(env, array, NULL); // 创建uint8_t数组 uint8_t udidHash[length]; // 将数据复制到uint8_t数组中 for (jsize i = 0; i < length; i++) { udidHash[i] = (uint8_t)elements[i]; printf("addr->info.ble.udidHash:%u", udidHash[i]); } printf("\n"); (*env)->ReleaseByteArrayElements(env, array, elements, 0); memcpy(addr->info.ble.udidHash, udidHash, sizeof(udidHash)); free(udidHash); } } (*env)->DeleteLocalRef(env, udidHashValue); //psm处理 // jmethodID getPsmMethod = (*env)->GetMethodID(env, bleAddrClass, "getPsm", "()I"); // jint psm = (*env)->CallIntMethod(env, bleAddr, getPsmMethod); // addr->info.ble.psm = psm; } //释放bleAddr引用 (*env)->DeleteLocalRef(env, bleAddr); jmethodID getIpMethod = (*env)->GetMethodID(env, addrInfoClass, "getIp", "()Lcom/jg/softbus/network/protocol/IpAddr;"); jobject ipAddr = (*env)->CallObjectMethod(env, addrInfo, getIpMethod); if(ipAddr != NULL) { jclass ipAddrClass = (*env)->GetObjectClass(env, ipAddr); //获取ip属性 jmethodID getIpMethod = (*env)->GetMethodID(env, ipAddrClass, "getIp", "()Ljava/lang/String;"); jstring ip = (*env)->CallObjectMethod(env, ipAddr, getIpMethod); if (ip != NULL) { const char *ipStr = (*env)->GetStringUTFChars(env, ip, 0); // 获取字符串长度 jsize length = (*env)->GetStringUTFLength(env, ip); // 将字符串转换为char数组 char ipArray[length+1]; for (int i = 0; i < length; i++) { ipArray[i] = ipStr[i]; } // 添加字符串结束符 ipArray[length] = '\0'; strcpy(addr->info.ip.ip, ipArray); printf("addr->info.ip.ip:%s\n", addr->info.ip.ip); (*env)->ReleaseStringUTFChars(env, ip, ipStr); } //获取端口port jmethodID getPortMethod = (*env)->GetMethodID(env, ipAddrClass, "getPort", "()I"); jint port = (*env)->CallIntMethod(env, ipAddr, getPortMethod); addr->info.ip.port = port; printf("addr->info.ip.port:%d\n", addr->info.ip.port); } //释放ipAddr引用 (*env)->DeleteLocalRef(env, ipAddr); //session处理 // jmethodID getSessionMethod = (*env)->GetMethodID(env, addrInfoClass, "getSession", "()Lcom/jg/softbus/network/protocol/SessionAddr;"); // jobject sessionAddr = (*env)->CallObjectMethod(env, addrInfo, getSessionMethod); // if(sessionAddr != NULL) { // jclass sessionClass = (*env)->GetObjectClass(env, sessionAddr); // //获取sessionId属性 // jmethodID getSessionIdMethod = (*env)->GetMethodID(env, sessionClass, "getSessionId", "()I"); // jint sessionId = (*env)->CallIntMethod(env, sessionAddr, getSessionIdMethod); // addr->info.session.sessionId = sessionId; // printf("addr->info.session.sessionId:%d\n", addr->info.session.sessionId); // //获取channelId // jmethodID getChannelIdMethod = (*env)->GetMethodID(env, sessionClass, "getChannelId", "()I"); // jint channelId = (*env)->CallIntMethod(env, sessionAddr, getChannelIdMethod); // addr->info.session.channelId = channelId; // printf("addr->info.session.channelId:%d\n", addr->info.session.channelId); // //获取type属性 // jmethodID getTypeMethod = (*env)->GetMethodID(env, sessionClass, "getType", "()I"); // jint type = (*env)->CallIntMethod(env, sessionAddr, getTypeMethod); // addr->info.session.type = type; // printf("addr->info.session.type:%d\n", addr->info.session.type); // } // //释放sessionAddr引用 // (*env)->DeleteLocalRef(env, sessionAddr); // } //开始解析peerUid jmethodID getPeerUidMethod = (*env)->GetMethodID(env, addrClass, "getPeerUid", "()Ljava/lang/String;"); jstring peerUid = (*env)->CallObjectMethod(env, targetAddr, getPeerUidMethod); if (peerUid != NULL) { const char *peerUidStr = (*env)->GetStringUTFChars(env, peerUid, 0); // 获取字符串长度 jsize length = (*env)->GetStringUTFLength(env, peerUid); // 将字符串转换为char数组 char cArray[length+1]; for (int i = 0; i < length; i++) { cArray[i] = peerUidStr[i]; } // 添加字符串结束符 cArray[length] = '\0'; strcpy(addr->peerUid, cArray); printf("addr->peerUid:%s\n", addr->peerUid); // 释放C字符串的内存 (*env)->ReleaseStringUTFChars(env, peerUid, peerUidStr); } return 0; } return -1; } /** * 将c结构ConnectionAddr转换为java的object对象 */ jobject parseAddrToJava(JNIEnv *env, const ConnectionAddr *addr) { //发现ConnectionAddr的java类 jclass connectionAddrClass = (*env)->FindClass(env, "com/jg/softbus/network/protocol/ConnectionAddr"); if (connectionAddrClass == NULL) { // 处理错误 printf("Cannot found the class:com/jg/softbus/network/protocol/ConnectionAddr"); return NULL; } //发现com.jg.softbus.network.protocol.ConnectionAddrType java类,根据其提供的静态getForValue(int)方法获取ConnectionAddrType对象 jclass connectionAddrTypeClass = (*env)->FindClass(env, "com/jg/softbus/network/protocol/ConnectionAddrType"); if (connectionAddrTypeClass == NULL) { // 处理错误 printf("Cannot found the class:com/jg/softbus/network/protocol/ConnectionAddrType"); return NULL; } //查找com.jg.softbus.network.protocol.ConnectionAddrInfo jclass connectionAddrInfoClass = (*env)->FindClass(env, "com/jg/softbus/network/protocol/ConnectionAddrInfo"); if (connectionAddrInfoClass == NULL) { // 处理错误 printf("Cannot found the class:com/jg/softbus/network/protocol/ConnectionAddrInfo"); return NULL; } //查找ConnectionAddrInfo的无参构造函数 jmethodID connectionAddrInfoConstructor = (*env)->GetMethodID(env, connectionAddrInfoClass, "", "()V"); if (connectionAddrInfoConstructor == NULL) { // 处理错误 printf("Cannot found the constructor:com/jg/softbus/network/protocol/ConnectionAddrInfo"); return NULL; } //查找com.jg.softbus.network.protocol.IpAddr的java对象 jclass ipAddrClass = (*env)->FindClass(env, "com/jg/softbus/network/protocol/IpAddr"); if(ipAddrClass == NULL){ printf("Cannot found the IpAddr class."); return NULL; } //查找IpAddr带参构造函数,函数结构为:IpAddr(String ip, int port) jmethodID ipAddrConstructor = (*env)->GetMethodID(env, ipAddrClass, "", "(Ljava/lang/String;I)V"); if(ipAddrConstructor == NULL){ printf("Cannot found the constructor of IpAddr."); return NULL; } //查找com.jg.softbus.network.protocol.BrAddr的java对象 jclass brAddrClass = (*env)->FindClass(env, "com/jg/softbus/network/protocol/BrAddr"); if(brAddrClass == NULL){ printf("Cannot found the BrAddr class."); return NULL; } //查找BrAddr带参构造函数,函数结构为:BrAddr(String brMac) jmethodID brAddrConstructor = (*env)->GetMethodID(env, brAddrClass, "", "(Ljava/lang/String)V"); if(brAddrConstructor == NULL){ printf("Cannot found the constructor of BrAddr."); return NULL; } //查找com.jg.softbus.network.protocol.BleAddr的java对象 jclass bleAddrClass = (*env)->FindClass(env, "com/jg/softbus/network/protocol/BleAddr"); if(bleAddrClass == NULL){ printf("Cannot found the BleAddr class."); return NULL; } //查找BleAddr无参构造函数,函数结构为:BleAddr() jmethodID bleAddrConstructor = (*env)->GetMethodID(env, bleAddrClass, "", "()V"); if(bleAddrConstructor == NULL){ printf("Cannot found the constructor of BleAddr."); return NULL; } //查找com.jg.softbus.network.protocol.BleProtocolType的java对象 // jclass bleProtocolTypeClass = (*env)->FindClass(env, "com/jg/softbus/network/protocol/BleProtocolType"); // if(bleProtocolTypeClass == NULL){ // printf("Cannot found the BleProtocolType class."); // return NULL; // } //查找com/jg/softbus/network/protocol/SessionAddr的java对象 // jclass sessionAddrClass = (*env)->FindClass(env, "com/jg/softbus/network/protocol/SessionAddr"); // if(sessionAddrClass == NULL){ // printf("Cannot found the SessionAddr class."); // return NULL; // } //查找SessionAddr无参构造函数,函数结构为:SessionAddr() // jmethodID sessionAddrConstructor = (*env)->GetMethodID(env, sessionAddrClass, "", "()V"); // if(sessionAddrConstructor == NULL){ // printf("Cannot found the constructor of SessionAddr."); // return NULL; // } //基于无参的构造函数创建ConnectionAddr对象 jmethodID connectionAddrConstructor = (*env)->GetMethodID(env, connectionAddrClass, "", "()V"); jobject addrObj = (*env)->NewObject(env, connectionAddrClass, connectionAddrConstructor); //获取ConnectionAddrType对象 jmethodID getForValueMethod = (*env)->GetStaticMethodID(env, connectionAddrTypeClass, "getForValue", "(I)Lcom/jg/softbus/network/protocol/ConnectionAddrType;"); if (getForValueMethod == NULL) { // 处理错误 printf("Cannot found the method:getForValue(int)"); return NULL; } //根据device提供的地址类型获取ConnectionAddrType对象 jobject addrTypeObj = (*env)->CallStaticObjectMethod(env, connectionAddrTypeClass, getForValueMethod, addr->type); if(addrTypeObj == NULL) { // 处理错误 printf("Cannot found the ConnectionAddrType. type info: %d", addr->type); return NULL; } //查找ConnectionAddr的setType(ConnectionAddrType type)方法 jmethodID setTypeMethod = (*env)->GetMethodID(env, connectionAddrClass, "setType", "(Lcom/jg/softbus/network/protocol/ConnectionAddrType;)V"); //设置地址类型到地址对象中 (*env)->CallVoidMethod(env, addrObj, setTypeMethod, addrTypeObj); (*env)->DeleteLocalRef(env, addrTypeObj); //无参创建ConnectionAddrInfo的java对象 jobject infoObj = (*env)->NewObject(env, connectionAddrInfoClass, connectionAddrInfoConstructor); //判断addr->type的类型,可参考下面代码的Switch方式 switch (addr->type) { case CONNECTION_ADDR_WLAN: { printf("ip=%s,port=%d,", addr->info.ip.ip, addr->info.ip.port); } case CONNECTION_ADDR_ETH: { jstring ipstr = (*env)->NewStringUTF(env, addr->info.ip.ip); //并使用有参构造函数进行初始化 jobject ipAddrObj = (*env)->NewObject(env, ipAddrClass, ipAddrConstructor, ipstr, addr->info.ip.port); //将地址对象写入ConnectionAddrInfo对象中 jmethodID setIpMethod = (*env)->GetMethodID(env, connectionAddrClass, "setIp", "(Lcom/jg/softbus/network/protocol/IpAddr;)V"); //设置地址类型到地址对象中 (*env)->CallVoidMethod(env, addrObj, setIpMethod, ipAddrObj); (*env)->DeleteLocalRef(env, ipAddrObj); break; } case CONNECTION_ADDR_BR: { jstring brMacStr = (*env)->NewStringUTF(env, addr->info.br.brMac); //并使用有参构造函数进行初始化 jobject brAddrObj = (*env)->NewObject(env, brAddrClass, brAddrConstructor, brMacStr); //将地址对象写入ConnectionAddrInfo对象中 jmethodID setBrMethod = (*env)->GetMethodID(env, connectionAddrClass, "setBr", "(Lcom/jg/softbus/network/protocol/BrAddr;)V"); //设置地址类型到地址对象中 (*env)->CallVoidMethod(env, addrObj, setBrMethod, brAddrObj); (*env)->DeleteLocalRef(env, brAddrObj); (*env)->DeleteLocalRef(env, brMacStr); break; } case CONNECTION_ADDR_BLE: { //并使用构造函数进行初始化 jobject bleAddrObj = (*env)->NewObject(env, bleAddrClass, bleAddrConstructor); // //获取BleProtocolType对象 // jmethodID getForValueMethod2 = (*env)->GetStaticMethodID(env, bleProtocolTypeClass, "getForValue", "(I)Lcom/jg/softbus/network/protocol/BleProtocolType;"); // if (getForValueMethod2 == NULL) { // // 处理错误 // printf("Cannot found the method:getForValue(int)"); // return NULL; // } // //根据device提供的bleprotocol类型获取BleProtocolType对象 // jobject bleProtocolTypeObj = (*env)->CallStaticObjectMethod(env, bleProtocolTypeClass, getForValueMethod2, addr->info.ble.protocol); // if(bleProtocolTypeObj == NULL) { // // 处理错误 // printf("Cannot found the BleProtocolType. type info: %d", addr->info.ble.protocol); // return NULL; // } // //将地址对象写入ConnectionAddrInfo对象中 // jmethodID setProtocolMethod = (*env)->GetMethodID(env, bleAddrClass, "setProtocol", "(Lcom/jg/softbus/network/protocol/BleProtocolType;)V"); // (*env)->CallVoidMethod(env, bleAddrObj, setProtocolMethod, bleProtocolTypeObj); // (*env)->DeleteLocalRef(env, bleProtocolTypeObj); //setbleMac jmethodID setBleMacMethod = (*env)->GetMethodID(env, bleAddrClass, "setBleMac", "(Ljava/lang/String)V"); jstring bleMac = (*env)->NewStringUTF(env, addr->info.ble.bleMac); (*env)->CallVoidMethod(env, bleAddrObj, setBleMacMethod, bleMac); (*env)->DeleteLocalRef(env, bleMac); //setUdidHash jmethodID setUdidHashMethod = (*env)->GetMethodID(env, bleAddrClass, "setUdidHash", "([B)V"); size_t len = UDID_HASH_LEN / sizeof(uint8_t); jbyteArray byteArray = (*env)->NewByteArray(env, len); (*env)->SetByteArrayRegion(env, byteArray, 0, len, (const jbyte*)addr->info.ble.udidHash); // 将udidHash转换为整数 // int hash_value = 0; // for (int k = 0; k < UDID_HASH_LEN; k++) { // hash_value = (hash_value << 8) + addr->info.ble.udidHash[k]; // } (*env)->CallVoidMethod(env, bleAddrObj, setUdidHashMethod, byteArray); (*env)->DeleteLocalRef(env, byteArray); // //setPsm // jmethodID setPsmMethod = (*env)->GetMethodID(env, bleAddrClass, "setPsm", "(I)V"); // (*env)->CallVoidMethod(env, bleAddrObj, setPsmMethod, addr->info.ble.psm); //将地址对象写入ConnectionAddrInfo对象中 jmethodID setBleMethod = (*env)->GetMethodID(env, connectionAddrClass, "setBle", "(Lcom/jg/softbus/network/protocol/BrAddr;)V"); (*env)->CallVoidMethod(env, addrObj, setBleMethod, bleAddrObj); (*env)->DeleteLocalRef(env, bleAddrObj); printf("bleMac=%s,", addr->info.ble.bleMac); break; } // case CONNECTION_ADDR_SESSION: // //创建SessionAddr对象 // jobject sessionAddrObj = (*env)->NewObject(env, sessionAddrClass, sessionAddrConstructor); // //获取void setSessionId(Integer sessionId)方法 // jmethodID setSessionIdMethod = (*env)->GetMethodID(env, sessionAddrClass, "setSessionId", "(I)V"); // //将device中的sessionId调用方法设置到sessionAddrObj中 // (*env)->CallVoidMethod(env, sessionAddrObj, setSessionIdMethod, addr->info.session.sessionId); // //获取void setChannelId(Integer channelId)方法 // jmethodID setChannelIdMethod = (*env)->GetMethodID(env, sessionAddrClass, "setChannelId", "(I)V"); // //将device中的channelId调用方法设置到sessionAddrObj中 // (*env)->CallVoidMethod(env, sessionAddrObj, setChannelIdMethod, addr->info.session.channelId); // //获取void setType(String type)方法 // jmethodID setTypeMethod = (*env)->GetMethodID(env, sessionAddrClass, "setType", "(Ljava/lang/String;)V"); // //将device中的type调用方法设置到sessionAddrObj中 // jstring sessionTypeStr = (*env)->NewStringUTF(env, addr->info.session.type); // (*env)->CallVoidMethod(env, sessionAddrObj, setTypeMethod, sessionTypeStr); // jmethodID setSessionMethod = (*env)->GetMethodID(env, connectionAddrClass, "setSession", "(Lcom/jg/softbus/network/protocol/SessionAddr;)V"); // (*env)->CallVoidMethod(env, addrObj, setSessionMethod, sessionAddrObj); // (*env)->DeleteLocalRef(env, sessionTypeStr); // (*env)->DeleteLocalRef(env, sessionAddrObj); // printf("sessionId=%d, channelId=%d, type=%d", addr->info.session.sessionId, addr->info.session.channelId, addr->info.session.type); // break; default: break; } //获取ConnectionAddr中的void setPeerUid(String peerUid)方法,将device中的peerUid放入到addrObj中 jmethodID setPeerUidMethod = (*env)->GetMethodID(env, connectionAddrClass, "setPeerUid", "(Ljava/lang/String;)V"); jstring peerUidStr = (*env)->NewStringUTF(env, addr->peerUid); (*env)->CallVoidMethod(env, addrObj, setPeerUidMethod, peerUidStr); (*env)->DeleteLocalRef(env, peerUidStr); return addrObj; } void onJoinLNNResult(ConnectionAddr *addr, const char *networkId, int32_t retCode) { // 获取JNIEnv环境 JNIEnv *env; // 将当前线程附加到Java虚拟机 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // 获取当前对象的类引用 jclass nativeLibClass = (*env)->GetObjectClass(env, lNNCallback); // 获取当前对象的publishSuccess方法的ID jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onJoinLNNResult", "(Lcom/jg/softbus/network/protocol/ConnectionAddr;Ljava/lang/String;I)V"); //将ConnectionAddr转换为java对应的对象 jobject addrObj = parseAddrToJava(env, addr); if(addrObj == NULL) { return; } jstring networkIdStr = (*env)->NewStringUTF(env, networkId); printf("callback the join event. networkId:%s", networkId); //调用回调方法执行 (*env)->CallVoidMethod(env, lNNCallback, callbackMethod, addrObj, networkIdStr, retCode); printf("callback the join event completed. networkId:%s", networkId); //删除本地对象 (*env)->DeleteLocalRef(env, addrObj); //将当前线程从java虚拟机中移除 (*jvm)->DetachCurrentThread(jvm); } /* * Class: com_jg_softbus_naservice_LNNService * Method: joinLNN * Signature: (Ljava/lang/String;Lcom/jg/softbus/network/protocol/ConnectionAddr;Lcom/jg/softbus/network/callback/ILNNCallback;)I */ JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_LNNService_joinLNN (JNIEnv *env, jobject obj, jstring pkgName, jobject targetAddr, jobject callback) { // 保存Java虚拟机的引用 (*env)->GetJavaVM(env, &jvm); lNNCallback = (*env)->NewGlobalRef(env, callback); //包名处理 const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL); ConnectionAddr addr; int ret = parseConnectAddr(env, targetAddr, &addr); if(ret !=0) { // 尝试进行一些可能会抛出异常的操作 jclass exceptionClass = (*env)->FindClass(env, "java/lang/Exception"); // 获取异常类 // 如果找不到异常类,则抛出异常 jmethodID exceptionConstructor = (*env)->GetMethodID(env, exceptionClass, "", "()V"); jthrowable exception = (*env)->NewObject(env, exceptionClass, exceptionConstructor); // 抛出异常 (*env)->ThrowNew(env, exceptionClass, "ConnectionAddr object error."); //解析失败无法继续操作 return -1; } printf("joinLNN start..."); ret = JoinLNN(pkgNameStr, &addr, onJoinLNNResult); printf("joinLNN completed..."); (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr); return ret; } /** * 离开网络回调函数 */ void onLeaveLNNResult(const char *networkId, int32_t retCode) { // 获取JNIEnv环境 JNIEnv *env; // 将当前线程附加到Java虚拟机 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // 获取当前对象的类引用 jclass nativeLibClass = (*env)->GetObjectClass(env, leaveCallback); // 获取当前对象的publishSuccess方法的ID jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onLeaveLNNResult", "(Ljava/lang/String;I)V"); jstring networkIdStr = (*env)->NewStringUTF(env, networkId); printf("callback the leave event. networkId:%s", networkId); //调用回调方法执行 (*env)->CallVoidMethod(env, lNNCallback, callbackMethod, networkIdStr, retCode); printf("callback the leave event completed. networkId:%s", networkId); //将当前线程从java虚拟机中移除 (*jvm)->DetachCurrentThread(jvm); } /* * Class: com_jg_softbus_naservice_LNNService * Method: leaveLNN * Signature: (Ljava/lang/String;Ljava/lang/String;Lcom/jg/softbus/network/callback/ILNNCallback;)I */ JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_LNNService_leaveLNN (JNIEnv *env, jobject obj, jstring pkgName, jstring networkId, jobject callback) { // 保存Java虚拟机的引用 (*env)->GetJavaVM(env, &jvm); leaveCallback = (*env)->NewGlobalRef(env, callback); //包名处理 const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL); const char *networkIdStr = (*env)->GetStringUTFChars(env, networkId, NULL); printf("leave start."); int ret = LeaveLNN(pkgNameStr, networkIdStr, onLeaveLNNResult); printf("leave completed."); (*env)->ReleaseStringUTFChars(env, networkId, networkIdStr); (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr); return ret; } /** * 转换NodeBasicInfo对象为java的对象 */ jobject parseNodeBasicInfoToJava(JNIEnv *env, NodeBasicInfo *info) { //创建java的DeviceInfo对象 jclass nodeBasicInfoClass = (*env)->FindClass(env, "com/jg/softbus/network/node/NodeBasicInfo"); if (nodeBasicInfoClass == NULL) { // 处理错误 printf("Cannot found the java class:com/jg/softbus/network/node/NodeBasicInfo"); return NULL; } jmethodID constructor = (*env)->GetMethodID(env, nodeBasicInfoClass, "", "(Ljava/lang/String;Ljava/lang/String;S)V"); if (constructor == NULL) { // 处理错误 printf("Cannot found the default constructor of NodeBasicInfo."); return NULL; } jstring networkId = (*env)->NewStringUTF(env, info->networkId); jstring deviceName = (*env)->NewStringUTF(env, info->deviceName); jobject nbInfoObj = (*env)->NewObject(env, nodeBasicInfoClass, constructor, networkId, deviceName, info->deviceTypeId); return nbInfoObj; } /** * 节点上线事件回调 */ void onNodeOnline(NodeBasicInfo *info) { // 获取JNIEnv环境 JNIEnv *env; // 将当前线程附加到Java虚拟机 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // 获取当前对象的类引用 jclass nativeLibClass = (*env)->GetObjectClass(env, nodeStateCb); // 获取当前对象的publishSuccess方法的ID jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onNodeOnline", "(Lcom/jg/softbus/network/node/NodeBasicInfo;)V"); //将NodeBasicInfo转换为java对应的对象 jobject nodeBasicInfoObj = parseNodeBasicInfoToJava(env, info); if(nodeBasicInfoObj == NULL) { return; } printf("listen the node online."); //调用回调方法执行 (*env)->CallVoidMethod(env, nodeStateCb, callbackMethod, nodeBasicInfoObj); printf("java listen node online completed."); //删除本地对象 (*env)->DeleteLocalRef(env, nodeBasicInfoObj); //将当前线程从java虚拟机中移除 (*jvm)->DetachCurrentThread(jvm); } /** * 节点下线事件回调 */ void onNodeOffline(NodeBasicInfo *info) { // 获取JNIEnv环境 JNIEnv *env; // 将当前线程附加到Java虚拟机 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // 获取当前对象的类引用 jclass nativeLibClass = (*env)->GetObjectClass(env, nodeStateCb); // 获取当前对象的publishSuccess方法的ID jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onNodeOffline", "(Lcom/jg/softbus/network/node/NodeBasicInfo;)V"); //将NodeBasicInfo转换为java对应的对象 jobject nodeBasicInfoObj = parseNodeBasicInfoToJava(env, info); if(nodeBasicInfoObj == NULL) { return; } printf("listen the node offline."); //调用回调方法执行 (*env)->CallVoidMethod(env, nodeStateCb, callbackMethod, nodeBasicInfoObj); printf("java listen node offline completed."); //删除本地对象 (*env)->DeleteLocalRef(env, nodeBasicInfoObj); //将当前线程从java虚拟机中移除 (*jvm)->DetachCurrentThread(jvm); } /** * 节点信息变化事件回调 */ void onNodeBasicInfoChanged(NodeBasicInfoType type, NodeBasicInfo *info) { // 获取JNIEnv环境 JNIEnv *env; // 将当前线程附加到Java虚拟机 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // 获取当前对象的类引用 jclass nativeLibClass = (*env)->GetObjectClass(env, nodeStateCb); // 获取当前对象的publishSuccess方法的ID jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onNodeBasicInfoChanged", "(Lcom/jg/softbus/network/node/NodeBasicInfoType;Lcom/jg/softbus/network/node/NodeBasicInfo;)V"); //将NodeBasicInfo转换为java对应的对象 jobject nodeBasicInfoObj = parseNodeBasicInfoToJava(env, info); if(nodeBasicInfoObj == NULL) { return; } //创建java的NodeBasicInfoType对象 jclass nodeBasicInfoTypeClass = (*env)->FindClass(env, "com/jg/softbus/network/node/NodeBasicInfoType"); if (nodeBasicInfoTypeClass == NULL) { // 处理错误 printf("Cannot found the java class:com/jg/softbus/network/node/NodeBasicInfoType"); return; } jmethodID getForValueMethod = (*env)->GetStaticMethodID(env, nodeBasicInfoTypeClass, "getForValue", "(I)Lcom/jg/softbus/network/node/NodeBasicInfoType;"); if (getForValueMethod == NULL) { // 处理错误 printf("Cannot found the static method:getForValue(int)"); return; } jobject nodeBasicInfoTypeObj = (*env)->CallStaticObjectMethod(env, nodeBasicInfoTypeClass, getForValueMethod, (int)type); if (nodeBasicInfoTypeObj == NULL) { // 处理错误 printf("Cannot found NodeBasicInfoType. the type is: %d", type); return; } printf("listen the node change."); //调用回调方法执行 (*env)->CallVoidMethod(env, nodeStateCb, callbackMethod, nodeBasicInfoTypeObj, nodeBasicInfoObj); printf("java listen node chagned completed."); //删除本地对象 (*env)->DeleteLocalRef(env, nodeBasicInfoObj); //删除本地对象 (*env)->DeleteLocalRef(env, nodeBasicInfoTypeObj); //将当前线程从java虚拟机中移除 (*jvm)->DetachCurrentThread(jvm); } /** * 将c的NodeStatus结构转换为java对应的对象 */ // jobject parseNodeStatusToJava(JNIEnv *env, NodeStatus *status) { // //创建java的NodeStatusType对象 // jclass nodeStatusClass = (*env)->FindClass(env, "com/jg/softbus/network/node/NodeStatus"); // if(nodeStatusClass == NULL) { // printf("Cannot found the java class:com/jg/softbus/network/node/NodeStatus"); // return NULL; // } // jmethodID constructor = (*env)->GetMethodID(env, nodeStatusClass, "", "()V"); // if (constructor == NULL) { // // 处理错误 // printf("Cannot found the default constructor of NodeStatus."); // return NULL; // } // jobject obj = (*env)->NewObject(env, nodeStatusClass, constructor); // if (obj == NULL) { // // 处理错误 // printf("Cannot create the NodeStatus object."); // return NULL; // } // //设置basicInfo // jmethodID setBasicInfoMethod = (*env)->GetMethodID(env, nodeStatusClass, "setBasicInfo", "(Lcom/jg/softbus/network/node/NodeBasicInfo;)V"); // jobject nodeBasicInfoObj = parseNodeBasicInfoToJava(env, status->basicInfo); // (*env)->CallVoidMethod(env, obj, setBasicInfoMethod, nodeBasicInfoObj); // (*env)->DeleteLocalRef(env, nodeBasicInfoObj); // //authStatus // jmethodID setAuthStatusMethod = (*env)->GetMethodID(env, nodeStatusClass, "setAuthStatus", "(S)V"); // (*env)->CallVoidMethod(env, obj, setAuthStatusMethod, status->authStatus); // //dataBaseStatus // jmethodID setDataBaseStatusMethod = (*env)->GetMethodID(env, nodeStatusClass, "setDataBaseStatus", "(S)V"); // (*env)->CallVoidMethod(env, obj, setDataBaseStatusMethod, status->dataBaseStatus); // //meshType // jmethodID setMeshTypeMethod = (*env)->GetMethodID(env, nodeStatusClass, "setMeshType", "(S)V"); // (*env)->CallVoidMethod(env, obj, setMeshTypeMethod, status->meshType); // //reserved // jmethodID setReservedMethod = (*env)->GetMethodID(env, nodeStatusClass, "setReserved", "([S)V"); // (*env)->CallVoidMethod(env, obj, setReservedMethod, (jshort*)status->meshType); // reutrn obj; // } /** * 设备运行状态变化事件回调 */ // void onNodeStatusChanged(NodeStatusType type, NodeStatus *status) { // // 获取JNIEnv环境 // JNIEnv *env; // // 将当前线程附加到Java虚拟机 // (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // // 获取当前对象的类引用 // jclass nativeLibClass = (*env)->GetObjectClass(env, nodeStateCb); // // 获取当前对象的publishSuccess方法的ID // jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onNodeStatusChanged", "(Lcom/jg/softbus/network/node/NodeStatusType;Lcom/jg/softbus/network/node/status;)V"); // //将NodeBasicInfo转换为java对应的对象 // jobject nodeStatusObj = parseNodeStatusToJava(status); // if(nodeStatusObj == NULL) { // return; // } // //创建java的NodeStatusType对象 // jclass nodeStatusTypeClass = (*env)->FindClass(env, "com/jg/softbus/network/node/NodeStatusType"); // if (nodeStatusTypeClass == NULL) { // // 处理错误 // printf("Cannot found the java class:com/jg/softbus/network/node/NodeStatusType"); // return; // } // jmethodID getForValueMethod = (*env)->GetStaticMethodID(env, nodeBasicInfoTypeClass, "getForValue", "(I)Lcom/jg/softbus/network/node/nodeStatusTypeClass;"); // if (getForValueMethod == NULL) { // // 处理错误 // printf("Cannot found the static method:getForValue(int)"); // return; // } // jobject nodeStatusTypeObj = (*env)->CallStaticObjectMethod(env, nodeStatusTypeClass, getForValueMethod, (int)type); // if (nodeStatusTypeObj == NULL) { // // 处理错误 // printf("Cannot found NodeStatusType. the type is: %d", type); // return; // } // printf("listen the node status change."); // //调用回调方法执行 // (*env)->CallVoidMethod(env, nodeStateCb, callbackMethod, nodeStatusTypeObj, nodeStatusObj); // printf("java listen node status chagned completed."); // //删除本地对象 // (*env)->DeleteLocalRef(env, nodeStatusObj); // //删除本地对象 // (*env)->DeleteLocalRef(env, nodeStatusTypeObj); // //将当前线程从java虚拟机中移除 // (*jvm)->DetachCurrentThread(jvm); // } /** * 创建全局回调对象 */ void createGlobalStateCb(JNIEnv *env, jobject nodeStateCallback) { //获取当前对象的类引用 jclass nscbClass = (*env)->GetObjectClass(env, nodeStateCallback); // 获取当前对象的getEvents方法的ID jmethodID getEventsMethod = (*env)->GetMethodID(env, nscbClass, "getEvents", "()I"); jint events = (*env)->CallIntMethod(env, nodeStateCallback, getEventsMethod); //监听有关所有事件 g_stateCb.events = events; g_stateCb.onNodeOffline = onNodeOffline; g_stateCb.onNodeOnline = onNodeOnline; g_stateCb.onNodeBasicInfoChanged = onNodeBasicInfoChanged; // g_stateCb.onNodeStatusChanged = onNodeStatusChanged; } /* * Class: com_jg_softbus_naservice_LNNService * Method: regNodeDeviceStateCb * Signature: (Ljava/lang/String;Lcom/jg/softbus/network/callback/INodeStateCb;)I */ JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_LNNService_regNodeDeviceStateCb (JNIEnv *env, jobject obj, jstring pkgName, jobject nodeStateCallback) { // 保存Java虚拟机的引用 (*env)->GetJavaVM(env, &jvm); nodeStateCb = (*env)->NewGlobalRef(env, nodeStateCallback); //包名处理 const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL); createGlobalStateCb(env, nodeStateCallback); int ret = RegNodeDeviceStateCb(pkgNameStr, &g_stateCb); (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr); return ret; } /* * Class: com_jg_softbus_naservice_LNNService * Method: unRegNodeDeviceStateCb * Signature: (Lcom/jg/softbus/network/callback/INodeStateCb;)I */ JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_LNNService_unRegNodeDeviceStateCb (JNIEnv *env, jobject obj, jobject nodeStateCallback) { // 保存Java虚拟机的引用 (*env)->GetJavaVM(env, &jvm); int ret = 0x00; if (&g_stateCb != NULL) { //注销事件 ret = UnregNodeDeviceStateCb(&g_stateCb); } return ret; } /* * Class: com_jg_softbus_naservice_LNNService * Method: destroy * Signature: ()V */ JNIEXPORT void JNICALL Java_com_jg_softbus_naservice_LNNService_destroy (JNIEnv *env, jobject obj) { // 删除全局引用 (*env)->DeleteGlobalRef(env, lNNCallback); (*env)->DeleteGlobalRef(env, leaveCallback); (*env)->DeleteGlobalRef(env, nodeStateCb); // free(jvm); }