SoftbusSession.c 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <jni.h>
  6. #include "securec.h"
  7. #include "softbus_bus_center.h"
  8. #include "session.h"
  9. #include "com_jg_softbus_naservice_SessionService.h"
  10. // 全局变量,用于保存Java虚拟机的引用
  11. JavaVM *jvm;
  12. //全局引用变量sessionListener,用于保存java对象
  13. jobject sessionListener;
  14. //全局引用变量fileSendListener,用于保存java对象
  15. jobject fileSendListener;
  16. //全局引用变量fileReceiveListener,用于保存java对象
  17. jobject fileReceiveListener;
  18. /**
  19. * sessionOpen
  20. */
  21. int sessionOpened(int sessionId, int result)
  22. {
  23. // 获取JNIEnv环境
  24. JNIEnv *env;
  25. // 将当前线程附加到Java虚拟机
  26. (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  27. // 获取当前对象的类引用
  28. jclass nativeLibClass = (*env)->GetObjectClass(env, sessionListener);
  29. // 获取当前对象的onSessionOpened方法的ID
  30. jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onSessionOpened", "(II)I");
  31. // 调用当前对象的非静态方法
  32. int ret = (*env)->CallIntMethod(env, sessionListener, callbackMethod, sessionId, result);
  33. // 将当前线程从Java虚拟机分离
  34. (*jvm)->DetachCurrentThread(jvm);
  35. printf("<sessionOpened>sessionOpend: %d opened, result: %d.\n", sessionId, result);
  36. return ret;
  37. }
  38. /**
  39. * sessionClose
  40. */
  41. void sessionClosed(int sessionId) {
  42. // 获取JNIEnv环境
  43. JNIEnv *env;
  44. // 将当前线程附加到Java虚拟机
  45. (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  46. // 获取当前对象的类引用
  47. jclass nativeLibClass = (*env)->GetObjectClass(env, sessionListener);
  48. // 获取当前对象的onSessionClosed方法的ID
  49. jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onSessionClosed", "(I)V");
  50. // 调用当前对象的非静态方法
  51. (*env)->CallVoidMethod(env, sessionListener, callbackMethod, sessionId);
  52. // 将当前线程从Java虚拟机分离
  53. (*jvm)->DetachCurrentThread(jvm);
  54. printf("<sessionClosed>sessionClosed: %d closed.\n", sessionId);
  55. }
  56. /**
  57. * 接收bytes数据
  58. */
  59. void bytesReceived(int sessionId, const void *data, unsigned int dataLen) {
  60. // 获取JNIEnv环境
  61. JNIEnv *env;
  62. // 将当前线程附加到Java虚拟机
  63. (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  64. // 获取当前对象的类引用
  65. jclass nativeLibClass = (*env)->GetObjectClass(env, sessionListener);
  66. // 获取当前对象的onBytesReceived方法的ID
  67. jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onBytesReceived", "(I[BI)V");
  68. //转换data为byte[]数组
  69. jbyteArray byteArray = (*env)->NewByteArray(env, dataLen);
  70. jbyte *byteArrayElements = (*env)->GetByteArrayElements(env, byteArray, NULL);
  71. memcpy(byteArrayElements, data, dataLen);
  72. (*env)->ReleaseByteArrayElements(env, byteArray, byteArrayElements, 0);
  73. // 调用当前对象的非静态方法
  74. (*env)->CallVoidMethod(env, sessionListener, callbackMethod, sessionId, byteArray, dataLen);
  75. // 将当前线程从Java虚拟机分离
  76. (*jvm)->DetachCurrentThread(jvm);
  77. printf("<bytesReceived>bytesReceived: received data.\n");
  78. }
  79. /**
  80. * 接收消息数据
  81. */
  82. void messageReceived(int sessionId, const void *data, unsigned int dataLen) {
  83. // 获取JNIEnv环境
  84. JNIEnv *env;
  85. // 将当前线程附加到Java虚拟机
  86. (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  87. // 获取当前对象的类引用
  88. jclass nativeLibClass = (*env)->GetObjectClass(env, sessionListener);
  89. // 获取当前对象的publishSuccess方法的ID
  90. jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onMessageReceived", "(ILjava/lang/String;I)V");
  91. //转换data为string
  92. const char *charData = (const char *)data;
  93. jstring jstr = (*env)->NewStringUTF(env, charData);
  94. // 调用当前对象的非静态方法
  95. (*env)->CallVoidMethod(env, sessionListener, callbackMethod, sessionId, jstr, dataLen);
  96. // 将当前线程从Java虚拟机分离
  97. (*jvm)->DetachCurrentThread(jvm);
  98. printf("<messageReceived>messageReceived: received data:%s.\n", charData);
  99. }
  100. jobject parseStreamDataToJava(JNIEnv *env, const StreamData *data) {
  101. if(data == NULL) {
  102. return NULL;
  103. }
  104. //发现StreamData的java类
  105. jclass streamDataClass = (*env)->FindClass(env, "com/jg/softbus/session/StreamData");
  106. if (streamDataClass == NULL) {
  107. // 处理错误
  108. printf("Cannot found the class:com/jg/softbus/session/StreamData");
  109. return NULL;
  110. }
  111. //获取构造函数
  112. jmethodID constructor = (*env)->GetMethodID(env, streamDataClass, "<init>", "([BI)V");
  113. if(constructor == NULL) {
  114. // 处理错误
  115. printf("Cannot found the constructor(byte[], int):com/jg/softbus/session/StreamData");
  116. return NULL;
  117. }
  118. //将data中的buf字符转换为java的byte数组
  119. const char *charBuf = data->buf;
  120. jstring jstr = (*env)->NewStringUTF(env, charBuf);
  121. jsize len = (*env)->GetStringLength(env, jstr);
  122. jbyteArray byteArray = (*env)->NewByteArray(env, len);
  123. jboolean isCopy;
  124. jbyte *byteArrayElements = (*env)->GetByteArrayElements(env, byteArray, &isCopy);
  125. // 将 char *buf 复制到 jbyteArray 中
  126. for (jsize i = 0; i < len; i++) {
  127. byteArrayElements[i] = (jbyte)charBuf[i];
  128. }
  129. (*env)->ReleaseByteArrayElements(env, byteArray, byteArrayElements, 0);
  130. jobject obj = (*env)->NewObject(env, streamDataClass, constructor, byteArray, data->bufLen);
  131. (*env)->DeleteLocalRef(env, jstr);
  132. return obj;
  133. }
  134. /**
  135. * 解析StreamFrameInfo
  136. */
  137. jobject parseStreamFrameInfoToJava(JNIEnv *env, const StreamFrameInfo *param) {
  138. if(param == NULL) {
  139. return NULL;
  140. }
  141. //发现StreamFrameInfo的java类
  142. jclass streamFrameInfoClass = (*env)->FindClass(env, "com/jg/softbus/session/StreamFrameInfo");
  143. if (streamFrameInfoClass == NULL) {
  144. // 处理错误
  145. printf("Cannot found the class:com/jg/softbus/session/StreamFrameInfo");
  146. return NULL;
  147. }
  148. //获取构造函数
  149. jmethodID constructor = (*env)->GetMethodID(env, streamFrameInfoClass, "<init>", "()V");
  150. if(constructor == NULL) {
  151. // 处理错误
  152. printf("Cannot found the constructor():com/jg/softbus/session/StreamFrameInfo");
  153. return NULL;
  154. }
  155. jobject obj = (*env)->NewObject(env, streamFrameInfoClass, constructor);
  156. //获取setFrameType方法
  157. jmethodID setFrameTypeMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "setFrameType", "(I)V");
  158. (*env)->CallVoidMethod(env, obj, setFrameTypeMethod, param->frameType);
  159. //获取setTimeStamp方法
  160. jmethodID setTimeStampMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "setTimeStamp", "(J)V");
  161. (*env)->CallVoidMethod(env, obj, setTimeStampMethod, param->timeStamp);
  162. //setSeqNum
  163. jmethodID setSeqNumMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "setSeqNum", "(I)V");
  164. (*env)->CallVoidMethod(env, obj, setSeqNumMethod, param->seqNum);
  165. //setSeqSubNum
  166. jmethodID setSeqSubNumMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "setSeqSubNum", "(I)V");
  167. (*env)->CallVoidMethod(env, obj, setSeqSubNumMethod, param->seqSubNum);
  168. //setLevel
  169. jmethodID setLevelMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "setLevel", "(I)V");
  170. (*env)->CallVoidMethod(env, obj, setLevelMethod, param->level);
  171. //setBitMap
  172. jmethodID setBitMapMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "setBitMap", "(I)V");
  173. (*env)->CallVoidMethod(env, obj, setBitMapMethod, param->bitMap);
  174. //setTvCount
  175. jmethodID tvCountMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "tvCount", "(I)V");
  176. (*env)->CallVoidMethod(env, obj, tvCountMethod, param->tvCount);
  177. //setTvList
  178. //还想TV类型对象
  179. //发现StreamData的java类
  180. jclass tvClass = (*env)->FindClass(env, "com/jg/softbus/session/TV");
  181. if (tvClass == NULL) {
  182. // 处理错误
  183. printf("Cannot found the class:com/jg/softbus/session/TV");
  184. return obj;
  185. }
  186. //获取构造函数
  187. jmethodID tvConstructor = (*env)->GetMethodID(env, tvClass, "<init>", "([IJ)V");
  188. if(constructor == NULL) {
  189. // 处理错误
  190. printf("Cannot found the constructor(int, long):com/jg/softbus/session/TV");
  191. return obj;
  192. }
  193. //构建一个TV类型的数组
  194. jobjectArray tvArray = (*env)->NewObjectArray(env, param->tvCount, tvClass, NULL);
  195. for(int i=0; i<param->tvCount; i++) {
  196. jobject tvobject = (*env)->NewObject(env, tvClass, tvConstructor, param->tvList[i].type, param->tvList[i].value);
  197. (*env)->SetObjectArrayElement(env, tvArray, i, tvobject);
  198. (*env)->DeleteLocalRef(env, tvobject);
  199. }
  200. jmethodID setTvListMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "setTvList", "(I)V");
  201. (*env)->CallVoidMethod(env, obj, setTvListMethod, tvArray);
  202. (*env)->DeleteLocalRef(env, tvArray);
  203. return obj;
  204. }
  205. /**
  206. * 接收消息数据
  207. */
  208. void streamReceived(int sessionId, const StreamData *data, const StreamData *ext, const StreamFrameInfo *param) {
  209. // 获取JNIEnv环境
  210. JNIEnv *env;
  211. // 将当前线程附加到Java虚拟机
  212. (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  213. // 获取当前对象的类引用
  214. jclass nativeLibClass = (*env)->GetObjectClass(env, sessionListener);
  215. // 获取当前对象的onStreamReceived方法的ID
  216. jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onStreamReceived", "(ILcom/jg/softbus/session/StreamData;Lcom/jg/softbus/session/StreamData;Lcom/jg/softbus/session/StreamFrameInfo;)V");
  217. //转换data为string
  218. jobject streamData = parseStreamDataToJava(env, data);
  219. jobject extData = parseStreamDataToJava(env, ext);
  220. jobject streamframeInfo = parseStreamFrameInfoToJava(env, param);
  221. // 调用当前对象的非静态方法
  222. (*env)->CallVoidMethod(env, sessionListener, callbackMethod, sessionId, streamData, extData, streamframeInfo);
  223. // 将当前线程从Java虚拟机分离
  224. (*jvm)->DetachCurrentThread(jvm);
  225. printf("<streamReceived>streamReceived\n");
  226. }
  227. /**
  228. * 将c的WifiChannelQuality转换为java的对应对象 参见:com/jg/softbus/session/WifiChannelQuality
  229. */
  230. jobject parseWifiChannelQualityToJava(JNIEnv *env, const QosTv *tv) {
  231. jclass wifiChannelQualityClass = (*env)->FindClass(env, "com/jg/softbus/session/WifiChannelQuality");
  232. if (wifiChannelQualityClass == NULL) {
  233. // 处理错误
  234. printf("Cannot found the class:com/jg/softbus/session/WifiChannelQuality");
  235. return NULL;
  236. }
  237. //获取构造函数
  238. jmethodID wifiChannelQualityConstructor = (*env)->GetMethodID(env, wifiChannelQualityClass, "<init>", "(II)V");
  239. if(wifiChannelQualityConstructor == NULL) {
  240. // 处理错误
  241. printf("Cannot found the constructor():com/jg/softbus/session/WifiChannelQuality");
  242. return NULL;
  243. }
  244. return (*env)->NewObject(env, wifiChannelQualityClass, wifiChannelQualityConstructor, tv->info.wifiChannelInfo.channel, tv->info.wifiChannelInfo.score);
  245. }
  246. /**
  247. * 将c的FrameStatus结构转换为java对象,参见:com/jg/softbus/session/FrameStatus
  248. */
  249. jobject parseFrameStatusToJava(JNIEnv *env, const QosTv *tv) {
  250. jclass frameStatusClass = (*env)->FindClass(env, "com/jg/softbus/session/FrameStatus");
  251. if (frameStatusClass == NULL) {
  252. // 处理错误
  253. printf("Cannot found the class:com/jg/softbus/session/FrameStatus");
  254. return NULL;
  255. }
  256. //获取构造函数
  257. jmethodID frameStatusConstructor = (*env)->GetMethodID(env, frameStatusClass, "<init>", "(IIIII)V");
  258. if(frameStatusConstructor == NULL) {
  259. // 处理错误
  260. printf("Cannot found the constructor():com/jg/softbus/session/FrameStatus");
  261. return NULL;
  262. }
  263. return (*env)->NewObject(env, frameStatusClass, frameStatusConstructor, tv->info.frameStatusInfo.streamId, tv->info.frameStatusInfo.seqNum, tv->info.frameStatusInfo.level, tv->info.frameStatusInfo.transStatus, tv->info.frameStatusInfo.interval);
  264. }
  265. /**
  266. * 将c的BandwidthDetection结构转换为java对象 com/jg/softbus/session/BandwidthDetection
  267. */
  268. jobject parseBandwidthDetectionToJava(JNIEnv *env, const QosTv *tv) {
  269. jclass bandwidthDetectionClass = (*env)->FindClass(env, "com/jg/softbus/session/BandwidthDetection");
  270. if (bandwidthDetectionClass == NULL) {
  271. // 处理错误
  272. printf("Cannot found the class:com/jg/softbus/session/BandwidthDetection");
  273. return NULL;
  274. }
  275. //获取构造函数
  276. jmethodID bandwidthDetectionConstructor = (*env)->GetMethodID(env, bandwidthDetectionClass, "<init>", "(II)V");
  277. if(bandwidthDetectionConstructor == NULL) {
  278. // 处理错误
  279. printf("Cannot found the constructor():com/jg/softbus/session/BandwidthDetection");
  280. return NULL;
  281. }
  282. return (*env)->NewObject(env, bandwidthDetectionClass, bandwidthDetectionConstructor, tv->info.bandwidthInfo.trend, tv->info.bandwidthInfo.rate);
  283. }
  284. /**
  285. * 将c的JitterEstimation结构转换为java对象 com/jg/softbus/session/JitterEstimation
  286. */
  287. jobject parseJitterEstimationToJava(JNIEnv *env, const QosTv *tv) {
  288. jclass jitterEstimationClass = (*env)->FindClass(env, "com/jg/softbus/session/JitterEstimation");
  289. if (jitterEstimationClass == NULL) {
  290. // 处理错误
  291. printf("Cannot found the class:com/jg/softbus/session/JitterEstimation");
  292. return NULL;
  293. }
  294. //获取构造函数
  295. jmethodID jitterEstimationConstructor = (*env)->GetMethodID(env, jitterEstimationClass, "<init>", "(II)V");
  296. if(jitterEstimationConstructor == NULL) {
  297. // 处理错误
  298. printf("Cannot found the constructor():com/jg/softbus/session/JitterEstimation");
  299. return NULL;
  300. }
  301. return (*env)->NewObject(env, jitterEstimationClass, jitterEstimationConstructor, tv->info.jitterInfo.jitterLevel, tv->info.jitterInfo.bufferTime);
  302. }
  303. /**
  304. * 将c的StreamStatistics结构转换为java对象 com/jg/softbus/session/StreamStatistics
  305. */
  306. jobject parseStreamStatisticsToJava(JNIEnv *env, const QosTv *tv) {
  307. jclass streamStatisticsClass = (*env)->FindClass(env, "com/jg/softbus/session/StreamStatistics");
  308. if (streamStatisticsClass == NULL) {
  309. // 处理错误
  310. printf("Cannot found the class:com/jg/softbus/session/StreamStatistics");
  311. return NULL;
  312. }
  313. //获取构造函数
  314. jmethodID streamStatisticsConstructor = (*env)->GetMethodID(env, streamStatisticsClass, "<init>", "()V");
  315. if(streamStatisticsConstructor == NULL) {
  316. // 处理错误
  317. printf("Cannot found the constructor():com/jg/softbus/session/StreamStatistics");
  318. return NULL;
  319. }
  320. jobject streamStatisticsObj = (*env)->NewObject(env, streamStatisticsClass, streamStatisticsConstructor);
  321. //setStatisticsGotTime
  322. jmethodID setStatisticsGotTimeMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setStatisticsGotTime", "(J)V");
  323. (*env)->CallVoidMethod(env, streamStatisticsObj, setStatisticsGotTimeMethod, tv->info.appStatistics.statisticsGotTime);
  324. //setPeriodRecvBits
  325. jmethodID setPeriodRecvBitsMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodRecvBits", "(J)V");
  326. (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodRecvBitsMethod, tv->info.appStatistics.periodRecvBits);
  327. //setPktNum
  328. jmethodID setPktNumMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPktNum", "(I)V");
  329. (*env)->CallVoidMethod(env, streamStatisticsObj, setPktNumMethod, tv->info.appStatistics.pktNum);
  330. //setPeriodRecvPkts
  331. jmethodID setPeriodRecvPktsMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodRecvBits", "(I)V");
  332. (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodRecvPktsMethod, tv->info.appStatistics.periodRecvPkts);
  333. //setPeriodRecvPktLoss
  334. jmethodID setPeriodRecvPktLossMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodRecvPktLoss", "(I)V");
  335. (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodRecvPktLossMethod, tv->info.appStatistics.periodRecvPktLoss);
  336. //setPeriodRecvRate
  337. jmethodID setPeriodRecvRateMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodRecvRate", "(I)V");
  338. (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodRecvRateMethod, tv->info.appStatistics.periodRecvRate);
  339. //setPeriodRecvRateBps
  340. jmethodID setPeriodRecvRateBpsMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodRecvRateBps", "(J)V");
  341. (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodRecvRateBpsMethod, tv->info.appStatistics.periodRecvRateBps);
  342. //setPeriodRtt
  343. jmethodID setPeriodRttMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodRtt", "(I)V");
  344. (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodRttMethod, tv->info.appStatistics.periodRtt);
  345. //setPeriodRecvPktLossHighPrecision
  346. jmethodID setPeriodRecvPktLossHighPrecisionMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodRecvPktLossHighPrecision", "(I)V");
  347. (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodRecvPktLossHighPrecisionMethod, tv->info.appStatistics.periodRecvPktLossHighPrecision);
  348. //setPeriodSendLostPkts
  349. jmethodID setPeriodSendLostPktsMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodSendLostPkts", "(I)V");
  350. (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodSendLostPktsMethod, tv->info.appStatistics.periodSendLostPkts);
  351. //setPeriodSendPkts
  352. jmethodID setPeriodSendPktsMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodSendPkts", "(I)V");
  353. (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodSendPktsMethod, tv->info.appStatistics.periodSendPkts);
  354. //setPeriodSendPktLossHighPrecision
  355. jmethodID setPeriodSendPktLossHighPrecisionMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodSendPktLossHighPrecision", "(I)V");
  356. (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodSendPktLossHighPrecisionMethod, tv->info.appStatistics.periodSendPktLossHighPrecision);
  357. //setPeriodSendBits
  358. jmethodID setPeriodSendBitsMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodSendBits", "(J)V");
  359. (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodSendBitsMethod, tv->info.appStatistics.periodSendBits);
  360. //setPeriodSendRateBps
  361. jmethodID setPeriodSendRateBpsMethod = (*env)->GetMethodID(env, streamStatisticsClass, "setPeriodSendRateBps", "(J)V");
  362. (*env)->CallVoidMethod(env, streamStatisticsObj, setPeriodSendRateBpsMethod, tv->info.appStatistics.periodSendRateBps);
  363. return streamStatisticsObj;
  364. }
  365. /**
  366. * 将c的QosTvInfo结构转换为java对应的对象
  367. */
  368. jobject parseQosTvInfoToJava(JNIEnv *env, const QosTv *tv) {
  369. jclass qosTvInfoClass = (*env)->FindClass(env, "com/jg/softbus/session/QosTvInfo");
  370. if (qosTvInfoClass == NULL) {
  371. // 处理错误
  372. printf("Cannot found the class:com/jg/softbus/session/QosTvInfo");
  373. return NULL;
  374. }
  375. //获取构造函数
  376. jmethodID qosTvInfoConstructor = (*env)->GetMethodID(env, qosTvInfoClass, "<init>", "()V");
  377. if(qosTvInfoConstructor == NULL) {
  378. // 处理错误
  379. printf("Cannot found the constructor():com/jg/softbus/session/QosTvInfo");
  380. return NULL;
  381. }
  382. //创建qosTvInfo
  383. jobject qosTvInfoobject = (*env)->NewObject(env, qosTvInfoClass, qosTvInfoConstructor);
  384. //setWifiChannelInfo com/jg/softbus/session/WifiChannelQuality
  385. jobject wifiChannelQualityObj = parseWifiChannelQualityToJava(env, tv);
  386. jmethodID setWifiChannelInfoMethod = (*env)->GetMethodID(env, qosTvInfoClass, "setWifiChannelInfo", "(Lcom/jg/softbus/session/WifiChannelQuality;)V");
  387. (*env)->CallVoidMethod(env, qosTvInfoobject, setWifiChannelInfoMethod, wifiChannelQualityObj);
  388. (*env)->DeleteLocalRef(env, wifiChannelQualityObj);
  389. //setFrameStatusInfo com/jg/softbus/session/FrameStatus
  390. jobject frameStatusObj = parseFrameStatusToJava(env, tv);
  391. jmethodID setFrameStatusInfoMethod = (*env)->GetMethodID(env, qosTvInfoClass, "setFrameStatusInfo", "(Lcom/jg/softbus/session/FrameStatus;)V");
  392. (*env)->CallVoidMethod(env, qosTvInfoobject, setFrameStatusInfoMethod, frameStatusObj);
  393. (*env)->DeleteLocalRef(env, frameStatusObj);
  394. //setBandwidthInfo com/jg/softbus/session/BandwidthDetection
  395. jobject bandwidthDetectionObj = parseBandwidthDetectionToJava(env, tv);
  396. jmethodID setBandwidthInfoMethod = (*env)->GetMethodID(env, qosTvInfoClass, "setBandwidthInfo", "(Lcom/jg/softbus/session/BandwidthDetection;)V");
  397. (*env)->CallVoidMethod(env, qosTvInfoobject, setBandwidthInfoMethod, bandwidthDetectionObj);
  398. (*env)->DeleteLocalRef(env, bandwidthDetectionObj);
  399. //setJitterInfo com/jg/softbus/session/JitterEstimation
  400. jobject jitterEstimationObj = parseJitterEstimationToJava(env, tv);
  401. jmethodID setJitterInfoMethod = (*env)->GetMethodID(env, qosTvInfoClass, "setJitterInfo", "(Lcom/jg/softbus/session/JitterEstimation;)V");
  402. (*env)->CallVoidMethod(env, qosTvInfoobject, setJitterInfoMethod, jitterEstimationObj);
  403. (*env)->DeleteLocalRef(env, jitterEstimationObj);
  404. //setAppStatistics com/jg/softbus/session/StreamStatistics
  405. jobject streamStatisticsObj = parseStreamStatisticsToJava(env, tv);
  406. jmethodID setAppStatisticsMethod = (*env)->GetMethodID(env, qosTvInfoClass, "setAppStatistics", "(Lcom/jg/softbus/session/StreamStatistics;)V");
  407. (*env)->CallVoidMethod(env, qosTvInfoobject, setAppStatisticsMethod, streamStatisticsObj);
  408. (*env)->DeleteLocalRef(env, streamStatisticsObj);
  409. return qosTvInfoobject;
  410. }
  411. /**
  412. * 将c的QosTv结构转换为java对应对象
  413. */
  414. jobject parseQosTvToJavaObject(JNIEnv *env, const QosTv *tv) {
  415. jclass qosTvClass = (*env)->FindClass(env, "com/jg/softbus/session/QosTv");
  416. if (qosTvClass == NULL) {
  417. // 处理错误
  418. printf("Cannot found the class:com/jg/softbus/session/QosTv");
  419. return NULL;
  420. }
  421. //获取构造函数
  422. jmethodID qosTvConstructor = (*env)->GetMethodID(env, qosTvClass, "<init>", "()V");
  423. if(qosTvConstructor == NULL) {
  424. // 处理错误
  425. printf("Cannot found the constructor():com/jg/softbus/session/QosTv");
  426. return NULL;
  427. }
  428. jobject tvobject = (*env)->NewObject(env, qosTvClass, qosTvConstructor);
  429. jclass transEnumEventTypeClass = (*env)->FindClass(env, "com/jg/softbus/session/enums/TransEnumEventType");
  430. if (transEnumEventTypeClass == NULL) {
  431. // 处理错误
  432. printf("Cannot found the class:com/jg/softbus/session/enums/TransEnumEventType");
  433. return NULL;
  434. }
  435. jmethodID getForValueMethod = (*env)->GetStaticMethodID(env, transEnumEventTypeClass, "getForValue", "(I)Lcom/jg/softbus/session/enums/TransEnumEventType;");
  436. if (getForValueMethod == NULL) {
  437. // 处理错误
  438. printf("Cannot found the static method:getForValue(int)");
  439. return NULL;
  440. }
  441. //setType
  442. jobject transEnumEventTypeObj = (*env)->CallStaticObjectMethod(env, transEnumEventTypeClass, getForValueMethod, tv->type);
  443. jmethodID setTypeMethod = (*env)->GetMethodID(env, qosTvClass, "setType", "(Lcom/jg/softbus/session/enums/TransEnumEventType;)V");
  444. (*env)->CallVoidMethod(env, tvobject, setTypeMethod, transEnumEventTypeObj);
  445. (*env)->DeleteLocalRef(env, transEnumEventTypeObj);
  446. //setInfo com/jg/softbus/session/QosTvInfo
  447. jobject qosTvInfoobject = parseQosTvInfoToJava(env, tv);
  448. jmethodID setInfoMethod = (*env)->GetMethodID(env, qosTvClass, "setInfo", "(Lcom/jg/softbus/session/QosTvInfo;)V");
  449. (*env)->CallVoidMethod(env, tvobject, setInfoMethod, qosTvInfoobject);
  450. (*env)->DeleteLocalRef(env, qosTvInfoobject);
  451. return tvobject;
  452. }
  453. /**
  454. * tvList
  455. */
  456. jobjectArray parseQosTvListToJava(JNIEnv *env, int tvCount, const QosTv *tvList, jclass qosTvClass) {
  457. if(tvList == NULL) {
  458. return NULL;
  459. }
  460. //构建一个TV类型的数组
  461. jobjectArray tvArray = (*env)->NewObjectArray(env, tvCount, qosTvClass, NULL);
  462. for(int i=0; i<tvCount; i++) {
  463. jobject tvobject = parseQosTvToJavaObject(env, &tvList[i]);
  464. (*env)->SetObjectArrayElement(env, tvArray, i, tvobject);
  465. (*env)->DeleteLocalRef(env, tvobject);
  466. }
  467. return tvArray;
  468. }
  469. /**
  470. * qosEvent
  471. */
  472. void qosEvent(int sessionId, int eventId, int tvCount, const QosTv *tvList) {
  473. // 获取JNIEnv环境
  474. JNIEnv *env;
  475. // 将当前线程附加到Java虚拟机
  476. (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  477. // 获取当前对象的类引用
  478. jclass nativeLibClass = (*env)->GetObjectClass(env, sessionListener);
  479. // 获取当前对象的onQosEvent方法的ID
  480. jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onQosEvent", "(III[Lcom/jg/softbus/session/QosTv;)V");
  481. //转换data为string
  482. jobjectArray tvListArray = parseQosTvListToJava(env, tvCount, tvList, nativeLibClass);
  483. // 调用当前对象的非静态方法
  484. (*env)->CallVoidMethod(env, sessionListener, callbackMethod, sessionId, eventId, tvCount, tvListArray);
  485. // 将当前线程从Java虚拟机分离
  486. (*jvm)->DetachCurrentThread(jvm);
  487. printf("<streamReceived>streamReceived\n");
  488. }
  489. /*
  490. * Class: com_jg_softbus_naservice_SessionService
  491. * Method: createSessionServer
  492. * Signature: (Ljava/lang/String;Ljava/lang/String;Lcom/jg/softbus/session/callback/ISessionListener;)I
  493. */
  494. JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SessionService_createSessionServer
  495. (JNIEnv *env, jobject obj, jstring pkgName, jstring sessionName, jobject listener) {
  496. // 保存Java虚拟机的引用
  497. (*env)->GetJavaVM(env, &jvm);
  498. sessionListener = (*env)->NewGlobalRef(env, listener);
  499. //包名处理
  500. const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL);
  501. const char *sessionNameStr = (*env)->GetStringUTFChars(env, sessionName, NULL);
  502. ISessionListener sl = {
  503. .OnSessionOpened = sessionOpened,
  504. .OnSessionClosed = sessionClosed,
  505. .OnBytesReceived = bytesReceived,
  506. .OnMessageReceived = messageReceived,
  507. .OnStreamReceived = streamReceived,
  508. .OnQosEvent = qosEvent
  509. };
  510. printf("[jni] create session server..........\n");
  511. int ret = CreateSessionServer(pkgNameStr, sessionNameStr, &sl);
  512. printf("[jni] create session server completed. the result: %d\n", ret);
  513. (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr);
  514. (*env)->ReleaseStringUTFChars(env, sessionName, sessionNameStr);
  515. return ret;
  516. }
  517. /**
  518. * 解析sessionAttribute
  519. */
  520. int parseSessionAttribute(JNIEnv *env, jobject sessionAttr, SessionAttribute *attr) {
  521. if(sessionAttr == NULL) {
  522. return -1;
  523. }
  524. jclass sessionAttrClass = (*env)->GetObjectClass(env, sessionAttr);
  525. jmethodID getDataTypeMethod = (*env)->GetMethodID(env, sessionAttrClass, "getDataType", "()I");
  526. jint dataType = (*env)->CallIntMethod(env, sessionAttr, getDataTypeMethod);
  527. attr->dataType = dataType;
  528. printf("SessionAttribute->dataType:%d\n", attr->dataType);
  529. jmethodID getLinkTypeNumMethod = (*env)->GetMethodID(env, sessionAttrClass, "getLinkTypeNum", "()I");
  530. jint linkTypeNum = (*env)->CallIntMethod(env, sessionAttr, getLinkTypeNumMethod);
  531. attr->linkTypeNum = linkTypeNum;
  532. printf("SessionAttribute->linkTypeNum:%d\n", attr->linkTypeNum);
  533. //getLinkType linkType
  534. LinkType linkTypeEnum[linkTypeNum];
  535. jmethodID getLinkTypeMethod = (*env)->GetMethodID(env, sessionAttrClass, "getLinkType", "()[Lcom/jg/softbus/session/enums/LinkType;");
  536. jobjectArray linkTypes = (*env)->CallObjectMethod(env, sessionAttr, getLinkTypeMethod);
  537. jsize length = (*env)->GetArrayLength(env, linkTypes);
  538. for (jsize i = 0; i < length; i++) {
  539. jobject linkTypeObj = (*env)->GetObjectArrayElement(env, linkTypes, i);
  540. jclass linkTypeObjClass = (*env)->GetObjectClass(env, linkTypeObj);
  541. jmethodID getLinkTypeValueOfMethod = (*env)->GetMethodID(env, linkTypeObjClass, "valueOf", "()I");
  542. jint linkTypeValue = (*env)->CallIntMethod(env, linkTypeObj, getLinkTypeValueOfMethod);
  543. linkTypeEnum[i] = (LinkType)linkTypeValue;
  544. printf("SessionAttribute->linkeType[%d]: %d\n", i, linkTypeEnum[i]);
  545. }
  546. memcpy(attr->linkType, linkTypeEnum, linkTypeNum);
  547. free(linkTypeEnum);
  548. //StreamAttr attr getAttr
  549. jmethodID getAttrMethod = (*env)->GetMethodID(env, sessionAttrClass, "getAttr", "()Lcom/jg/softbus/session/StreamAttr;");
  550. jobject attrObj = (*env)->CallObjectMethod(env, sessionAttr, getAttrMethod);
  551. if(attrObj != NULL) {
  552. jclass attrObjClass = (*env)->GetObjectClass(env, attrObj);
  553. jmethodID getStreamTypeMethod = (*env)->GetMethodID(env, attrObjClass, "getStreamType", "()I");
  554. jint streamType = (*env)->CallIntMethod(env, attrObj, getStreamTypeMethod);
  555. attr->attr.streamAttr.streamType = linkTypeNum;
  556. printf("attr->attr.streamAttr.streamType: %d", linkTypeNum);
  557. }
  558. //getFastTransData byte
  559. // jmethodID getFastTransDataMethod = (*env)->GetMethodID(env, sessionAttrClass, "getFastTransData", "()[B");
  560. // jbyteArray fastTransData = (*env)->CallObjectMethod(env, sessionAttr, getFastTransDataMethod);
  561. // // 获取数组长度
  562. // jsize fastTransDataLength = (*env)->GetArrayLength(fastTransData);
  563. // // 分配 uint8_t 数组
  564. // uint8_t *transData[fastTransDataLength];
  565. // // 将 jbyteArray 转换为 uint8_t 数组
  566. // (*env)->GetByteArrayRegion(env, fastTransData, 0, length, (jbyte *) transData);
  567. // attr->fastTransData = transData;
  568. // free(transData);
  569. //getFastTransDataSize short
  570. // jmethodID getFastTransDataSizeMethod = (*env)->GetMethodID(env, sessionAttrClass, "getFastTransDataSize", "()S");
  571. // jbyte transDataSize = (*env)->CallObjectMethod(env, sessionAttr, getFastTransDataSizeMethod);
  572. // attr->fastTransDataSize = transDataSize;
  573. return 0;
  574. }
  575. /*
  576. * Class: com_jg_softbus_naservice_SessionService
  577. * Method: openSession
  578. * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lcom/jg/softbus/session/SessionAttribute;)I
  579. */
  580. JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SessionService_openSession
  581. (JNIEnv *env, jobject obj, jstring sessionName, jstring peerSessionName, jstring peerNetworkId, jstring groupId, jobject sessionAttr) {
  582. // 保存Java虚拟机的引用
  583. (*env)->GetJavaVM(env, &jvm);
  584. //包名处理
  585. const char *sessionNameStr = (*env)->GetStringUTFChars(env, sessionName, NULL);
  586. const char *peerSessionNameStr = (*env)->GetStringUTFChars(env, peerSessionName, NULL);
  587. const char *peerNetworkIdStr = (*env)->GetStringUTFChars(env, peerNetworkId, NULL);
  588. const char *groupIdStr = (*env)->GetStringUTFChars(env, groupId, NULL);
  589. //转换SessionAttribute
  590. SessionAttribute attr;
  591. int ret = parseSessionAttribute(env, sessionAttr, &attr);
  592. if(ret != 0) {
  593. // 尝试进行一些可能会抛出异常的操作
  594. jclass exceptionClass = (*env)->FindClass(env, "java/lang/Exception"); // 获取异常类
  595. // 如果找不到异常类,则抛出异常
  596. jmethodID exceptionConstructor = (*env)->GetMethodID(env, exceptionClass, "<init>", "()V");
  597. jthrowable exception = (*env)->NewObject(env,exceptionClass, exceptionConstructor);
  598. // 抛出异常
  599. (*env)->ThrowNew(env, exceptionClass, "SessionAttribute object error.");
  600. //解析失败无法继续操作
  601. return -1;
  602. }
  603. // 创建会话
  604. ret = OpenSession(sessionNameStr, peerSessionNameStr, peerNetworkIdStr, groupIdStr, &attr);
  605. (*env)->ReleaseStringUTFChars(env, sessionName, sessionNameStr);
  606. (*env)->ReleaseStringUTFChars(env, peerSessionName, peerSessionNameStr);
  607. (*env)->ReleaseStringUTFChars(env, peerNetworkId, peerNetworkIdStr);
  608. (*env)->ReleaseStringUTFChars(env, groupId, groupIdStr);
  609. return ret;
  610. }
  611. /*
  612. * Class: com_jg_softbus_naservice_SessionService
  613. * Method: sendBytes
  614. * Signature: (ILjava/lang/String;)I
  615. */
  616. JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SessionService_sendBytes
  617. (JNIEnv *env, jobject obj, jint sessionId, jbyteArray byteArray, jint len) {
  618. // 保存Java虚拟机的引用
  619. (*env)->GetJavaVM(env, &jvm);
  620. jboolean isCopy;
  621. jbyte *byteArrayElements = (*env)->GetByteArrayElements(env, byteArray, &isCopy);
  622. if (byteArrayElements == NULL) {
  623. // 处理获取数组元素失败的情况
  624. return -1;
  625. }
  626. // 将 jbyteArray 转换为 const void *data
  627. const void *data = byteArrayElements;
  628. (*env)->ReleaseByteArrayElements(env, byteArray, byteArrayElements, 0);
  629. return SendBytes(sessionId, data, len);
  630. }
  631. /*
  632. * Class: com_jg_softbus_naservice_SessionService
  633. * Method: sendMessage
  634. * Signature: (ILjava/lang/String;)I
  635. */
  636. JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SessionService_sendMessage
  637. (JNIEnv *env, jobject obj, jint sessionId, jstring message, jint len) {
  638. // 保存Java虚拟机的引用
  639. (*env)->GetJavaVM(env, &jvm);
  640. const char *charStr = (*env)->GetStringUTFChars(env, message, NULL);
  641. if (charStr == NULL) {
  642. // 处理内存分配失败的情况
  643. (*env)->ReleaseStringUTFChars(env, message, charStr);
  644. return -1;
  645. }
  646. // 将 jstring 转换为 const void *data
  647. const void *data = (const void *)charStr;
  648. int ret = SendMessage(sessionId, data, len);
  649. (*env)->ReleaseStringUTFChars(env, message, charStr);
  650. return ret;
  651. }
  652. int parseStreamData(JNIEnv *env, jobject streamData, StreamData *data) {
  653. if(data == NULL) {
  654. return -1;
  655. }
  656. //获取StreamData的java类
  657. jclass sessionAttrClass = (*env)->GetObjectClass(env, streamData);
  658. jmethodID getBufMethod = (*env)->GetMethodID(env, sessionAttrClass, "getBuf", "()[B");
  659. jbyteArray byteArray = (*env)->CallObjectMethod(env, streamData, getBufMethod);
  660. jmethodID getBufLenMethod = (*env)->GetMethodID(env, sessionAttrClass, "getBufLen", "()I");
  661. jint bufLen = (*env)->CallIntMethod(env, streamData, getBufLenMethod);
  662. data->bufLen = bufLen;
  663. char buf[bufLen];
  664. // 将jbyteArray中的元素复制到char*类型的缓冲区中
  665. (*env)->GetByteArrayRegion(env, byteArray, 0, bufLen, (jbyte*)buf);
  666. data->buf = buf;
  667. return 0;
  668. }
  669. /**
  670. * 解析streamframeinfo
  671. */
  672. int parseStreamFrameInfo(JNIEnv *env, jobject param, StreamFrameInfo *data) {
  673. if(data == NULL) {
  674. return -1;
  675. }
  676. //获取StreamData的java类
  677. jclass streamFrameInfoClass = (*env)->GetObjectClass(env, param);
  678. jmethodID getFrameTypeMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "getFrameType", "()I");
  679. jint frameType = (*env)->CallIntMethod(env, param, getFrameTypeMethod);
  680. data->frameType = frameType;
  681. jmethodID getTimeStampMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "getTimeStamp", "()J");
  682. jlong timeStamp = (*env)->CallLongMethod(env, param, getTimeStampMethod);
  683. data->timeStamp = (int64_t)timeStamp;
  684. jmethodID getSeqNumMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "getSeqNum", "()I");
  685. jint seqNum = (*env)->CallIntMethod(env, param, getSeqNumMethod);
  686. data->seqNum = seqNum;
  687. jmethodID getSeqSubNumMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "getSeqSubNum", "()I");
  688. jint seqSubNum = (*env)->CallIntMethod(env, param, getSeqSubNumMethod);
  689. data->seqSubNum = seqSubNum;
  690. jmethodID getLevelMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "getLevel", "()I");
  691. jint level = (*env)->CallIntMethod(env, param, getLevelMethod);
  692. data->level = level;
  693. jmethodID getBitMapMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "getBitMap", "()I");
  694. jint bitMap = (*env)->CallIntMethod(env, param, getBitMapMethod);
  695. data->bitMap = bitMap;
  696. jmethodID getTvCountMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "getTvCount", "()I");
  697. jint tvCount = (*env)->CallIntMethod(env, param, getTvCountMethod);
  698. data->tvCount = tvCount;
  699. jmethodID getTvListMethod = (*env)->GetMethodID(env, streamFrameInfoClass, "getTvList", "()Lcom/jg/softbus/session/TV;");
  700. jobjectArray tvListArray = (*env)->CallObjectMethod(env, param, getTvListMethod);
  701. TV tvList[tvCount];
  702. for(int i=0; i<tvCount; i++) {
  703. jobject tvObject = (*env)->GetObjectArrayElement(env, tvListArray, i);
  704. if(tvObject != NULL) {
  705. jclass tvObjectClass = (*env)->GetObjectClass(env, tvObject);
  706. jmethodID tvGetTypeMethod = (*env)->GetMethodID(env, tvObjectClass, "getType", "()I");
  707. jint tvType = (*env)->CallIntMethod(env, tvObject, tvGetTypeMethod);
  708. jmethodID tvGetValueMethod = (*env)->GetMethodID(env, tvObjectClass, "getValue", "()J");
  709. jlong tvValue = (*env)->CallLongMethod(env, tvObject, tvGetValueMethod);
  710. tvList[i].type = (int)tvType;
  711. tvList[i].value = (int64_t)tvValue;
  712. }
  713. (*env)->DeleteLocalRef(env, tvObject);
  714. }
  715. data->tvList = tvList;
  716. }
  717. /*
  718. * Class: com_jg_softbus_naservice_SessionService
  719. * Method: sendStream
  720. * Signature: (ILcom/jg/softbus/session/StreamData;Lcom/jg/softbus/session/StreamData;Lcom/jg/softbus/session/StreamFrameInfo;)I
  721. */
  722. JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SessionService_sendStream
  723. (JNIEnv *env, jobject obj, jint sessionId, jobject streamData, jobject ext, jobject param) {
  724. // 保存Java虚拟机的引用
  725. (*env)->GetJavaVM(env, &jvm);
  726. StreamData data;
  727. int ret = parseStreamData(env, streamData, &data);
  728. if(ret != 0) {
  729. // 尝试进行一些可能会抛出异常的操作
  730. jclass exceptionClass = (*env)->FindClass(env, "java/lang/Exception"); // 获取异常类
  731. // 如果找不到异常类,则抛出异常
  732. jmethodID exceptionConstructor = (*env)->GetMethodID(env, exceptionClass, "<init>", "()V");
  733. jthrowable exception = (*env)->NewObject(env,exceptionClass, exceptionConstructor);
  734. // 抛出异常
  735. (*env)->ThrowNew(env, exceptionClass, "StreamData object error.");
  736. //解析失败无法继续操作
  737. return -1;
  738. }
  739. StreamData extData;
  740. parseStreamData(env, ext, &extData);
  741. StreamFrameInfo sfi;
  742. parseStreamFrameInfo(env, param, &sfi);
  743. ret = SendStream(sessionId, &data, &extData, &sfi);
  744. return ret;
  745. }
  746. /*
  747. * Class: com_jg_softbus_naservice_SessionService
  748. * Method: sendFile
  749. * Signature: (I[Ljava/lang/String;[Ljava/lang/String;I)I
  750. */
  751. JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SessionService_sendFile
  752. (JNIEnv *env, jobject obj, jint sessionId, jobjectArray sFileList, jobjectArray dFileList, jint fileCnt) {
  753. // 保存Java虚拟机的引用
  754. (*env)->GetJavaVM(env, &jvm);
  755. // 获取数组长度
  756. jsize sFileLen = (*env)->GetArrayLength(env, sFileList);
  757. const char *sFiles[sFileLen];
  758. for(jsize i=0; i< sFileLen; i++) {
  759. jstring sFile = (*env)->GetObjectArrayElement(env, sFileList, i);
  760. const char *sFileStr = (*env)->GetStringUTFChars(env, sFile, NULL);
  761. sFiles[i] = sFileStr;
  762. (*env)->ReleaseStringUTFChars(env, sFile, sFileStr);
  763. (*env)->DeleteLocalRef(env, sFile);
  764. }
  765. jsize dFileLen = (*env)->GetArrayLength(env, dFileList);
  766. const char *dFiles[dFileLen];
  767. for(jsize i=0; i< dFileLen; i++) {
  768. jstring dFile = (*env)->GetObjectArrayElement(env, dFileList, i);
  769. const char *dFileStr = (*env)->GetStringUTFChars(env, dFile, NULL);
  770. dFiles[i] = dFileStr;
  771. (*env)->ReleaseStringUTFChars(env, dFile, dFileStr);
  772. (*env)->DeleteLocalRef(env, dFile);
  773. }
  774. return SendFile(sessionId, sFiles, dFiles, fileCnt);
  775. }
  776. /**
  777. * 发送进度回调
  778. */
  779. int sendFileProcess(int sessionId, uint64_t bytesUpload, uint64_t bytesTotal) {
  780. // 获取JNIEnv环境
  781. JNIEnv *env;
  782. // 将当前线程附加到Java虚拟机
  783. (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  784. // 获取当前对象的类引用
  785. jclass nativeLibClass = (*env)->GetObjectClass(env, fileSendListener);
  786. // 获取当前对象的onQosEvent方法的ID
  787. jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onSendFileProcess", "(IJJ)I");
  788. // 调用当前对象的非静态方法
  789. jint ret = (*env)->CallIntMethod(env, fileSendListener, callbackMethod, sessionId, bytesUpload, bytesTotal);
  790. // 将当前线程从Java虚拟机分离
  791. (*jvm)->DetachCurrentThread(jvm);
  792. printf("<sendFileProcess>sendFileProcess, sessionId:%d, send bytes:%d\n", sessionId, bytesUpload);
  793. return ret;
  794. }
  795. /**
  796. * 发送完成回调
  797. */
  798. int sendFileFinished(int sessionId, const char *firstFile) {
  799. // 获取JNIEnv环境
  800. JNIEnv *env;
  801. // 将当前线程附加到Java虚拟机
  802. (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  803. // 获取当前对象的类引用
  804. jclass nativeLibClass = (*env)->GetObjectClass(env, fileSendListener);
  805. // 获取当前对象的onQosEvent方法的ID
  806. jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onSendFileFinished", "(ILjava/lang/String;)I");
  807. jstring firstFileStr = (*env)->NewStringUTF(env, firstFile);
  808. // 调用当前对象的非静态方法
  809. jint ret = (*env)->CallIntMethod(env, fileSendListener, callbackMethod, sessionId, firstFileStr);
  810. // 将当前线程从Java虚拟机分离
  811. (*jvm)->DetachCurrentThread(jvm);
  812. printf("<sendFileFinished>sendFileFinished, sessionId:%d, firstFile:%s\n", sessionId, firstFile);
  813. return ret;
  814. }
  815. /**
  816. * 发送报错
  817. */
  818. void sendFileTransError(int sessionId) {
  819. // 获取JNIEnv环境
  820. JNIEnv *env;
  821. // 将当前线程附加到Java虚拟机
  822. (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  823. // 获取当前对象的类引用
  824. jclass nativeLibClass = (*env)->GetObjectClass(env, fileSendListener);
  825. // 获取当前对象的onQosEvent方法的ID
  826. jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onFileTransError", "(I)V");
  827. // 调用当前对象的非静态方法
  828. (*env)->CallVoidMethod(env, fileSendListener, callbackMethod, sessionId);
  829. // 将当前线程从Java虚拟机分离
  830. (*jvm)->DetachCurrentThread(jvm);
  831. printf("<sendFileTransError>sendFileTransError, sessionId:%d\n", sessionId);
  832. }
  833. /*
  834. * Class: com_jg_softbus_naservice_SessionService
  835. * Method: setFileSendListener
  836. * Signature: (Ljava/lang/String;Ljava/lang/String;Lcom/jg/softbus/session/callback/IFileSendListener;)I
  837. */
  838. JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SessionService_setFileSendListener
  839. (JNIEnv *env, jobject obj, jstring pkgName, jstring sessionName, jobject listener) {
  840. // 保存Java虚拟机的引用
  841. (*env)->GetJavaVM(env, &jvm);
  842. fileSendListener = (*env)->NewGlobalRef(env, listener);
  843. //包名处理
  844. const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL);
  845. const char *sessionNameStr = (*env)->GetStringUTFChars(env, sessionName, NULL);
  846. IFileSendListener fsl = {
  847. .OnSendFileProcess = sendFileProcess,
  848. .OnSendFileFinished = sendFileFinished,
  849. .OnFileTransError = sendFileTransError
  850. };
  851. int ret = SetFileSendListener(pkgNameStr, sessionNameStr, &fsl);
  852. (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr);
  853. (*env)->ReleaseStringUTFChars(env, sessionName, sessionNameStr);
  854. return ret;
  855. }
  856. /**
  857. * 开始接收回调
  858. */
  859. int receiveFileStarted(int sessionId, const char *files, int fileCnt) {
  860. // 获取JNIEnv环境
  861. JNIEnv *env;
  862. // 将当前线程附加到Java虚拟机
  863. (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  864. // 获取当前对象的类引用
  865. jclass nativeLibClass = (*env)->GetObjectClass(env, fileReceiveListener);
  866. // 获取当前对象的onQosEvent方法的ID
  867. jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onReceiveFileStarted", "(ILjava/lang/String;I)I");
  868. jstring filesStr = (*env)->NewStringUTF(env, files);
  869. // 调用当前对象的非静态方法
  870. jint ret = (*env)->CallIntMethod(env, fileReceiveListener, callbackMethod, sessionId, filesStr, fileCnt);
  871. // 将当前线程从Java虚拟机分离
  872. (*jvm)->DetachCurrentThread(jvm);
  873. printf("<receiveFileProcess>receiveFileProcess, sessionId:%d, files:%s, fileCnt: %d\n", sessionId, files, fileCnt);
  874. return ret;
  875. }
  876. /**
  877. * 接收进度回调
  878. */
  879. int receiveFileProcess(int sessionId, const char *firstFile, uint64_t bytesUpload, uint64_t bytesTotal) {
  880. // 获取JNIEnv环境
  881. JNIEnv *env;
  882. // 将当前线程附加到Java虚拟机
  883. (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  884. // 获取当前对象的类引用
  885. jclass nativeLibClass = (*env)->GetObjectClass(env, fileReceiveListener);
  886. // 获取当前对象的onQosEvent方法的ID
  887. jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onReceiveFileProcess", "(ILjava/lang/String;JJ)I");
  888. jstring firstFileStr = (*env)->NewStringUTF(env, firstFile);
  889. // 调用当前对象的非静态方法
  890. jint ret = (*env)->CallIntMethod(env, fileReceiveListener, callbackMethod, sessionId, firstFileStr, bytesUpload, bytesTotal);
  891. // 将当前线程从Java虚拟机分离
  892. (*jvm)->DetachCurrentThread(jvm);
  893. printf("<receiveFileProcess>receiveFileProcess, sessionId:%d, firstFile:%s, bytesUpload: %d, bytesTotal: %d\n", sessionId, firstFile, bytesUpload, bytesTotal);
  894. return ret;
  895. }
  896. /**
  897. * 接收文件完成回调
  898. */
  899. void receiveFileFinished(int sessionId, const char *files, int fileCnt) {
  900. // 获取JNIEnv环境
  901. JNIEnv *env;
  902. // 将当前线程附加到Java虚拟机
  903. (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  904. // 获取当前对象的类引用
  905. jclass nativeLibClass = (*env)->GetObjectClass(env, fileReceiveListener);
  906. // 获取当前对象的onQosEvent方法的ID
  907. jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onReceiveFileFinished", "(ILjava/lang/String;I)V");
  908. jstring filesStr = (*env)->NewStringUTF(env, files);
  909. // 调用当前对象的非静态方法
  910. (*env)->CallVoidMethod(env, fileReceiveListener, callbackMethod, sessionId, filesStr, fileCnt);
  911. // 将当前线程从Java虚拟机分离
  912. (*jvm)->DetachCurrentThread(jvm);
  913. printf("<receiveFileFinished>receiveFileFinished, sessionId:%d, files:%s, fileCnt: %d\n", sessionId, files, fileCnt);
  914. }
  915. /**
  916. * 接收错误回调
  917. */
  918. void receiveFileTransError(int sessionId) {
  919. // 获取JNIEnv环境
  920. JNIEnv *env;
  921. // 将当前线程附加到Java虚拟机
  922. (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
  923. // 获取当前对象的类引用
  924. jclass nativeLibClass = (*env)->GetObjectClass(env, fileReceiveListener);
  925. // 获取当前对象的onQosEvent方法的ID
  926. jmethodID callbackMethod = (*env)->GetMethodID(env, nativeLibClass, "onFileTransError", "(I)V");
  927. // 调用当前对象的非静态方法
  928. (*env)->CallVoidMethod(env, fileReceiveListener, callbackMethod, sessionId);
  929. // 将当前线程从Java虚拟机分离
  930. (*jvm)->DetachCurrentThread(jvm);
  931. printf("<receiveFileTransError>receiveFileTransError, sessionId:%d\n", sessionId);
  932. }
  933. /*
  934. * Class: com_jg_softbus_naservice_SessionService
  935. * Method: setFileReceiveListener
  936. * Signature: (Ljava/lang/String;Ljava/lang/String;Lcom/jg/softbus/session/callback/IFileReceiveListener;Ljava/lang/String;)I
  937. */
  938. JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SessionService_setFileReceiveListener
  939. (JNIEnv *env, jobject obj, jstring pkgName, jstring sessionName, jobject listener, jstring rootDir) {
  940. // 保存Java虚拟机的引用
  941. (*env)->GetJavaVM(env, &jvm);
  942. fileReceiveListener = (*env)->NewGlobalRef(env, listener);
  943. //包名处理
  944. const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL);
  945. const char *sessionNameStr = (*env)->GetStringUTFChars(env, sessionName, NULL);
  946. const char *rootDirStr = (*env)->GetStringUTFChars(env, rootDir, NULL);
  947. IFileReceiveListener frl = {
  948. .OnReceiveFileStarted = receiveFileStarted,
  949. .OnReceiveFileProcess = receiveFileProcess,
  950. .OnReceiveFileFinished = receiveFileFinished,
  951. .OnFileTransError = receiveFileTransError
  952. };
  953. int ret = SetFileReceiveListener(pkgNameStr, sessionNameStr, &frl, rootDirStr);
  954. (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr);
  955. (*env)->ReleaseStringUTFChars(env, sessionName, sessionNameStr);
  956. (*env)->ReleaseStringUTFChars(env, rootDir, rootDirStr);
  957. return ret;
  958. }
  959. /*
  960. * Class: com_jg_softbus_naservice_SessionService
  961. * Method: closeSession
  962. * Signature: (I)V
  963. */
  964. JNIEXPORT void JNICALL Java_com_jg_softbus_naservice_SessionService_closeSession
  965. (JNIEnv *env, jobject obj, jint sessionId) {
  966. // 保存Java虚拟机的引用
  967. (*env)->GetJavaVM(env, &jvm);
  968. CloseSession(sessionId);
  969. }
  970. /*
  971. * Class: com_jg_softbus_naservice_SessionService
  972. * Method: removeSessionServer
  973. * Signature: (Ljava/lang/String;Ljava/lang/String;)I
  974. */
  975. JNIEXPORT jint JNICALL Java_com_jg_softbus_naservice_SessionService_removeSessionServer
  976. (JNIEnv *env, jobject obj, jstring pkgName, jstring sessionName) {
  977. // 保存Java虚拟机的引用
  978. (*env)->GetJavaVM(env, &jvm);
  979. const char *pkgNameStr = (*env)->GetStringUTFChars(env, pkgName, NULL);
  980. const char *sessionNameStr = (*env)->GetStringUTFChars(env, sessionName, NULL);
  981. printf("[jni]: remove session....\n");
  982. int ret = RemoveSessionServer(pkgNameStr, sessionNameStr);
  983. printf("[jni]: remove session completed. the result: %d\n", ret);
  984. (*env)->ReleaseStringUTFChars(env, pkgName, pkgNameStr);
  985. (*env)->ReleaseStringUTFChars(env, sessionName, sessionNameStr);
  986. return ret;
  987. }
  988. JNIEXPORT jstring JNICALL Java_com_jg_softbus_naservice_SessionService_getPeerDeviceId
  989. (JNIEnv *env, jobject obj, jint sessionId) {
  990. // 保存Java虚拟机的引用
  991. (*env)->GetJavaVM(env, &jvm);
  992. char *networkId = "default";
  993. int ret = GetPeerDeviceId(sessionId, networkId, NETWORK_ID_BUF_LEN);
  994. if(networkId != NULL){
  995. jstring networkIdStr = (*env)->NewStringUTF(env, networkId);
  996. return networkIdStr;
  997. }
  998. return NULL;
  999. }
  1000. /*
  1001. * Class: com_jg_softbus_naservice_SessionService
  1002. * Method: getPeerSessionName
  1003. * Signature: (I)Ljava/lang/String;
  1004. */
  1005. JNIEXPORT jstring JNICALL Java_com_jg_softbus_naservice_SessionService_getPeerSessionName
  1006. (JNIEnv *env, jobject obj, jint sessionId) {
  1007. // 保存Java虚拟机的引用
  1008. (*env)->GetJavaVM(env, &jvm);
  1009. char *sessionName = "default";
  1010. int ret = GetPeerSessionName(sessionId, sessionName, 255);
  1011. if(sessionName != NULL){
  1012. jstring sessionNameStr = (*env)->NewStringUTF(env, sessionName);
  1013. return sessionNameStr;
  1014. }
  1015. return NULL;
  1016. }
  1017. JNIEXPORT void JNICALL Java_com_jg_softbus_naservice_SessionService_destroy
  1018. (JNIEnv *env, jobject obj) {
  1019. printf("[session]destory the session data.\r\n");
  1020. // 删除全局引用
  1021. (*env)->DeleteGlobalRef(env, sessionListener);
  1022. printf("[session]sessionListener have been destory.\r\n");
  1023. (*env)->DeleteGlobalRef(env, fileSendListener);
  1024. printf("[session]fileSendListener have been destory.\r\n");
  1025. (*env)->DeleteGlobalRef(env, fileReceiveListener);
  1026. printf("[session]fileReceiveListener have been destory.\r\n");
  1027. // if(jvm != NULL) {
  1028. // free(jvm);
  1029. // printf("[session]jvm have been destory.\r\n");
  1030. // }
  1031. }