SoftbusSubscribe.c 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  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_SubscribeService.h"
  9. // 全局变量,用于保存Java虚拟机的引用
  10. JavaVM *jvm;
  11. //全局引用变量,用于保存java对象
  12. jobject globalRef;
  13. /**
  14. * 解析java对象为c的SubscribeInfo结构
  15. */
  16. int ParseSubscribeInfo(JNIEnv *env, jobject subscribeInfo, SubscribeInfo *info) {
  17. jclass infoClass = (*env)->GetObjectClass(env, subscribeInfo);
  18. //读取subscribeId
  19. jmethodID getSubscribeIdMethod = (*env)->GetMethodID(env, infoClass, "getSubscribeId", "()I");
  20. jint subscribeId = (*env)->CallIntMethod(env, subscribeInfo, getSubscribeIdMethod);
  21. info->subscribeId = subscribeId;
  22. printf("SubscribeInfo->subscribeId:%d\n", subscribeId);
  23. //获取mode
  24. jmethodID getDiscoverModeMethod = (*env)->GetMethodID(env, infoClass, "getMode", "()Lcom/jg/softbus/discovery/enums/DiscoverMode;");
  25. jobject modeInfo = (*env)->CallObjectMethod(env, subscribeInfo, 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("SubscribeInfo->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, subscribeInfo, 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("SubscribeInfo->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, subscribeInfo, 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("SubscribeInfo->freq:%d\n", freq);
  50. //获取isSameAccount bool类型
  51. jmethodID getIsSameAccountMethod = (*env)->GetMethodID(env, infoClass, "getIsSameAccount", "()Z");
  52. info->isSameAccount = (*env)->CallBooleanMethod(env, subscribeInfo, getIsSameAccountMethod);
  53. printf("SubscribeInfo->isSameAccount:%d\n", info->isSameAccount);
  54. //获取isWakeRemote bool类型
  55. jmethodID getIsWakeRemoteMethod = (*env)->GetMethodID(env, infoClass, "getIsWakeRemote", "()Z");
  56. info->isWakeRemote = (*env)->CallBooleanMethod(env, subscribeInfo, getIsWakeRemoteMethod);
  57. printf("SubscribeInfo->isWakeRemote:%d\n", info->isWakeRemote);
  58. //获取capability
  59. jmethodID getCapabilityMethod = (*env)->GetMethodID(env, infoClass, "getCapability", "()Ljava/lang/String;");
  60. jstring capability = (*env)->CallObjectMethod(env, subscribeInfo, getCapabilityMethod);
  61. if(capability != NULL) {
  62. const char *capabilityStr = (*env)->GetStringUTFChars(env, capability, 0);
  63. char *temp = (char *)malloc(strlen(capabilityStr) + 1);
  64. // 复制字符串到新分配的内存
  65. strcpy(temp, capabilityStr);
  66. info->capability = temp;
  67. (*env)->ReleaseStringUTFChars(env, capability, capabilityStr);
  68. } else {
  69. info->capability = "osdCapability";
  70. }
  71. printf("SubscribeInfo->capability:%s\n", info->capability);
  72. //获取capabilityData
  73. jmethodID getCapabilityDataMethod = (*env)->GetMethodID(env, infoClass, "getCapabilityData", "()Ljava/lang/String;");
  74. jstring capabilityData = (*env)->CallObjectMethod(env, subscribeInfo, getCapabilityDataMethod);
  75. if(capabilityData != NULL) {
  76. const char *capabilityDataStr = (*env)->GetStringUTFChars(env, capabilityData, 0);
  77. strcpy(info->capabilityData, capabilityDataStr);
  78. if(info->capabilityData == NULL) {
  79. info->capabilityData = NULL;
  80. }
  81. (*env)->ReleaseStringUTFChars(env, capabilityData, capabilityDataStr);
  82. printf("SubscribeInfo->capabilityData:%s\n", capabilityDataStr);
  83. }
  84. //获取数据长度
  85. jmethodID getDataLenMethod = (*env)->GetMethodID(env, infoClass, "getDataLen", "()I");
  86. info->dataLen = (*env)->CallIntMethod(env, subscribeInfo, getDataLenMethod);
  87. printf("SubscribeInfo->dataLen:%d\n", info->dataLen);
  88. return 0;
  89. }
  90. /**
  91. * 将c的DeviceInfo对象转换为java的object对象
  92. */
  93. jobject DeviceInfoToJavaObject(JNIEnv *env, const DeviceInfo *device) {
  94. //创建java的DeviceInfo对象
  95. jclass deviceInfoClass = (*env)->FindClass(env, "com/jg/softbus/device/DeviceInfo");
  96. if (deviceInfoClass == NULL) {
  97. // 处理错误
  98. printf("Cannot found the java class:com/jg/softbus/device/DeviceInfo");
  99. return NULL;
  100. }
  101. jmethodID constructor = (*env)->GetMethodID(env, deviceInfoClass, "<init>", "()V");
  102. if (constructor == NULL) {
  103. // 处理错误
  104. printf("Cannot found the default constructor of DeviceInfo.");
  105. return NULL;
  106. }
  107. jobject obj = (*env)->NewObject(env, deviceInfoClass, constructor);
  108. if (obj == NULL) {
  109. // 处理错误
  110. printf("Cannot create the DeviceInfo object.");
  111. return NULL;
  112. }
  113. //设置devId
  114. jmethodID setDevIdMethod = (*env)->GetMethodID(env, deviceInfoClass, "setDevId", "(Ljava/lang/String;)V");
  115. jstring devIdStr = (*env)->NewStringUTF(env, device->devId);
  116. (*env)->CallVoidMethod(env, obj, setDevIdMethod, devIdStr);
  117. (*env)->DeleteLocalRef(env, devIdStr);
  118. //设置devName
  119. jmethodID setDevNameMethod = (*env)->GetMethodID(env, deviceInfoClass, "setDevName", "(Ljava/lang/String;)V");
  120. jstring devNameStr = (*env)->NewStringUTF(env, device->devName);
  121. (*env)->CallVoidMethod(env, obj, setDevNameMethod, devNameStr);
  122. (*env)->DeleteLocalRef(env, devNameStr);
  123. //发现DeviceType java类,根据其提供的静态getForValue(int)方法获取DeviceType对象
  124. jclass deviceTypeClass = (*env)->FindClass(env, "com/jg/softbus/device/DeviceType");
  125. if (deviceTypeClass == NULL) {
  126. // 处理错误
  127. printf("Cannot found the java class:com/jg/softbus/device/DeviceType");
  128. return NULL;
  129. }
  130. jmethodID getForValueMethod = (*env)->GetStaticMethodID(env, deviceTypeClass, "getForValue", "(I)Lcom/jg/softbus/device/DeviceType;");
  131. if (getForValueMethod == NULL) {
  132. // 处理错误
  133. printf("Cannot found the static method:getForValue(int)");
  134. return NULL;
  135. }
  136. jobject deviceTypeObj = (*env)->CallStaticObjectMethod(env, deviceTypeClass, getForValueMethod, (int)(device->devType));
  137. if (deviceTypeObj == NULL) {
  138. // 处理错误
  139. printf("Cannot found DeviceType. the devType is: %d", device->devType);
  140. return NULL;
  141. }
  142. //设置devType
  143. jmethodID setDevTypeMethod = (*env)->GetMethodID(env, deviceInfoClass, "setDevType", "(Lcom/jg/softbus/device/DeviceType;)V");
  144. (*env)->CallVoidMethod(env, obj, setDevTypeMethod, deviceTypeObj);
  145. (*env)->DeleteLocalRef(env, deviceTypeObj);
  146. //设置在线状态isOnline
  147. // jmethodID setIsOnlineMethod = (*env)->GetMethodID(env, deviceInfoClass, "setOnline", "(Z)V");
  148. // (*env)->CallVoidMethod(env, obj, setIsOnlineMethod, device->isOnline);
  149. //设置地址数addrNum
  150. jmethodID setAddrNumMethod = (*env)->GetMethodID(env, deviceInfoClass, "setAddrNum", "(I)V");
  151. (*env)->CallVoidMethod(env, obj, setAddrNumMethod, device->addrNum);
  152. //发现ConnectionAddr的java类
  153. jclass connectionAddrClass = (*env)->FindClass(env, "com/jg/softbus/network/protocol/ConnectionAddr");
  154. if (connectionAddrClass == NULL) {
  155. // 处理错误
  156. printf("Cannot found the class:com/jg/softbus/network/protocol/ConnectionAddr");
  157. return NULL;
  158. }
  159. //构建一个java ConnectionAddr的数组,数组长度为addrNum
  160. jobjectArray addrArray = (*env)->NewObjectArray(env, device->addrNum, connectionAddrClass, NULL);
  161. //发现com.jg.softbus.network.protocol.ConnectionAddrType java类,根据其提供的静态getForValue(int)方法获取ConnectionAddrType对象
  162. jclass connectionAddrTypeClass = (*env)->FindClass(env, "com/jg/softbus/network/protocol/ConnectionAddrType");
  163. if (connectionAddrTypeClass == NULL) {
  164. // 处理错误
  165. printf("Cannot found the class:com/jg/softbus/network/protocol/ConnectionAddrType");
  166. return NULL;
  167. }
  168. //查找com.jg.softbus.network.protocol.ConnectionAddrInfo
  169. jclass connectionAddrInfoClass = (*env)->FindClass(env, "com/jg/softbus/network/protocol/ConnectionAddrInfo");
  170. if (connectionAddrInfoClass == NULL) {
  171. // 处理错误
  172. printf("Cannot found the class:com/jg/softbus/network/protocol/ConnectionAddrInfo");
  173. return NULL;
  174. }
  175. //查找ConnectionAddrInfo的无参构造函数
  176. jmethodID connectionAddrInfoConstructor = (*env)->GetMethodID(env, connectionAddrInfoClass, "<init>", "()V");
  177. if (connectionAddrInfoConstructor == NULL) {
  178. // 处理错误
  179. printf("Cannot found the constructor:com/jg/softbus/network/protocol/ConnectionAddrInfo");
  180. return NULL;
  181. }
  182. //查找com.jg.softbus.network.protocol.IpAddr的java对象
  183. jclass ipAddrClass = (*env)->FindClass(env, "com/jg/softbus/network/protocol/IpAddr");
  184. if(ipAddrClass == NULL){
  185. printf("Cannot found the IpAddr class.");
  186. return NULL;
  187. }
  188. //查找IpAddr带参构造函数,函数结构为:IpAddr(String ip, int port)
  189. jmethodID ipAddrConstructor = (*env)->GetMethodID(env, ipAddrClass, "<init>", "(Ljava/lang/String;I)V");
  190. if(ipAddrConstructor == NULL){
  191. printf("Cannot found the constructor of IpAddr.");
  192. return NULL;
  193. }
  194. //查找com.jg.softbus.network.protocol.BrAddr的java对象
  195. jclass brAddrClass = (*env)->FindClass(env, "com/jg/softbus/network/protocol/BrAddr");
  196. if(brAddrClass == NULL){
  197. printf("Cannot found the BrAddr class.");
  198. return NULL;
  199. }
  200. //查找BrAddr带参构造函数,函数结构为:BrAddr(String brMac)
  201. jmethodID brAddrConstructor = (*env)->GetMethodID(env, brAddrClass, "<init>", "(Ljava/lang/String)V");
  202. if(brAddrConstructor == NULL){
  203. printf("Cannot found the constructor of BrAddr.");
  204. return NULL;
  205. }
  206. //查找com.jg.softbus.network.protocol.BleAddr的java对象
  207. jclass bleAddrClass = (*env)->FindClass(env, "com/jg/softbus/network/protocol/BleAddr");
  208. if(bleAddrClass == NULL){
  209. printf("Cannot found the BleAddr class.");
  210. return NULL;
  211. }
  212. //查找BleAddr无参构造函数,函数结构为:BleAddr()
  213. jmethodID bleAddrConstructor = (*env)->GetMethodID(env, bleAddrClass, "<init>", "()V");
  214. if(bleAddrConstructor == NULL){
  215. printf("Cannot found the constructor of BleAddr.");
  216. return NULL;
  217. }
  218. //查找com.jg.softbus.network.protocol.BleProtocolType的java对象
  219. // jclass bleProtocolTypeClass = (*env)->FindClass(env, "com/jg/softbus/network/protocol/BleProtocolType");
  220. // if(bleProtocolTypeClass == NULL){
  221. // printf("Cannot found the BleProtocolType class.");
  222. // return NULL;
  223. // }
  224. //查找com/jg/softbus/network/protocol/SessionAddr的java对象
  225. // jclass sessionAddrClass = (*env)->FindClass(env, "com/jg/softbus/network/protocol/SessionAddr");
  226. // if(sessionAddrClass == NULL){
  227. // printf("Cannot found the SessionAddr class.");
  228. // return NULL;
  229. // }
  230. //查找SessionAddr无参构造函数,函数结构为:SessionAddr()
  231. // jmethodID sessionAddrConstructor = (*env)->GetMethodID(env, sessionAddrClass, "<init>", "()V");
  232. // if(sessionAddrConstructor == NULL){
  233. // printf("Cannot found the constructor of SessionAddr.");
  234. // return NULL;
  235. // }
  236. for (int i = 0; i < device->addrNum; i++) {
  237. //基于无参的构造函数创建ConnectionAddr对象
  238. jmethodID connectionAddrConstructor = (*env)->GetMethodID(env, connectionAddrClass, "<init>", "()V");
  239. jobject addrObj = (*env)->NewObject(env, connectionAddrClass, connectionAddrConstructor);
  240. //获取ConnectionAddrType对象
  241. jmethodID getForValueMethod = (*env)->GetStaticMethodID(env, connectionAddrTypeClass, "getForValue", "(I)Lcom/jg/softbus/network/protocol/ConnectionAddrType;");
  242. if (getForValueMethod == NULL) {
  243. // 处理错误
  244. printf("Cannot found the method:getForValue(int)");
  245. return NULL;
  246. }
  247. //根据device提供的地址类型获取ConnectionAddrType对象
  248. jobject addrTypeObj = (*env)->CallStaticObjectMethod(env, connectionAddrTypeClass, getForValueMethod, device->addr[i].type);
  249. if(addrTypeObj == NULL) {
  250. // 处理错误
  251. printf("Cannot found the ConnectionAddrType. type info: %d", device->addr[i].type);
  252. return NULL;
  253. }
  254. //查找ConnectionAddr的setType(ConnectionAddrType type)方法
  255. jmethodID setTypeMethod = (*env)->GetMethodID(env, connectionAddrClass, "setType", "(Lcom/jg/softbus/network/protocol/ConnectionAddrType;)V");
  256. //设置地址类型到地址对象中
  257. (*env)->CallVoidMethod(env, addrObj, setTypeMethod, addrTypeObj);
  258. (*env)->DeleteLocalRef(env, addrTypeObj);
  259. //无参创建ConnectionAddrInfo的java对象
  260. jobject infoObj = (*env)->NewObject(env, connectionAddrInfoClass, connectionAddrInfoConstructor);
  261. //判断device->addr[i].type的类型,可参考下面代码的Switch方式
  262. switch (device->addr[i].type) {
  263. case CONNECTION_ADDR_WLAN: {
  264. printf("ip=%s,port=%d,", device->addr[i].info.ip.ip, device->addr[i].info.ip.port);
  265. }
  266. case CONNECTION_ADDR_ETH: {
  267. jstring ipstr = (*env)->NewStringUTF(env, device->addr[i].info.ip.ip);
  268. //并使用有参构造函数进行初始化
  269. jobject ipAddrObj = (*env)->NewObject(env, ipAddrClass, ipAddrConstructor, ipstr, device->addr[i].info.ip.port);
  270. //将地址对象写入ConnectionAddrInfo对象中
  271. jmethodID setIpMethod = (*env)->GetMethodID(env, connectionAddrClass, "setIp", "(Lcom/jg/softbus/network/protocol/IpAddr;)V");
  272. //设置地址类型到地址对象中
  273. (*env)->CallVoidMethod(env, addrObj, setIpMethod, ipAddrObj);
  274. (*env)->DeleteLocalRef(env, ipAddrObj);
  275. break;
  276. }
  277. case CONNECTION_ADDR_BR: {
  278. jstring brMacStr = (*env)->NewStringUTF(env, device->addr[i].info.br.brMac);
  279. //并使用有参构造函数进行初始化
  280. jobject brAddrObj = (*env)->NewObject(env, brAddrClass, brAddrConstructor, brMacStr);
  281. //将地址对象写入ConnectionAddrInfo对象中
  282. jmethodID setBrMethod = (*env)->GetMethodID(env, connectionAddrClass, "setBr", "(Lcom/jg/softbus/network/protocol/BrAddr;)V");
  283. //设置地址类型到地址对象中
  284. (*env)->CallVoidMethod(env, addrObj, setBrMethod, brAddrObj);
  285. (*env)->DeleteLocalRef(env, brAddrObj);
  286. (*env)->DeleteLocalRef(env, brMacStr);
  287. break;
  288. }
  289. case CONNECTION_ADDR_BLE: {
  290. //并使用构造函数进行初始化
  291. jobject bleAddrObj = (*env)->NewObject(env, bleAddrClass, bleAddrConstructor);
  292. // //获取BleProtocolType对象
  293. // jmethodID getForValueMethod2 = (*env)->GetStaticMethodID(env, bleProtocolTypeClass, "getForValue", "(I)Lcom/jg/softbus/network/protocol/BleProtocolType;");
  294. // if (getForValueMethod2 == NULL) {
  295. // // 处理错误
  296. // printf("Cannot found the method:getForValue(int)");
  297. // return NULL;
  298. // }
  299. // //根据device提供的bleprotocol类型获取BleProtocolType对象
  300. // jobject bleProtocolTypeObj = (*env)->CallStaticObjectMethod(env, bleProtocolTypeClass, getForValueMethod2, device->addr[i].info.ble.protocol);
  301. // if(bleProtocolTypeObj == NULL) {
  302. // // 处理错误
  303. // printf("Cannot found the BleProtocolType. type info: %d", device->addr[i].info.ble.protocol);
  304. // return NULL;
  305. // }
  306. // //将地址对象写入ConnectionAddrInfo对象中
  307. // jmethodID setProtocolMethod = (*env)->GetMethodID(env, bleAddrClass, "setProtocol", "(Lcom/jg/softbus/network/protocol/BleProtocolType;)V");
  308. // (*env)->CallVoidMethod(env, bleAddrObj, setProtocolMethod, bleProtocolTypeObj);
  309. // (*env)->DeleteLocalRef(env, bleProtocolTypeObj);
  310. //setbleMac
  311. jmethodID setBleMacMethod = (*env)->GetMethodID(env, bleAddrClass, "setBleMac", "(Ljava/lang/String)V");
  312. jstring bleMac = (*env)->NewStringUTF(env, device->addr[i].info.ble.bleMac);
  313. (*env)->CallVoidMethod(env, bleAddrObj, setBleMacMethod, bleMac);
  314. (*env)->DeleteLocalRef(env, bleMac);
  315. //setUdidHash
  316. jmethodID setUdidHashMethod = (*env)->GetMethodID(env, bleAddrClass, "setUdidHash", "([B)V");
  317. size_t len = UDID_HASH_LEN / sizeof(uint8_t);
  318. jbyteArray byteArray = (*env)->NewByteArray(env, len);
  319. (*env)->SetByteArrayRegion(env, byteArray, 0, len, (const jbyte*)device->addr[i].info.ble.udidHash);
  320. // 将udidHash转换为整数
  321. // int hash_value = 0;
  322. // for (int k = 0; k < UDID_HASH_LEN; k++) {
  323. // hash_value = (hash_value << 8) + device->addr[i].info.ble.udidHash[k];
  324. // }
  325. (*env)->CallVoidMethod(env, bleAddrObj, setUdidHashMethod, byteArray);
  326. (*env)->DeleteLocalRef(env, byteArray);
  327. // //setPsm
  328. // jmethodID setPsmMethod = (*env)->GetMethodID(env, bleAddrClass, "setPsm", "(I)V");
  329. // (*env)->CallVoidMethod(env, bleAddrObj, setPsmMethod, device->addr[i].info.ble.psm);
  330. //将地址对象写入ConnectionAddrInfo对象中
  331. jmethodID setBleMethod = (*env)->GetMethodID(env, connectionAddrClass, "setBle", "(Lcom/jg/softbus/network/protocol/BrAddr;)V");
  332. (*env)->CallVoidMethod(env, addrObj, setBleMethod, bleAddrObj);
  333. (*env)->DeleteLocalRef(env, bleAddrObj);
  334. printf("bleMac=%s,", device->addr[i].info.ble.bleMac);
  335. break;
  336. }
  337. // case CONNECTION_ADDR_SESSION:
  338. // //创建SessionAddr对象
  339. // jobject sessionAddrObj = (*env)->NewObject(env, sessionAddrClass, sessionAddrConstructor);
  340. // //获取void setSessionId(Integer sessionId)方法
  341. // jmethodID setSessionIdMethod = (*env)->GetMethodID(env, sessionAddrClass, "setSessionId", "(I)V");
  342. // //将device中的sessionId调用方法设置到sessionAddrObj中
  343. // (*env)->CallVoidMethod(env, sessionAddrObj, setSessionIdMethod, device->addr[i].info.session.sessionId);
  344. // //获取void setChannelId(Integer channelId)方法
  345. // jmethodID setChannelIdMethod = (*env)->GetMethodID(env, sessionAddrClass, "setChannelId", "(I)V");
  346. // //将device中的channelId调用方法设置到sessionAddrObj中
  347. // (*env)->CallVoidMethod(env, sessionAddrObj, setChannelIdMethod, device->addr[i].info.session.channelId);
  348. // //获取void setType(String type)方法
  349. // jmethodID setTypeMethod = (*env)->GetMethodID(env, sessionAddrClass, "setType", "(Ljava/lang/String;)V");
  350. // //将device中的type调用方法设置到sessionAddrObj中
  351. // jstring sessionTypeStr = (*env)->NewStringUTF(env, device->addr[i].info.session.type);
  352. // (*env)->CallVoidMethod(env, sessionAddrObj, setTypeMethod, sessionTypeStr);
  353. // jmethodID setSessionMethod = (*env)->GetMethodID(env, connectionAddrClass, "setSession", "(Lcom/jg/softbus/network/protocol/SessionAddr;)V");
  354. // (*env)->CallVoidMethod(env, addrObj, setSessionMethod, sessionAddrObj);
  355. // (*env)->DeleteLocalRef(env, sessionTypeStr);
  356. // (*env)->DeleteLocalRef(env, sessionAddrObj);
  357. // printf("sessionId=%d, channelId=%d, type=%d", device->addr[i].info.session.sessionId, device->addr[i].info.session.channelId,device->addr[i].info.session.type);
  358. // break;
  359. default:
  360. break;
  361. }
  362. //获取ConnectionAddr中的void setPeerUid(String peerUid)方法,将device中的peerUid放入到addrObj中
  363. jmethodID setPeerUidMethod = (*env)->GetMethodID(env, connectionAddrClass, "setPeerUid", "(Ljava/lang/String;)V");
  364. jstring peerUidStr = (*env)->NewStringUTF(env, device->addr[i].peerUid);
  365. (*env)->CallVoidMethod(env, addrObj, setPeerUidMethod, peerUidStr);
  366. (*env)->DeleteLocalRef(env, peerUidStr);
  367. (*env)->SetObjectArrayElement(env, addrArray, i, addrObj);
  368. (*env)->DeleteLocalRef(env, addrObj);
  369. }
  370. //查找void setAddr(ConnectionAddr[] addr)方法并将addrArray对象设置到obj对象中
  371. jmethodID setAddrMethod = (*env)->GetMethodID(env, deviceInfoClass, "setAddr", "([Lcom/jg/softbus/network/protocol/ConnectionAddr;)V");
  372. (*env)->CallVoidMethod(env, obj, setAddrMethod, addrArray);
  373. (*env)->DeleteLocalRef(env, addrArray);
  374. //查找void setCapabilityBitmapNum(Integer capabilityBitmapNum)方法
  375. jmethodID setCapabilityBitmapNumMethod = (*env)->GetMethodID(env, deviceInfoClass, "setCapabilityBitmapNum", "(I)V");
  376. (*env)->CallVoidMethod(env, obj, setCapabilityBitmapNumMethod, device->capabilityBitmapNum);
  377. //查找void setCapabilityBitmap(String[] capabilityBitmap)方法
  378. jmethodID setCapabilityBitmapMethod = (*env)->GetMethodID(env, deviceInfoClass, "setCapabilityBitmap", "([Ljava/lang/String;)V");
  379. //构建jstring的数组对象,长度为addrNum的数值
  380. jobjectArray sArray = (*env)->NewObjectArray(env, device->addrNum, (*env)->FindClass(env, "java/lang/String"), NULL);
  381. for (int i = 0; i < device->addrNum; i++) {
  382. char* cbitmap_str;
  383. sprintf(cbitmap_str, "0x%x", device->capabilityBitmap[i]);
  384. //将cbitmap_str放入到jstringArray中
  385. jstring addrObj = (*env)->NewStringUTF(env, cbitmap_str);
  386. (*env)->SetObjectArrayElement(env, sArray, i, addrObj);
  387. (*env)->DeleteLocalRef(env, addrObj);
  388. printf("\t\tcapabilityBitmap[%d]=0x%x\n", i + 1, device->capabilityBitmap[i]);
  389. }
  390. (*env)->CallVoidMethod(env, obj, setCapabilityBitmapMethod, sArray);
  391. (*env)->DeleteLocalRef(env, sArray);
  392. //查找void setCustData(String custData)方法
  393. jmethodID setCustDataMethod = (*env)->GetMethodID(env, deviceInfoClass, "setCustData", "(Ljava/lang/String;)V");
  394. //获取device的custData放入到obj中
  395. jstring custDataObj = (*env)->NewStringUTF(env, device->custData);
  396. (*env)->CallVoidMethod(env, obj, setCustDataMethod, custDataObj);
  397. (*env)->DeleteLocalRef(env, custDataObj);
  398. //获取void setRange(Integer range)方法
  399. // jmethodID setRangeMethod = (*env)->GetMethodID(env, deviceInfoClass, "setRange", "(I)V");
  400. // (*env)->CallVoidMethod(env, obj, setRangeMethod, device->range);
  401. }
  402. /**
  403. * 设备发现回调
  404. */
  405. void DeviceFound(const DeviceInfo *device)
  406. {
  407. // 获取JNIEnv环境
  408. JNIEnv *env;
  409. // 将当前线程附加到Java虚拟机
  410. (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  411. // 获取当前对象的类引用
  412. jclass nativeLibClass = (*env)->GetObjectClass(env, globalRef);
  413. // 获取当前对象的publishSuccess方法的ID
  414. jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onDeviceFound", "(Lcom/jg/softbus/device/DeviceInfo;)V");
  415. //转换DeviceInfo为java对应的对象
  416. jobject deviceObj = DeviceInfoToJavaObject(env, device);
  417. if(deviceObj == NULL) {
  418. return;
  419. }
  420. //调用回调方法执行
  421. (*env)->CallVoidMethod(env, globalRef, callbackMethod, deviceObj);
  422. //删除本地对象
  423. (*env)->DeleteLocalRef(env, deviceObj);
  424. //将当前线程从java虚拟机中移除
  425. (*jvm)->DetachCurrentThread(jvm);
  426. }
  427. /**
  428. * 发现成功回调
  429. */
  430. void DiscoverySuccess(int subscribeId)
  431. {
  432. // 获取JNIEnv环境
  433. JNIEnv *env;
  434. // 将当前线程附加到Java虚拟机
  435. (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  436. // 获取当前对象的类引用
  437. jclass nativeLibClass = (*env)->GetObjectClass(env, globalRef);
  438. // 获取当前对象的publishSuccess方法的ID
  439. jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onDiscoverySuccess", "(I)V");
  440. //调用回调方法执行
  441. (*env)->CallVoidMethod(env, globalRef, callbackMethod, subscribeId);
  442. //将当前线程从java虚拟机中移除
  443. (*jvm)->DetachCurrentThread(jvm);
  444. printf("<DiscoverySuccess>CB: discover subscribeId=%d\n", subscribeId);
  445. }
  446. /**
  447. * 发现失败回调
  448. */
  449. void DiscoveryFailed(int subscribeId, DiscoveryFailReason reason)
  450. {
  451. // 获取JNIEnv环境
  452. JNIEnv *env;
  453. // 将当前线程附加到Java虚拟机
  454. (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  455. // 获取当前对象的类引用
  456. jclass nativeLibClass = (*env)->GetObjectClass(env, globalRef);
  457. // 获取当前对象的publishSuccess方法的ID
  458. jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onDiscoverFailed", "(II)V");
  459. // 调用当前对象的非静态方法
  460. (*env)->CallVoidMethod(env, globalRef, callbackMethod, subscribeId, (int)reason);
  461. //将当前线程从java虚拟机中移除
  462. (*jvm)->DetachCurrentThread(jvm);
  463. printf("<DiscoveryFailed>CB: discover subscribeId=%d failed, reason=%d\n", subscribeId, (int)reason);
  464. }
  465. JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SubscribeService_discoveryStart
  466. (JNIEnv *env, jobject obj, jstring pkgName, jobject subscribeInfo, jobject callback) {
  467. // 保存Java虚拟机的引用
  468. (*env)->GetJavaVM(env, &jvm);
  469. globalRef = (*env)->NewGlobalRef(env, callback);
  470. const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL);
  471. SubscribeInfo info;
  472. int ret = ParseSubscribeInfo(env, subscribeInfo, &info);
  473. if(ret != 0) {
  474. // 尝试进行一些可能会抛出异常的操作
  475. jclass exceptionClass = (*env)->FindClass(env, "java/lang/Exception"); // 获取异常类
  476. // 如果找不到异常类,则抛出异常
  477. jmethodID exceptionConstructor = (*env)->GetMethodID(env, exceptionClass, "<init>", "()V");
  478. jthrowable exception = (*env)->NewObject(env,exceptionClass, exceptionConstructor);
  479. // 抛出异常
  480. (*env)->ThrowNew(env, exceptionClass, "SubscribeInfo object error.");
  481. //解析失败无法继续操作
  482. return -1;
  483. }
  484. IDiscoveryCallback cb = {
  485. .OnDeviceFound = DeviceFound,
  486. .OnDiscoverFailed = DiscoveryFailed,
  487. .OnDiscoverySuccess = DiscoverySuccess
  488. };
  489. ret = StartDiscovery(pkgNameStr, &info, &cb);
  490. (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr);
  491. return ret;
  492. }
  493. JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SubscribeService_stopDiscovery
  494. (JNIEnv * env, jobject obj, jstring pkgName, jint subscribeId) {
  495. (*env)->GetJavaVM(env, &jvm);
  496. const char* pkgName_str = (*env)->GetStringUTFChars(env, pkgName, NULL);
  497. int ret = StopDiscovery(pkgName_str, subscribeId);
  498. if (ret) {
  499. // 尝试进行一些可能会抛出异常的操作
  500. jclass exceptionClass = (*env)->FindClass(env, "java/lang/Exception"); // 获取异常类
  501. // 如果找不到异常类,则抛出异常
  502. jmethodID exceptionConstructor = (*env)->GetMethodID(env, exceptionClass, "<init>", "()V");
  503. jthrowable exception = (*env)->NewObject(env, exceptionClass, exceptionConstructor);
  504. // 抛出异常
  505. (*env)->ThrowNew(env, exceptionClass, "stop discovery error.");
  506. printf("StopDiscovery fail:%d\n", ret);
  507. }
  508. printf("<stopDiscovery>stop discover pkgName=%s, subscribeId=%d\n", pkgName_str, subscribeId);
  509. (*env)->ReleaseStringUTFChars(env, pkgName, pkgName_str);
  510. return ret;
  511. }
  512. static void discoverResult(int32_t refreshId, RefreshResult reason) {
  513. // 获取JNIEnv环境
  514. JNIEnv *env;
  515. // 将当前线程附加到Java虚拟机
  516. (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  517. // 获取当前对象的类引用
  518. jclass nativeLibClass = (*env)->GetObjectClass(env, globalRef);
  519. // 获取当前对象的publishSuccess方法的ID
  520. jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onDiscoverResult", "(II)V");
  521. // 调用当前对象的非静态方法
  522. (*env)->CallVoidMethod(env, globalRef, callbackMethod, refreshId, (int)reason);
  523. // 将当前线程从Java虚拟机分离
  524. (*jvm)->DetachCurrentThread(jvm);
  525. printf("<DiscoveryResult>CB: discover subscribeId=%d failed, reason=%d\n", refreshId, (int)reason);
  526. }
  527. JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SubscribeService_refreshLNN
  528. (JNIEnv *env, jobject obj, jstring pkgName, jobject subscribeInfo, jobject callback){
  529. // 保存Java虚拟机的引用
  530. (*env)->GetJavaVM(env, &jvm);
  531. globalRef = (*env)->NewGlobalRef(env, callback);
  532. const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL);
  533. SubscribeInfo info;
  534. int ret = ParseSubscribeInfo(env, subscribeInfo, &info);
  535. if(ret != 0) {
  536. // 尝试进行一些可能会抛出异常的操作
  537. jclass exceptionClass = (*env)->FindClass(env, "java/lang/Exception"); // 获取异常类
  538. // 如果找不到异常类,则抛出异常
  539. jmethodID exceptionConstructor = (*env)->GetMethodID(env, exceptionClass, "<init>", "()V");
  540. jthrowable exception = (*env)->NewObject(env, exceptionClass, exceptionConstructor);
  541. // 抛出异常
  542. (*env)->ThrowNew(env, exceptionClass, "SubscribeInfo object error.");
  543. //解析失败无法继续操作
  544. return -1;
  545. }
  546. IRefreshCallback cb = {
  547. .OnDeviceFound = DeviceFound,
  548. .OnDiscoverResult = discoverResult,
  549. };
  550. ret = RefreshLNN(pkgNameStr, &info, &cb);
  551. (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr);
  552. return ret;
  553. }
  554. JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SubscribeService_stopRefreshLNN
  555. (JNIEnv * env, jobject obj, jstring pkgName, jint refreshId) {
  556. // 保存Java虚拟机的引用
  557. (*env)->GetJavaVM(env, &jvm);
  558. const char* pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL);
  559. // 停止刷新LNN
  560. int ret = StopRefreshLNN(pkgNameStr, refreshId);
  561. if (ret) {
  562. // 尝试进行一些可能会抛出异常的操作
  563. jclass exceptionClass = (*env)->FindClass(env, "java/lang/Exception"); // 获取异常类
  564. // 如果找不到异常类,则抛出异常
  565. jmethodID exceptionConstructor = (*env)->GetMethodID(env, exceptionClass, "<init>", "()V");
  566. jthrowable exception = (*env)->NewObject(env, exceptionClass, exceptionConstructor);
  567. // 抛出异常
  568. (*env)->ThrowNew(env, exceptionClass, "stop refreshLNN error.");
  569. printf("stop refreshLNN fail:%d\n", ret);
  570. }
  571. // 释放pkgNameStr
  572. (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr);
  573. return ret;
  574. }
  575. JNIEXPORT jobjectArray JNICALL Java_com_jg_softbus_naservice_SubscribeService_findDeviceNodes
  576. (JNIEnv *env, jobject obj, jstring pkgName) {
  577. // 保存Java虚拟机的引用
  578. (*env)->GetJavaVM(env, &jvm);
  579. const char* pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL);
  580. NodeBasicInfo **dev = NULL;
  581. int ret, num;
  582. ret = GetAllNodeDeviceInfo(pkgNameStr, dev, &num);
  583. if (ret) {
  584. // 尝试进行一些可能会抛出异常的操作
  585. jclass exceptionClass = (*env)->FindClass(env, "java/lang/Exception"); // 获取异常类
  586. // 如果找不到异常类,则抛出异常
  587. jmethodID exceptionConstructor = (*env)->GetMethodID(env, exceptionClass, "<init>", "()V");
  588. jthrowable exception = (*env)->NewObject(env, exceptionClass, exceptionConstructor);
  589. // 抛出异常
  590. (*env)->ThrowNew(env, exceptionClass, "get online device error.");
  591. printf("GetAllNodeDeviceInfo fail:%d\n", ret);
  592. return NULL;
  593. }
  594. jclass nodeClass = (*env)->FindClass(env, "com/jg/softbus/network/node/NodeBasicInfo");
  595. // 获取构造函数
  596. jmethodID nodeConstructor = (*env)->GetMethodID(env, nodeClass, "<init>", "(Ljava/lang/String;Ljava/lang/String;S)V");
  597. jobjectArray json_nodes = (*env)->NewObjectArray(env, num, nodeClass, NULL);
  598. printf("<GetAllNodeDeviceInfo>return %d Node\n", num);
  599. for (int i = 0; i < num; i++) {
  600. jstring networkId = (*env)->NewStringUTF(env, dev[i]->networkId);
  601. jstring deviceName = (*env)->NewStringUTF(env, dev[i]->deviceName);
  602. //构造node对象
  603. jobject node = (*env)->NewObject(env, nodeClass, nodeConstructor, networkId, deviceName, dev[i]->deviceTypeId);
  604. (*env)->SetObjectArrayElement(env, json_nodes, i, node);
  605. //释放字符串资源
  606. (*env)->DeleteLocalRef(env, networkId);
  607. (*env)->DeleteLocalRef(env, deviceName);
  608. (*env)->DeleteLocalRef(env, node);
  609. printf("<num %d>deviceName=%s\n", i + 1, dev[i]->deviceName);
  610. printf("\tnetworkId=%s\n", dev[i]->networkId);
  611. printf("\tdeviceTypeId=%d\n", dev[i]->deviceTypeId);
  612. }
  613. // 释放pkgNameStr
  614. (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr);
  615. return json_nodes;
  616. }
  617. JNIEXPORT void JNICALL Java_com_jg_softbus_naservice_SubscribeService_releaseDeviceNodes
  618. (JNIEnv *env, jobject obj, jobjectArray nodes) {
  619. // 保存Java虚拟机的引用
  620. (*env)->GetJavaVM(env, &jvm);
  621. // 释放创建的节点集合对象
  622. (*env)->DeleteLocalRef(env, nodes);
  623. }
  624. JNIEXPORT void JNICALL Java_com_jg_softbus_naservice_SubscribeService_destroy
  625. (JNIEnv *env, jobject obj) {
  626. printf("[subscribe]destory the subscribe data.\r\n");
  627. // 删除全局引用
  628. (*env)->DeleteGlobalRef(env, globalRef);
  629. printf("[subscribe]globalRef have been destory.\r\n");
  630. // if(jvm != NULL) {
  631. // free(jvm);
  632. // printf("[subscribe]jvm have been destory.\r\n");
  633. // }
  634. }