SoftbusPublish.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <string.h>
  4. #include <jni.h>
  5. #include "securec.h"
  6. #include "discovery_service.h"
  7. #include "softbus_bus_center.h"
  8. #include "com_jg_softbus_naservice_PublishService.h"
  9. // 全局变量,用于保存Java虚拟机的引用
  10. JavaVM *jvm;
  11. //全局引用变量,用于保存java对象
  12. jobject globalRef;
  13. /**
  14. * 解析对象为c的PublishInfo结构
  15. */
  16. int ParsePublishInfo(JNIEnv *env, jobject pInfo, PublishInfo *info) {
  17. jclass infoClass = (*env)->GetObjectClass(env, pInfo);
  18. // 获取publishId
  19. jmethodID getPublishIdMethod = (*env)->GetMethodID(env, infoClass, "getPublishId", "()I");
  20. jint publishId = (*env)->CallIntMethod(env, pInfo, getPublishIdMethod);
  21. info->publishId = publishId;
  22. printf("PublishInfo->publishId:%d\n", publishId);
  23. //获取mode
  24. jmethodID getDiscoverModeMethod = (*env)->GetMethodID(env, infoClass, "getMode", "()Lcom/jg/softbus/discovery/enums/DiscoverMode;");
  25. jobject modeInfo = (*env)->CallObjectMethod(env, pInfo, getDiscoverModeMethod);
  26. jclass modeClass = (*env)->GetObjectClass(env, modeInfo);
  27. jmethodID getModeMethod = (*env)->GetMethodID(env, modeClass, "valueOf", "()I");
  28. jint mode = (*env)->CallIntMethod(env, modeInfo, getModeMethod);
  29. info->mode = mode;
  30. (*env)->DeleteLocalRef(env,modeInfo);
  31. printf("PublishInfo->mode:%d\n", mode);
  32. //获取medium
  33. jmethodID getMediumMethod = (*env)->GetMethodID(env, infoClass, "getMedium", "()Lcom/jg/softbus/discovery/enums/ExchangeMedium;");
  34. jobject mediumInfo = (*env)->CallObjectMethod(env, pInfo, getMediumMethod);
  35. jclass mediumClass = (*env)->GetObjectClass(env, mediumInfo);
  36. jmethodID getMediumMethod2 = (*env)->GetMethodID(env, mediumClass, "valueOf", "()I");
  37. jint medium = (*env)->CallIntMethod(env, mediumInfo, getMediumMethod2);
  38. info->medium = medium;
  39. (*env)->DeleteLocalRef(env, mediumInfo);
  40. printf("PublishInfo->medium:%d\n", medium);
  41. //获取freq频次
  42. jmethodID getFreqMethod = (*env)->GetMethodID(env, infoClass, "getFreq", "()Lcom/jg/softbus/discovery/enums/ExchangeFreq;");
  43. jobject freqInfo = (*env)->CallObjectMethod(env, pInfo, getFreqMethod);
  44. jclass freqClass = (*env)->GetObjectClass(env, freqInfo);
  45. jmethodID getFreqMethod2 = (*env)->GetMethodID(env, freqClass, "valueOf", "()I");
  46. jint freq = (*env)->CallIntMethod(env, freqInfo, getFreqMethod2);
  47. info->freq = freq;
  48. (*env)->DeleteLocalRef(env, freqInfo);
  49. printf("PublishInfo->freq:%d\n", freq);
  50. //获取capability
  51. jmethodID getCapabilityMethod = (*env)->GetMethodID(env, infoClass, "getCapability", "()Ljava/lang/String;");
  52. jstring capability = (*env)->CallObjectMethod(env, pInfo, getCapabilityMethod);
  53. if(capability != NULL) {
  54. const char *capabilityStr = (*env)->GetStringUTFChars(env, capability, 0);
  55. char *temp = (char *)malloc(strlen(capabilityStr) + 1);
  56. // 复制字符串到新分配的内存
  57. strcpy(temp, capabilityStr);
  58. info->capability = temp;
  59. (*env)->ReleaseStringUTFChars(env, capability, capabilityStr);
  60. } else {
  61. info->capability = "osdCapability";
  62. }
  63. printf("PublishInfo->capability:%s\n", info->capability);
  64. //获取capabilityData
  65. jmethodID getCapabilityDataMethod = (*env)->GetMethodID(env, infoClass, "getCapabilityData", "()Ljava/lang/String;");
  66. jstring capabilityData = (*env)->CallObjectMethod(env, pInfo, getCapabilityDataMethod);
  67. if(capabilityData != NULL) {
  68. const char *capabilityDataStr = (*env)->GetStringUTFChars(env, capabilityData, 0);
  69. strcpy(info->capabilityData, capabilityDataStr);
  70. (*env)->ReleaseStringUTFChars(env, capabilityData, capabilityDataStr);
  71. printf("PublishInfo->capabilityData:%s\n", capabilityDataStr);
  72. }
  73. //获取数据长度
  74. jmethodID getDataLenMethod = (*env)->GetMethodID(env, infoClass, "getDataLen", "()I");
  75. info->dataLen = (*env)->CallIntMethod(env, pInfo, getDataLenMethod);
  76. printf("PublishInfo->dataLen:%d\n", info->dataLen);
  77. //获取ranging bool类型
  78. //jmethodID getRangingMethod = (*env)->GetMethodID(env, infoClass, "getRanging", "()Z");
  79. //info->ranging = (*env)->CallBooleanMethod(env, pInfo, getRangingMethod);
  80. //printf("PublishInfo->ranging:%d\n", info->ranging);
  81. return 0;
  82. }
  83. /**
  84. * 发布成功回调处理
  85. */
  86. void PublishSuc(int publishId)
  87. {
  88. // 获取JNIEnv环境
  89. JNIEnv *env;
  90. // 将当前线程附加到Java虚拟机
  91. (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  92. // 获取当前对象的类引用
  93. jclass nativeLibClass = (*env)->GetObjectClass(env, globalRef);
  94. // 获取当前对象的publishSuccess方法的ID
  95. jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onPublishSuccess", "(I)V");
  96. // 调用当前对象的非静态方法
  97. (*env)->CallVoidMethod(env, globalRef, callbackMethod, publishId);
  98. // 将当前线程从Java虚拟机分离
  99. (*jvm)->DetachCurrentThread(jvm);
  100. printf("<PublishSuc>CB: publish %d done\n", publishId);
  101. }
  102. /**
  103. * 发布失败回调处理
  104. */
  105. void PublishFailed(int publishId, PublishFailReason reason)
  106. {
  107. // 获取JNIEnv环境
  108. JNIEnv *env;
  109. // 将当前线程附加到Java虚拟机
  110. (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  111. // 获取当前对象的类引用
  112. jclass nativeLibClass = (*env)->GetObjectClass(env, globalRef);
  113. // 获取当前对象的publishSuccess方法的ID
  114. jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onPublishFail", "(II)V");
  115. // 调用当前对象的非静态方法
  116. (*env)->CallVoidMethod(env, globalRef, callbackMethod, publishId, (int)reason);
  117. // 将当前线程从Java虚拟机分离
  118. (*jvm)->DetachCurrentThread(jvm);
  119. printf("<PublishFailed>CB: publish %d failed, reason=%d\n", publishId, (int)reason);
  120. }
  121. /**
  122. * 发布服务
  123. */
  124. JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_PublishService_publishService
  125. (JNIEnv *env, jobject obj, jstring pkgName, jobject publishInfo, jobject callback) {
  126. // 保存Java虚拟机的引用
  127. (*env)->GetJavaVM(env, &jvm);
  128. globalRef = (*env)->NewGlobalRef(env, callback);
  129. //包名处理
  130. const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL);
  131. PublishInfo info;
  132. int ret = ParsePublishInfo(env, publishInfo, &info);
  133. if(ret != 0) {
  134. // 尝试进行一些可能会抛出异常的操作
  135. jclass exceptionClass = (*env)->FindClass(env, "java/lang/Exception"); // 获取异常类
  136. // 如果找不到异常类,则抛出异常
  137. jmethodID exceptionConstructor = (*env)->GetMethodID(env, exceptionClass, "<init>", "()V");
  138. jthrowable exception = (*env)->NewObject(env, exceptionClass, exceptionConstructor);
  139. // 抛出异常
  140. (*env)->ThrowNew(env, exceptionClass, "PublishInfo object error.");
  141. //解析失败无法继续操作
  142. return -1;
  143. }
  144. IPublishCallback cb = {
  145. .OnPublishSuccess = PublishSuc,
  146. .OnPublishFail = PublishFailed,
  147. };
  148. //将当前的publishId维护进pkgName关系中,方便后期管理
  149. // addPublishIdToPkgName(pkgNameStr, info.publishId);
  150. //发布服务
  151. ret = PublishService(pkgNameStr, &info, &cb);
  152. (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr);
  153. return ret;
  154. }
  155. /**
  156. * 停止发布
  157. */
  158. JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_PublishService_unPublishService
  159. (JNIEnv *env, jobject obj, jstring pkgName, jint publishId) {
  160. const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL);
  161. int ret = UnPublishService(pkgNameStr, publishId);
  162. if (ret != 0) {
  163. // 尝试进行一些可能会抛出异常的操作
  164. jclass exceptionClass = (*env)->FindClass(env, "java/lang/Exception"); // 获取异常类
  165. // 如果找不到异常类,则抛出异常
  166. jmethodID exceptionConstructor = (*env)->GetMethodID(env, exceptionClass, "<init>", "()V");
  167. jthrowable exception = (*env)->NewObject(env, exceptionClass, exceptionConstructor);
  168. // 抛出异常
  169. (*env)->ThrowNew(env, exceptionClass, "stop publish failed!");
  170. printf("UnPublishService fail:%d\n", ret);
  171. }
  172. (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr);
  173. (*env)->DeleteGlobalRef(env, globalRef);
  174. }
  175. /**
  176. * publishLNN回调方法
  177. */
  178. void PublishResultHandle(int publishId, PublishResult reason) {
  179. // 获取JNIEnv环境
  180. JNIEnv *env;
  181. // 将当前线程附加到Java虚拟机
  182. (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  183. // 获取当前对象的类引用
  184. jclass nativeLibClass = (*env)->GetObjectClass(env, globalRef);
  185. // 获取当前对象的publishSuccess方法的ID
  186. jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onPublishResult", "(II)V");
  187. // 调用当前对象的非静态方法
  188. (*env)->CallVoidMethod(env, globalRef, callbackMethod, publishId, (int)reason);
  189. // 将当前线程从Java虚拟机分离
  190. (*jvm)->DetachCurrentThread(jvm);
  191. printf("<PublishFailed>CB: publish %d failed, reason=%d\n", publishId, (int)reason);
  192. }
  193. JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_PublishService_publishLNN
  194. (JNIEnv *env, jobject obj, jstring pkgName, jobject publishInfo, jobject callback) {
  195. // 保存Java虚拟机的引用
  196. (*env)->GetJavaVM(env, &jvm);
  197. globalRef = (*env)->NewGlobalRef(env, callback);
  198. //包名处理
  199. const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL);
  200. PublishInfo info;
  201. int ret = ParsePublishInfo(env, publishInfo, &info);
  202. if(ret != 0) {
  203. // 尝试进行一些可能会抛出异常的操作
  204. jclass exceptionClass = (*env)->FindClass(env, "java/lang/Exception"); // 获取异常类
  205. // 如果找不到异常类,则抛出异常
  206. jmethodID exceptionConstructor = (*env)->GetMethodID(env, exceptionClass, "<init>", "()V");
  207. jthrowable exception = (*env)->NewObject(env, exceptionClass, exceptionConstructor);
  208. // 抛出异常
  209. (*env)->ThrowNew(env, exceptionClass, "PublishInfo object error.");
  210. //解析失败无法继续操作
  211. return -1;
  212. }
  213. IPublishCb cb = {
  214. .OnPublishResult = PublishResultHandle,
  215. };
  216. //将当前的publishId维护进pkgName关系中,方便后期管理
  217. // addPublishIdToPkgName(pkgNameStr, info.publishId);
  218. //发布服务
  219. ret = PublishLNN(pkgNameStr, &info, &cb);
  220. (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr);
  221. return ret;
  222. }
  223. JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_PublishService_stopPublishLNN
  224. (JNIEnv *env, jobject obj, jstring pkgName, jint publishId) {
  225. const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL);
  226. int ret = StopPublishLNN(pkgNameStr, publishId);
  227. if (ret != 0) {
  228. // 尝试进行一些可能会抛出异常的操作
  229. jclass exceptionClass = (*env)->FindClass(env, "java/lang/Exception"); // 获取异常类
  230. // 如果找不到异常类,则抛出异常
  231. jmethodID exceptionConstructor = (*env)->GetMethodID(env, exceptionClass, "<init>", "()V");
  232. jthrowable exception = (*env)->NewObject(env, exceptionClass, exceptionConstructor);
  233. // 抛出异常
  234. (*env)->ThrowNew(env, exceptionClass, "stop publish failed!");
  235. printf("StopPublishLNN fail:%d\n", ret);
  236. }
  237. (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr);
  238. (*env)->DeleteGlobalRef(env, globalRef);
  239. }
  240. JNIEXPORT void JNICALL Java_com_jg_softbus_naservice_PublishService_destroy
  241. (JNIEnv *env, jobject obj) {
  242. printf("[publish]destory the publish data.");
  243. // 删除全局引用
  244. (*env)->DeleteGlobalRef(env, globalRef);
  245. printf("[publish]globalRef have been destory.");
  246. free(jvm);
  247. printf("[publish]jvm have been destory.");
  248. }