#include #include #include #include #include "securec.h" #include "discovery_service.h" #include "softbus_bus_center.h" #include "com_jg_softbus_naservice_PublishService.h" // 全局变量,用于保存Java虚拟机的引用 JavaVM *jvm; //全局引用变量,用于保存java对象 jobject globalRef; /** * 解析对象为c的PublishInfo结构 */ int ParsePublishInfo(JNIEnv *env, jobject pInfo, PublishInfo *info) { jclass infoClass = (*env)->GetObjectClass(env, pInfo); // 获取publishId jmethodID getPublishIdMethod = (*env)->GetMethodID(env, infoClass, "getPublishId", "()I"); jint publishId = (*env)->CallIntMethod(env, pInfo, getPublishIdMethod); info->publishId = publishId; printf("PublishInfo->publishId:%d\n", publishId); //获取mode jmethodID getDiscoverModeMethod = (*env)->GetMethodID(env, infoClass, "getMode", "()Lcom/jg/softbus/discovery/enums/DiscoverMode;"); jobject modeInfo = (*env)->CallObjectMethod(env, pInfo, getDiscoverModeMethod); jclass modeClass = (*env)->GetObjectClass(env, modeInfo); jmethodID getModeMethod = (*env)->GetMethodID(env, modeClass, "valueOf", "()I"); jint mode = (*env)->CallIntMethod(env, modeInfo, getModeMethod); info->mode = mode; (*env)->DeleteLocalRef(env,modeInfo); printf("PublishInfo->mode:%d\n", mode); //获取medium jmethodID getMediumMethod = (*env)->GetMethodID(env, infoClass, "getMedium", "()Lcom/jg/softbus/discovery/enums/ExchangeMedium;"); jobject mediumInfo = (*env)->CallObjectMethod(env, pInfo, getMediumMethod); jclass mediumClass = (*env)->GetObjectClass(env, mediumInfo); jmethodID getMediumMethod2 = (*env)->GetMethodID(env, mediumClass, "valueOf", "()I"); jint medium = (*env)->CallIntMethod(env, mediumInfo, getMediumMethod2); info->medium = medium; (*env)->DeleteLocalRef(env, mediumInfo); printf("PublishInfo->medium:%d\n", medium); //获取freq频次 jmethodID getFreqMethod = (*env)->GetMethodID(env, infoClass, "getFreq", "()Lcom/jg/softbus/discovery/enums/ExchangeFreq;"); jobject freqInfo = (*env)->CallObjectMethod(env, pInfo, getFreqMethod); jclass freqClass = (*env)->GetObjectClass(env, freqInfo); jmethodID getFreqMethod2 = (*env)->GetMethodID(env, freqClass, "valueOf", "()I"); jint freq = (*env)->CallIntMethod(env, freqInfo, getFreqMethod2); info->freq = freq; (*env)->DeleteLocalRef(env, freqInfo); printf("PublishInfo->freq:%d\n", freq); //获取capability jmethodID getCapabilityMethod = (*env)->GetMethodID(env, infoClass, "getCapability", "()Ljava/lang/String;"); jstring capability = (*env)->CallObjectMethod(env, pInfo, getCapabilityMethod); if(capability != NULL) { const char *capabilityStr = (*env)->GetStringUTFChars(env, capability, 0); char *temp = (char *)malloc(strlen(capabilityStr) + 1); // 复制字符串到新分配的内存 strcpy(temp, capabilityStr); info->capability = temp; (*env)->ReleaseStringUTFChars(env, capability, capabilityStr); } else { info->capability = "osdCapability"; } printf("PublishInfo->capability:%s\n", info->capability); //获取capabilityData jmethodID getCapabilityDataMethod = (*env)->GetMethodID(env, infoClass, "getCapabilityData", "()Ljava/lang/String;"); jstring capabilityData = (*env)->CallObjectMethod(env, pInfo, getCapabilityDataMethod); if(capabilityData != NULL) { const char *capabilityDataStr = (*env)->GetStringUTFChars(env, capabilityData, 0); strcpy(info->capabilityData, capabilityDataStr); (*env)->ReleaseStringUTFChars(env, capabilityData, capabilityDataStr); printf("PublishInfo->capabilityData:%s\n", capabilityDataStr); } //获取数据长度 jmethodID getDataLenMethod = (*env)->GetMethodID(env, infoClass, "getDataLen", "()I"); info->dataLen = (*env)->CallIntMethod(env, pInfo, getDataLenMethod); printf("PublishInfo->dataLen:%d\n", info->dataLen); //获取ranging bool类型 //jmethodID getRangingMethod = (*env)->GetMethodID(env, infoClass, "getRanging", "()Z"); //info->ranging = (*env)->CallBooleanMethod(env, pInfo, getRangingMethod); //printf("PublishInfo->ranging:%d\n", info->ranging); return 0; } /** * 发布成功回调处理 */ void PublishSuc(int publishId) { // 获取JNIEnv环境 JNIEnv *env; // 将当前线程附加到Java虚拟机 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // 获取当前对象的类引用 jclass nativeLibClass = (*env)->GetObjectClass(env, globalRef); // 获取当前对象的publishSuccess方法的ID jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onPublishSuccess", "(I)V"); // 调用当前对象的非静态方法 (*env)->CallVoidMethod(env, globalRef, callbackMethod, publishId); // 将当前线程从Java虚拟机分离 (*jvm)->DetachCurrentThread(jvm); printf("CB: publish %d done\n", publishId); } /** * 发布失败回调处理 */ void PublishFailed(int publishId, PublishFailReason reason) { // 获取JNIEnv环境 JNIEnv *env; // 将当前线程附加到Java虚拟机 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // 获取当前对象的类引用 jclass nativeLibClass = (*env)->GetObjectClass(env, globalRef); // 获取当前对象的publishSuccess方法的ID jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onPublishFail", "(II)V"); // 调用当前对象的非静态方法 (*env)->CallVoidMethod(env, globalRef, callbackMethod, publishId, (int)reason); // 将当前线程从Java虚拟机分离 (*jvm)->DetachCurrentThread(jvm); printf("CB: publish %d failed, reason=%d\n", publishId, (int)reason); } /** * 发布服务 */ JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_PublishService_publishService (JNIEnv *env, jobject obj, jstring pkgName, jobject publishInfo, jobject callback) { // 保存Java虚拟机的引用 (*env)->GetJavaVM(env, &jvm); globalRef = (*env)->NewGlobalRef(env, callback); //包名处理 const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL); PublishInfo info; int ret = ParsePublishInfo(env, publishInfo, &info); 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, "PublishInfo object error."); //解析失败无法继续操作 return -1; } IPublishCallback cb = { .OnPublishSuccess = PublishSuc, .OnPublishFail = PublishFailed, }; //将当前的publishId维护进pkgName关系中,方便后期管理 // addPublishIdToPkgName(pkgNameStr, info.publishId); //发布服务 ret = PublishService(pkgNameStr, &info, &cb); (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr); return ret; } /** * 停止发布 */ JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_PublishService_unPublishService (JNIEnv *env, jobject obj, jstring pkgName, jint publishId) { // 保存Java虚拟机的引用 (*env)->GetJavaVM(env, &jvm); const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL); int ret = UnPublishService(pkgNameStr, publishId); 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, "stop publish failed!"); printf("UnPublishService fail:%d\n", ret); } (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr); return ret; } /** * publishLNN回调方法 */ void PublishResultHandle(int publishId, PublishResult reason) { // 获取JNIEnv环境 JNIEnv *env; // 将当前线程附加到Java虚拟机 (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); // 获取当前对象的类引用 jclass nativeLibClass = (*env)->GetObjectClass(env, globalRef); // 获取当前对象的publishSuccess方法的ID jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onPublishResult", "(II)V"); // 调用当前对象的非静态方法 (*env)->CallVoidMethod(env, globalRef, callbackMethod, publishId, (int)reason); // 将当前线程从Java虚拟机分离 (*jvm)->DetachCurrentThread(jvm); printf("CB: publish %d failed, reason=%d\n", publishId, (int)reason); } JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_PublishService_publishLNN (JNIEnv *env, jobject obj, jstring pkgName, jobject publishInfo, jobject callback) { // 保存Java虚拟机的引用 (*env)->GetJavaVM(env, &jvm); globalRef = (*env)->NewGlobalRef(env, callback); //包名处理 const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL); PublishInfo info; int ret = ParsePublishInfo(env, publishInfo, &info); 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, "PublishInfo object error."); //解析失败无法继续操作 return -1; } IPublishCb cb = { .OnPublishResult = PublishResultHandle, }; //将当前的publishId维护进pkgName关系中,方便后期管理 // addPublishIdToPkgName(pkgNameStr, info.publishId); //发布服务 ret = PublishLNN(pkgNameStr, &info, &cb); (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr); return ret; } JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_PublishService_stopPublishLNN (JNIEnv *env, jobject obj, jstring pkgName, jint publishId) { // 保存Java虚拟机的引用 (*env)->GetJavaVM(env, &jvm); const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL); int ret = StopPublishLNN(pkgNameStr, publishId); 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, "stop publish failed!"); printf("StopPublishLNN fail:%d\n", ret); } (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr); return ret; } JNIEXPORT void JNICALL Java_com_jg_softbus_naservice_PublishService_destroy (JNIEnv *env, jobject obj) { printf("[publish]destory the publish data.\r\n"); // 删除全局引用 (*env)->DeleteGlobalRef(env, globalRef); printf("[publish]globalRef have been destory.\r\n"); // free(jvm); // printf("[publish]jvm have been destory.\r\n"); }