X-Git-Url: https://rtime.felk.cvut.cz/gitweb/orte.git/blobdiff_plain/8a64c855d6b39383104939877d3248571d949c71..123c8c321489e0d0528603d397ca552641dec89b:/orte/libjorte/JORTESubscriptionCreate.c diff --git a/orte/libjorte/JORTESubscriptionCreate.c b/orte/libjorte/JORTESubscriptionCreate.c index 599f9c8..e0838cf 100644 --- a/orte/libjorte/JORTESubscriptionCreate.c +++ b/orte/libjorte/JORTESubscriptionCreate.c @@ -28,6 +28,7 @@ #include #include +#include // library header file's path #include "orte_all.h" @@ -44,275 +45,109 @@ * ****************************************************************** */ void -recvCallBack(const ORTERecvInfo *info,void *vinstance, void *recvCallBackParam) +recvCallBack(const ORTERecvInfo *info, void *vinstance, void *recvCallBackParam) { // jni varialbles JavaVM *jvm = 0; JNIEnv *env = 0; - jclass cls = 0; // local reference! - jclass cls_msg = 0; - jobject rinfo = 0; - jobject obj_msg; jobject obj_bo = 0; - jfieldID fid = 0; - jmethodID mid = 0; - jmethodID mid_callback = 0; - // - JORTECallbackContext_t *callback_cont = (JORTECallbackContext_t*)recvCallBackParam; + + JORTECallbackContext_t *callback_cont; + + // HACK: if the subscriber has been destroyed, return + if ((*(JORTECallbackContext_t **)recvCallBackParam) == 0) + return; + + callback_cont = *((JORTECallbackContext_t **)recvCallBackParam); #ifdef TEST_STAGE - printf("\n\n:c: --------------- recvCallBack called.. --------------- \n"); + printf("\n\n:c: --------------- recvCallBack called.. --------------- \n"); #endif - do - { + do { // set local variables from struct - if(callback_cont->jvm == 0) - { - #ifdef TEST_STAGE - printf(":!c: jvm = NULL \n"); - #endif - break; - } jvm = callback_cont->jvm; // get env - (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL); - if(env == 0) - { + if ((*jvm)->AttachCurrentThread(jvm, + #ifdef __ANDROID__ + &env, + #else + (void **)&env, + #endif + NULL) != JNI_OK) { #ifdef TEST_STAGE - printf(":!c: env = NULL \n"); + printf(":!c: recvCallBack: AttachCurrentThread() failed \n"); #endif - break; + return; } - // + // set byte order only if it differs from that currently set - if(info->data_endian != callback_cont->cur_endian) { - //prepare ByteOrder - cls = (*env)->FindClass(env, "java/nio/ByteOrder"); - if (cls == 0) { - #ifdef TEST_STAGE - printf(":!c: cls = NULL \n"); - #endif - } - if(info->data_endian == BigEndian) { - fid = (*env)->GetStaticFieldID(env, - cls, - "BIG_ENDIAN", - "Ljava/nio/ByteOrder;"); - callback_cont->cur_endian = BigEndian; - } - else { - fid = (*env)->GetStaticFieldID(env, - cls, - "LITTLE_ENDIAN", - "Ljava/nio/ByteOrder;"); - callback_cont->cur_endian = LittleEndian; - } - if(fid == 0) { - #ifdef TEST_STAGE - printf(":!c: fid = NULL \n"); - #endif - } - obj_bo = (*env)->GetStaticObjectField(env, cls, fid); - if(obj_bo == 0) { - #ifdef TEST_STAGE - printf(":!c: cls = NULL \n"); - #endif + if (info->data_endian != callback_cont->cur_endian) { + if (info->data_endian == BigEndian) { + obj_bo = callback_cont->obj_BO_BE; + callback_cont->cur_endian = BigEndian; + } else { + obj_bo = callback_cont->obj_BO_LE; + callback_cont->cur_endian = LittleEndian; } // set byte order to ByteBuffer - // get BB class - cls = (*env)->GetObjectClass(env, callback_cont->obj_buf); - if(cls == 0) - { - #ifdef TEST_STAGE - printf(":!c: cls = NULL \n"); - #endif - } - // get methodID - order(ByteOrder) - mid = (*env)->GetMethodID(env, - cls, - "order", - "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;"); - if(mid == 0) - { - #ifdef TEST_STAGE - printf(":!c: mid = NULL \n"); - #endif - } - - // set ByteOrder - if((*env)->CallObjectMethod(env,callback_cont->obj_buf,mid,obj_bo) == 0) - { - #ifdef TEST_STAGE - printf(":!c: set byte order failed.. \n"); - #endif - } - } - // - if(callback_cont->obj == 0) - { - #ifdef TEST_STAGE - printf(":!c: obj = NULL \n"); - #endif - break; + (*env)->CallObjectMethod(env, callback_cont->obj_buf, callback_cont->mid_order, obj_bo); } - // set local vars - rinfo = callback_cont->rinfo; - obj_msg = callback_cont->msg; - #ifdef TEST_STAGE - printf(":c: #0 \n"); - printf(":c: env = %#"PRIxPTR", obj_msg = %#"PRIxPTR" \n", (intptr_t)env, (intptr_t)obj_msg); + printf(":c: #0 \n"); + printf(":c: env = %#" PRIxPTR ", obj_msg = %#" PRIxPTR " \n", (intptr_t)env, (intptr_t)callback_cont->msg); #endif - - // - if(rinfo == 0) - { - // find cls - cls = findClass(env, "org.ocera.orte.types.RecvInfo"); - if(cls == 0) - { - #ifdef TEST_STAGE - printf(":!c: cls = NULL \n"); - #endif - break; - } - // call object constructor - mid = (*env)->GetMethodID(env, cls, "", "()V"); - if(mid == 0) - { - #ifdef TEST_STAGE - printf(":!c: constructor failed! \n"); - #endif - break; - } - // create new object - rinfo = (*env)->NewObject(env, cls, mid); - if(rinfo == 0) - { - #ifdef TEST_STAGE - printf(":!c: rinfo = NULL \n"); - #endif - break; - } - // create global reference - callback_cont->rinfo = (*env)->NewGlobalRef(env, rinfo); - if (callback_cont->rinfo == 0) - { - #ifdef TEST_STAGE - printf(":!c: callback_cont->rinfo = NULL \n"); - #endif - break; - } - } //////////////////////////////////////////////////// - // set RecvInfo instance - if(setRecvInfo(env,info,callback_cont->rinfo) == 0) - { - #ifdef TEST_STAGE - printf(":!c: setRecvInfo() failed! \n"); - #endif - break; - } + memcpy(callback_cont->info_buf, (void *)info, sizeof(ORTERecvInfo)); //////////////////////////////////////////////////// + // control print - only in TEST_STAGE #ifdef TEST_STAGE - printf(":c: rinfo created :] \n"); - printf(":c:----- ORTERecvInfo members ------ \n"); - printf(":c: recvStatus: %#x \n", info->status); - printf(":c: senderGuid: hid = %#"PRIx32", aid = %#"PRIx32", oid = %#"PRIx32" \n", - info->senderGUID.hid,info->senderGUID.aid,info->senderGUID.oid); - printf(":c: topic: %s \n",info->topic); - printf(":c: type: %s \n",info->type); - printf(":c: localTimeRecv: sec = %"PRId32", fract = %"PRIu32" \n", - info->localTimeReceived.seconds,info->localTimeReceived.fraction); - printf(":c: remoteTimePub: sec = %"PRId32", fract = %"PRIu32" \n", - info->remoteTimePublished.seconds,info->remoteTimePublished.fraction); - printf(":c: seqNr: high = %"PRId32", low = %"PRIu32" \n",info->sn.high,info->sn.low); - printf(":c:---------------------------------- \n"); + printf(":c: rinfo created :] \n"); + printf(":c:----- ORTERecvInfo members ------ \n"); + printf(":c: recvStatus: %#x \n", info->status); + printf(":c: senderGuid: hid = %#" PRIx32 ", aid = %#" PRIx32 ", oid = %#" PRIx32 " \n", + info->senderGUID.hid, info->senderGUID.aid, info->senderGUID.oid); + printf(":c: topic: %s \n", info->topic); + printf(":c: type: %s \n", info->type); + printf(":c: localTimeRecv: sec = %" PRId32 ", fract = %" PRIu32 " \n", + info->localTimeReceived.seconds, info->localTimeReceived.fraction); + printf(":c: remoteTimePub: sec = %" PRId32 ", fract = %" PRIu32 " \n", + info->remoteTimePublished.seconds, info->remoteTimePublished.fraction); + printf(":c: seqNr: high = %" PRId32 ", low = %" PRIu32 " \n", info->sn.high, info->sn.low); + printf(":c:---------------------------------- \n"); #endif //////////////////////////////////////////////////// // update MessageData instance - // get cls - cls_msg = (*env)->GetObjectClass(env, obj_msg); - if(cls_msg == 0) - { - #ifdef TEST_STAGE - printf(":!c: cls_msg = NULL \n"); - #endif - break; - } - ///////////////////////////////////////////////////// - // methodID - read() - mid = (*env)->GetMethodID(env, - cls_msg, - "read", - "()V"); - if(mid == 0) - { - #ifdef TEST_STAGE - printf(":!c: mid = NULL \n"); - #endif - break; - } // call method (*env)->CallVoidMethod(env, - obj_msg, - mid); - - /* *************************** * - * call JAVA CallBack method * - * *************************** */ - #ifdef TEST_STAGE - printf(":c: call JAVA CallBack method \n"); - #endif - + callback_cont->msg, + callback_cont->mid_read); - // get class - cls = (*env)->GetObjectClass(env,callback_cont->obj); - if(cls == 0) - { - #ifdef TEST_STAGE - printf(":!c: cls = NULL \n"); - #endif - break; - } - // get method ID - mid = (*env)->GetMethodID(env, - cls, - "callback", - "(Lorg/ocera/orte/types/RecvInfo;Lorg/ocera/orte/types/MessageData;)V"); - if(mid == 0) - { - #ifdef TEST_STAGE - printf(":!c: cls = NULL \n"); - #endif - break; - } - mid_callback = mid; - // + /* *************************** * + * call JAVA CallBack method * + * *************************** */ #ifdef TEST_STAGE - printf(":c: volam callback metodu.. halo jsi tam?? \n"); + printf(":c: volam callback metodu.. halo jsi tam?? \n"); #endif // call object's method (*env)->CallVoidMethod(env, - callback_cont->obj, /*obj*/ - mid_callback, - callback_cont->rinfo, - obj_msg); - } while(0); + callback_cont->obj, /*obj*/ + callback_cont->mid_callback, + callback_cont->rinfo, + callback_cont->msg); + } while (0); // detach current thread - if((*jvm)->DetachCurrentThread(jvm) != 0) - printf(":c!: DetachCurrentThread failed! \n"); + if ((*jvm)->DetachCurrentThread(jvm) != JNI_OK) + printf(":c!: DetachCurrentThread failed! \n"); // #ifdef TEST_STAGE - printf(":c: ------------ thats all from recvCallBack ------------ \n\n"); + printf(":c: ------------ thats all from recvCallBack ------------ \n\n"); #endif - } /* ****************************************************************** * @@ -320,25 +155,27 @@ recvCallBack(const ORTERecvInfo *info,void *vinstance, void *recvCallBackParam) * ****************************************************************** */ JNIEXPORT jlong JNICALL Java_org_ocera_orte_Subscription_jORTESubscriptionCreate -(JNIEnv *env, - jobject obj, - jlong dhandle, // appDomain handle - jint jsmode, // subs mode - jint jstype, // subs type - jstring jtopic, // subs topic - jstring jtname, // subs typeName - jobject jinstance, // direct ByteBuffer - jint jbyteOrder,// byte order of ByteBuffer - jobject obj_msg, // messageData instance - jobject jdeadline, - jobject jminSeparation, - jobject obj_callback, - jlong j_multicastIP) + (JNIEnv *env, + jobject obj, + jlong dhandle, // appDomain handle + jint jsmode, // subs mode + jint jstype, // subs type + jstring jtopic, // subs topic + jstring jtname, // subs typeName + jobject jinstance, // direct ByteBuffer + jint jbyteOrder, // byte order of ByteBuffer + jobject obj_msg, // messageData instance + jobject jdeadline, + jobject jminSeparation, + jobject obj_callback, + jlong j_multicastIP) { // jni variables JavaVM *jvm; jfieldID fid; jclass cls; + jmethodID mid; + jobject obj_info_buffer; // orte variables ORTESubscription *s = 0; ORTEDomain *d; @@ -346,152 +183,249 @@ Java_org_ocera_orte_Subscription_jORTESubscriptionCreate SubscriptionType stype; NtpTime deadline; NtpTime minSeparation; - // jorte varialbe + // jorte variable JORTECallbackContext_t *callback_cont; + JORTECallbackContext_t **callback_cont_ptr; + // standart variables const char *topic = 0; const char *typename = 0; void *buffer; int flag_ok = 0; + + /* HACK: allocate space for callback context structure and than for a pointer to it */ + // memory alocation // don't forget use free() funct.!! - callback_cont = (JORTECallbackContext_t*)malloc(sizeof(JORTECallbackContext_t)); + callback_cont = (JORTECallbackContext_t *)malloc(sizeof(JORTECallbackContext_t)); + callback_cont_ptr = (JORTECallbackContext_t **)malloc(sizeof(JORTECallbackContext_t *)); + *callback_cont_ptr = callback_cont; - do - { + do { // get direct ByteBuffer pointer from Java buffer = (*env)->GetDirectBufferAddress(env, jinstance); // check obj_callback - if (obj_callback == 0) - { + if (obj_callback == 0) { #ifdef TEST_STAGE - printf(":!c: obj_callback = NULL \n"); + printf(":!c: obj_callback = NULL \n"); #endif break; } // get jvm - jint b = (*env)->GetJavaVM(env,&jvm); - if (b < 0) - { + jint b = (*env)->GetJavaVM(env, &jvm); + if (b == JNI_OK) { #ifdef TEST_STAGE - printf(":!c: getJavaVM() failed! \n"); + printf(":c: getJavaVM succesfull.. \n"); #endif - break; - } - if (b == 0) - { + } else { #ifdef TEST_STAGE - printf(":c: getJavaVM succesfull.. \n"); + printf(":!c: getJavaVM() failed! \n"); #endif + break; } callback_cont->jvm = jvm; - callback_cont->cur_endian = (CDR_Endianness) jbyteOrder; + callback_cont->cur_endian = (CDR_Endianness)jbyteOrder; // create global references callback_cont->obj = (*env)->NewGlobalRef(env, obj_callback); // - if (callback_cont->obj == 0) - { + if (callback_cont->obj == 0) { + #ifdef TEST_STAGE + printf(":c: global reference not created! \n"); + #endif + break; + } + // get ReceiveCallback class + cls = (*env)->GetObjectClass(env, callback_cont->obj); + if (cls == 0) { #ifdef TEST_STAGE - printf(":c: global reference not created! \n"); + printf(":!c: cls = NULL \n"); + #endif + break; + } + // get callback method ID + callback_cont->mid_callback = (*env)->GetMethodID(env, + cls, + "callback", + "(Lorg/ocera/orte/types/RecvInfo;Lorg/ocera/orte/types/MessageData;)V"); + if (callback_cont->mid_callback == 0) { + #ifdef TEST_STAGE + printf(":!c: mid_callback = NULL \n"); #endif break; } // create global references callback_cont->obj_buf = (*env)->NewGlobalRef(env, jinstance); // - if (callback_cont->obj_buf == 0) - { + if (callback_cont->obj_buf == 0) { #ifdef TEST_STAGE - printf(":c: global reference not created! \n"); + printf(":c: global reference not created! \n"); #endif break; } // create global references callback_cont->msg = (*env)->NewGlobalRef(env, obj_msg); // - if (callback_cont->msg == 0) - { + if (callback_cont->msg == 0) { + #ifdef TEST_STAGE + printf(":c: global reference not created! \n"); + #endif + break; + } + // get MessageData class + cls = (*env)->GetObjectClass(env, callback_cont->msg); + if (cls == 0) { #ifdef TEST_STAGE - printf(":c: global reference not created! \n"); + printf(":!c: cls_msg = NULL \n"); + #endif + break; + } + ///////////////////////////////////////////////////// + // methodID - read() + callback_cont->mid_read = (*env)->GetMethodID(env, + cls, + "read", + "()V"); + if (callback_cont->mid_read == 0) { + #ifdef TEST_STAGE + printf(":!c: mid_read = NULL \n"); #endif break; } // init RecvInfo pointer - callback_cont->rinfo = 0; + // find cls + cls = findClass(env, "org.ocera.orte.types.RecvInfo"); + if (cls == 0) { + #ifdef TEST_STAGE + printf(":!c: cls = NULL \n"); + #endif + break; + } + // call object constructor + mid = (*env)->GetMethodID(env, cls, "", "()V"); + if (mid == 0) { + #ifdef TEST_STAGE + printf(":!c: constructor failed! \n"); + #endif + break; + } + // create new object + callback_cont->rinfo = (*env)->NewObject(env, cls, mid); + if (callback_cont->rinfo == 0) { + #ifdef TEST_STAGE + printf(":!c: rinfo = NULL \n"); + #endif + break; + } + // create global reference + callback_cont->rinfo = (*env)->NewGlobalRef(env, callback_cont->rinfo); + if (callback_cont->rinfo == 0) { + #ifdef TEST_STAGE + printf(":!c: callback_cont->rinfo = NULL \n"); + #endif + break; + } + // lookup getBuffer() ID + mid = (*env)->GetMethodID(env, cls, "getBuffer", "()Ljava/nio/ByteBuffer;"); + if (mid == 0) { + #ifdef TEST_STAGE + printf(":!c: getBuffer() failed! \n"); + #endif + break; + } + // get ByteBuffer reference + obj_info_buffer = (*env)->CallObjectMethod(env, callback_cont->rinfo, mid); + callback_cont->info_buf = (*env)->GetDirectBufferAddress(env, obj_info_buffer); + // create global references for ByteOrders + cls = (*env)->FindClass(env, "java/nio/ByteOrder"); + fid = (*env)->GetStaticFieldID(env, + cls, + "BIG_ENDIAN", + "Ljava/nio/ByteOrder;"); + callback_cont->obj_BO_BE = (*env)->GetStaticObjectField(env, cls, fid); + callback_cont->obj_BO_BE = (*env)->NewGlobalRef(env, callback_cont->obj_BO_BE); + fid = (*env)->GetStaticFieldID(env, + cls, + "LITTLE_ENDIAN", + "Ljava/nio/ByteOrder;"); + callback_cont->obj_BO_LE = (*env)->GetStaticObjectField(env, cls, fid); + callback_cont->obj_BO_LE = (*env)->NewGlobalRef(env, callback_cont->obj_BO_LE); + // get methodID - order(ByteOrder) + cls = (*env)->GetObjectClass(env, callback_cont->obj_buf); + callback_cont->mid_order = (*env)->GetMethodID(env, + cls, + "order", + "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;"); // cls = (*env)->GetObjectClass(env, obj); - if(cls == 0) - { + if (cls == 0) { #ifdef TEST_STAGE - printf(":!c: cls = NULL \n"); + printf(":!c: cls = NULL \n"); #endif break; } // fieldID - callbackContextHandle fid = (*env)->GetFieldID(env, - cls, - "callbackContextHandle", - "J"); - if(fid == 0) - { + cls, + "callbackContextHandle", + "J"); + if (fid == 0) { #ifdef TEST_STAGE - printf(":!c: fid = NULL \n"); + printf(":!c: fid = NULL \n"); #endif break; } (*env)->SetLongField(env, - obj, - fid, - (jlong) callback_cont); + obj, + fid, + (jlong)callback_cont_ptr); #ifdef TEST_STAGE - printf(":c: ORTESubscriptionCreate() calling..\n"); + printf(":c: ORTESubscriptionCreate() calling..\n"); #endif // - d = (ORTEDomain *) dhandle; - if (d == 0) - { + d = (ORTEDomain *)dhandle; + if (d == 0) { #ifdef TEST_STAGE - printf(":!c: d = NULL [bad domain handle] \n"); + printf(":!c: d = NULL [bad domain handle] \n"); #endif break; } // - smode = (SubscriptionMode) jsmode; - stype = (SubscriptionType) jstype; + smode = (SubscriptionMode)jsmode; + stype = (SubscriptionType)jstype; topic = (*env)->GetStringUTFChars(env, jtopic, 0); typename = (*env)->GetStringUTFChars(env, jtname, 0); - deadline = getNtpTime(env, jdeadline);// - minSeparation = getNtpTime(env, jminSeparation);// + deadline = getNtpTime(env, jdeadline); // + minSeparation = getNtpTime(env, jminSeparation); // // call ORTE function s = ORTESubscriptionCreate(d, - smode, - stype, - topic, - typename, - buffer, - &deadline, - &minSeparation, - recvCallBack, - (void*)callback_cont, - (uint32_t) j_multicastIP); - if (s == 0) - { + smode, + stype, + topic, + typename, + buffer, + &deadline, + &minSeparation, + recvCallBack, + (void *)callback_cont_ptr, + (uint32_t)j_multicastIP); + if (s == 0) { #ifdef TEST_STAGE - printf(":!c: s = NULL [subscription not created] \n"); + printf(":!c: s = NULL [subscription not created] \n"); #endif break; } // set flag flag_ok = 1; - } while(0); + } while (0); // free memory (*env)->ReleaseStringUTFChars(env, jtopic, topic); (*env)->ReleaseStringUTFChars(env, jtname, typename); // returns handle of new created Subscription - if(flag_ok == 0) return 0; - return ((jlong) s); + if (flag_ok == 0) + return 0; + return ((jlong)s); }