SoftbusPublish.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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. // 保存Java虚拟机的引用
  161. (*env)->GetJavaVM(env, &jvm);
  162. const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL);
  163. int ret = UnPublishService(pkgNameStr, publishId);
  164. if (ret != 0) {
  165. // 尝试进行一些可能会抛出异常的操作
  166. jclass exceptionClass = (*env)->FindClass(env, "java/lang/Exception"); // 获取异常类
  167. // 如果找不到异常类,则抛出异常
  168. jmethodID exceptionConstructor = (*env)->GetMethodID(env, exceptionClass, "<init>", "()V");
  169. jthrowable exception = (*env)->NewObject(env, exceptionClass, exceptionConstructor);
  170. // 抛出异常
  171. (*env)->ThrowNew(env, exceptionClass, "stop publish failed!");
  172. printf("UnPublishService fail:%d\n", ret);
  173. }
  174. (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr);
  175. return ret;
  176. }
  177. /**
  178. * publishLNN回调方法
  179. */
  180. void PublishResultHandle(int publishId, PublishResult reason) {
  181. // 获取JNIEnv环境
  182. JNIEnv *env;
  183. // 将当前线程附加到Java虚拟机
  184. (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  185. // 获取当前对象的类引用
  186. jclass nativeLibClass = (*env)->GetObjectClass(env, globalRef);
  187. // 获取当前对象的publishSuccess方法的ID
  188. jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onPublishResult", "(II)V");
  189. // 调用当前对象的非静态方法
  190. (*env)->CallVoidMethod(env, globalRef, callbackMethod, publishId, (int)reason);
  191. // 将当前线程从Java虚拟机分离
  192. (*jvm)->DetachCurrentThread(jvm);
  193. printf("<PublishFailed>CB: publish %d failed, reason=%d\n", publishId, (int)reason);
  194. }
  195. JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_PublishService_publishLNN
  196. (JNIEnv *env, jobject obj, jstring pkgName, jobject publishInfo, jobject callback) {
  197. // 保存Java虚拟机的引用
  198. (*env)->GetJavaVM(env, &jvm);
  199. globalRef = (*env)->NewGlobalRef(env, callback);
  200. //包名处理
  201. const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL);
  202. PublishInfo info;
  203. int ret = ParsePublishInfo(env, publishInfo, &info);
  204. if(ret != 0) {
  205. // 尝试进行一些可能会抛出异常的操作
  206. jclass exceptionClass = (*env)->FindClass(env, "java/lang/Exception"); // 获取异常类
  207. // 如果找不到异常类,则抛出异常
  208. jmethodID exceptionConstructor = (*env)->GetMethodID(env, exceptionClass, "<init>", "()V");
  209. jthrowable exception = (*env)->NewObject(env, exceptionClass, exceptionConstructor);
  210. // 抛出异常
  211. (*env)->ThrowNew(env, exceptionClass, "PublishInfo object error.");
  212. //解析失败无法继续操作
  213. return -1;
  214. }
  215. IPublishCb cb = {
  216. .OnPublishResult = PublishResultHandle,
  217. };
  218. //将当前的publishId维护进pkgName关系中,方便后期管理
  219. // addPublishIdToPkgName(pkgNameStr, info.publishId);
  220. //发布服务
  221. ret = PublishLNN(pkgNameStr, &info, &cb);
  222. (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr);
  223. return ret;
  224. }
  225. JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_PublishService_stopPublishLNN
  226. (JNIEnv *env, jobject obj, jstring pkgName, jint publishId) {
  227. // 保存Java虚拟机的引用
  228. (*env)->GetJavaVM(env, &jvm);
  229. const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL);
  230. int ret = StopPublishLNN(pkgNameStr, publishId);
  231. if (ret != 0) {
  232. // 尝试进行一些可能会抛出异常的操作
  233. jclass exceptionClass = (*env)->FindClass(env, "java/lang/Exception"); // 获取异常类
  234. // 如果找不到异常类,则抛出异常
  235. jmethodID exceptionConstructor = (*env)->GetMethodID(env, exceptionClass, "<init>", "()V");
  236. jthrowable exception = (*env)->NewObject(env, exceptionClass, exceptionConstructor);
  237. // 抛出异常
  238. (*env)->ThrowNew(env, exceptionClass, "stop publish failed!");
  239. printf("StopPublishLNN fail:%d\n", ret);
  240. }
  241. (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr);
  242. return ret;
  243. }
  244. JNIEXPORT void JNICALL Java_com_jg_softbus_naservice_PublishService_destroy
  245. (JNIEnv *env, jobject obj) {
  246. printf("[publish]destory the publish data.\r\n");
  247. // 删除全局引用
  248. (*env)->DeleteGlobalRef(env, globalRef);
  249. printf("[publish]globalRef have been destory.\r\n");
  250. // free(jvm);
  251. // printf("[publish]jvm have been destory.\r\n");
  252. }