1 /* JORTESubscriptionCreate.c */
4 * This code provides conversion between JAVA a C environments.
5 * The C functions are calling here and results are send to JAVA
6 * native functions. It uses the header pregenerated by JAVA
7 * (by command 'javah -jni class_with_native_function')
9 * @author Lukas Pokorny (lukas_pokorny@centrum.cz)
10 * @author CTU FEE Prague - Department of Control Engineering (dce.felk.cvut.cz)
11 * @author Project ORTE - OCERA Real Time Ethernet (www.ocera.org)
12 * @author dedication to Kj
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
33 // library header file's path
35 // pregenerated header
36 #include "jorte/org_ocera_orte_Subscription.h"
37 // enable TEST_STAGE run level
38 #include "jorte/4all.h"
40 #include "jorte/jorte_typedefs_defines.h"
41 #include "jorte/jorte_protos_api.h"
43 /* ****************************************************************** *
45 * ****************************************************************** */
48 recvCallBack(const ORTERecvInfo *info, void *vinstance, void *recvCallBackParam)
55 JORTECallbackContext_t *callback_cont;
57 // HACK: if the subscriber has been destroyed, return
58 if ((*(JORTECallbackContext_t **)recvCallBackParam) == 0)
61 callback_cont = *((JORTECallbackContext_t **)recvCallBackParam);
64 printf("\n\n:c: --------------- recvCallBack called.. --------------- \n");
68 // set local variables from struct
69 jvm = callback_cont->jvm;
71 if ((*jvm)->AttachCurrentThread(jvm,
79 printf(":!c: recvCallBack: AttachCurrentThread() failed \n");
84 // set byte order only if it differs from that currently set
85 if (info->data_endian != callback_cont->cur_endian) {
86 if (info->data_endian == BigEndian) {
87 obj_bo = callback_cont->obj_BO_BE;
88 callback_cont->cur_endian = BigEndian;
90 obj_bo = callback_cont->obj_BO_LE;
91 callback_cont->cur_endian = LittleEndian;
94 // set byte order to ByteBuffer
95 (*env)->CallObjectMethod(env, callback_cont->obj_buf, callback_cont->mid_order, obj_bo);
100 printf(":c: env = %#" PRIxPTR ", obj_msg = %#" PRIxPTR " \n", (intptr_t)env, (intptr_t)callback_cont->msg);
103 ////////////////////////////////////////////////////
104 memcpy(callback_cont->info_buf, (void *)info, sizeof(ORTERecvInfo));
105 ////////////////////////////////////////////////////
107 // control print - only in TEST_STAGE
109 printf(":c: rinfo created :] \n");
110 printf(":c:----- ORTERecvInfo members ------ \n");
111 printf(":c: recvStatus: %#x \n", info->status);
112 printf(":c: senderGuid: hid = %#" PRIx32 ", aid = %#" PRIx32 ", oid = %#" PRIx32 " \n",
113 info->senderGUID.hid, info->senderGUID.aid, info->senderGUID.oid);
114 printf(":c: topic: %s \n", info->topic);
115 printf(":c: type: %s \n", info->type);
116 printf(":c: localTimeRecv: sec = %" PRId32 ", fract = %" PRIu32 " \n",
117 info->localTimeReceived.seconds, info->localTimeReceived.fraction);
118 printf(":c: remoteTimePub: sec = %" PRId32 ", fract = %" PRIu32 " \n",
119 info->remoteTimePublished.seconds, info->remoteTimePublished.fraction);
120 printf(":c: seqNr: high = %" PRId32 ", low = %" PRIu32 " \n", info->sn.high, info->sn.low);
121 printf(":c:---------------------------------- \n");
123 ////////////////////////////////////////////////////
124 // update MessageData instance
126 (*env)->CallVoidMethod(env,
128 callback_cont->mid_read);
130 /* *************************** *
131 * call JAVA CallBack method *
132 * *************************** */
134 printf(":c: volam callback metodu.. halo jsi tam?? \n");
136 // call object's method
137 (*env)->CallVoidMethod(env,
138 callback_cont->obj, /*obj*/
139 callback_cont->mid_callback,
140 callback_cont->rinfo,
144 // detach current thread
145 if ((*jvm)->DetachCurrentThread(jvm) != JNI_OK)
146 printf(":c!: DetachCurrentThread failed! \n");
149 printf(":c: ------------ thats all from recvCallBack ------------ \n\n");
153 /* ****************************************************************** *
155 * ****************************************************************** */
156 JNIEXPORT jlong JNICALL
157 Java_org_ocera_orte_Subscription_jORTESubscriptionCreate
160 jlong dhandle, // appDomain handle
161 jint jsmode, // subs mode
162 jint jstype, // subs type
163 jstring jtopic, // subs topic
164 jstring jtname, // subs typeName
165 jobject jinstance, // direct ByteBuffer
166 jint jbyteOrder, // byte order of ByteBuffer
167 jobject obj_msg, // messageData instance
169 jobject jminSeparation,
170 jobject obj_callback,
178 jobject obj_info_buffer;
180 ORTESubscription *s = 0;
182 SubscriptionMode smode;
183 SubscriptionType stype;
185 NtpTime minSeparation;
187 JORTECallbackContext_t *callback_cont;
188 JORTECallbackContext_t **callback_cont_ptr;
190 // standart variables
191 const char *topic = 0;
192 const char *typename = 0;
196 /* HACK: allocate space for callback context structure and than for a pointer to it */
199 // don't forget use free() funct.!!
200 callback_cont = (JORTECallbackContext_t *)malloc(sizeof(JORTECallbackContext_t));
201 callback_cont_ptr = (JORTECallbackContext_t **)malloc(sizeof(JORTECallbackContext_t *));
202 *callback_cont_ptr = callback_cont;
206 // get direct ByteBuffer pointer from Java
207 buffer = (*env)->GetDirectBufferAddress(env, jinstance);
208 // check obj_callback
209 if (obj_callback == 0) {
211 printf(":!c: obj_callback = NULL \n");
216 jint b = (*env)->GetJavaVM(env, &jvm);
219 printf(":c: getJavaVM succesfull.. \n");
223 printf(":!c: getJavaVM() failed! \n");
227 callback_cont->jvm = jvm;
228 callback_cont->cur_endian = (CDR_Endianness)jbyteOrder;
229 // create global references
230 callback_cont->obj = (*env)->NewGlobalRef(env, obj_callback);
232 if (callback_cont->obj == 0) {
234 printf(":c: global reference not created! \n");
238 // get ReceiveCallback class
239 cls = (*env)->GetObjectClass(env, callback_cont->obj);
242 printf(":!c: cls = NULL \n");
246 // get callback method ID
247 callback_cont->mid_callback = (*env)->GetMethodID(env,
250 "(Lorg/ocera/orte/types/RecvInfo;Lorg/ocera/orte/types/MessageData;)V");
251 if (callback_cont->mid_callback == 0) {
253 printf(":!c: mid_callback = NULL \n");
257 // create global references
258 callback_cont->obj_buf = (*env)->NewGlobalRef(env, jinstance);
260 if (callback_cont->obj_buf == 0) {
262 printf(":c: global reference not created! \n");
266 // create global references
267 callback_cont->msg = (*env)->NewGlobalRef(env, obj_msg);
269 if (callback_cont->msg == 0) {
271 printf(":c: global reference not created! \n");
275 // get MessageData class
276 cls = (*env)->GetObjectClass(env, callback_cont->msg);
279 printf(":!c: cls_msg = NULL \n");
283 /////////////////////////////////////////////////////
285 callback_cont->mid_read = (*env)->GetMethodID(env,
289 if (callback_cont->mid_read == 0) {
291 printf(":!c: mid_read = NULL \n");
295 // init RecvInfo pointer
297 cls = findClass(env, "org.ocera.orte.types.RecvInfo");
300 printf(":!c: cls = NULL \n");
304 // call object constructor
305 mid = (*env)->GetMethodID(env, cls, "<init>", "()V");
308 printf(":!c: constructor failed! \n");
313 callback_cont->rinfo = (*env)->NewObject(env, cls, mid);
314 if (callback_cont->rinfo == 0) {
316 printf(":!c: rinfo = NULL \n");
320 // create global reference
321 callback_cont->rinfo = (*env)->NewGlobalRef(env, callback_cont->rinfo);
322 if (callback_cont->rinfo == 0) {
324 printf(":!c: callback_cont->rinfo = NULL \n");
328 // lookup getBuffer() ID
329 mid = (*env)->GetMethodID(env, cls, "getBuffer", "()Ljava/nio/ByteBuffer;");
332 printf(":!c: getBuffer() failed! \n");
336 // get ByteBuffer reference
337 obj_info_buffer = (*env)->CallObjectMethod(env, callback_cont->rinfo, mid);
338 callback_cont->info_buf = (*env)->GetDirectBufferAddress(env, obj_info_buffer);
339 // create global references for ByteOrders
340 cls = (*env)->FindClass(env, "java/nio/ByteOrder");
341 fid = (*env)->GetStaticFieldID(env,
344 "Ljava/nio/ByteOrder;");
345 callback_cont->obj_BO_BE = (*env)->GetStaticObjectField(env, cls, fid);
346 callback_cont->obj_BO_BE = (*env)->NewGlobalRef(env, callback_cont->obj_BO_BE);
347 fid = (*env)->GetStaticFieldID(env,
350 "Ljava/nio/ByteOrder;");
351 callback_cont->obj_BO_LE = (*env)->GetStaticObjectField(env, cls, fid);
352 callback_cont->obj_BO_LE = (*env)->NewGlobalRef(env, callback_cont->obj_BO_LE);
353 // get methodID - order(ByteOrder)
354 cls = (*env)->GetObjectClass(env, callback_cont->obj_buf);
355 callback_cont->mid_order = (*env)->GetMethodID(env,
358 "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;");
360 cls = (*env)->GetObjectClass(env, obj);
363 printf(":!c: cls = NULL \n");
367 // fieldID - callbackContextHandle
368 fid = (*env)->GetFieldID(env,
370 "callbackContextHandle",
374 printf(":!c: fid = NULL \n");
378 (*env)->SetLongField(env,
381 (jlong)callback_cont_ptr);
383 printf(":c: ORTESubscriptionCreate() calling..\n");
386 d = (ORTEDomain *)dhandle;
389 printf(":!c: d = NULL [bad domain handle] \n");
394 smode = (SubscriptionMode)jsmode;
395 stype = (SubscriptionType)jstype;
396 topic = (*env)->GetStringUTFChars(env, jtopic, 0);
397 typename = (*env)->GetStringUTFChars(env, jtname, 0);
398 deadline = getNtpTime(env, jdeadline); //
399 minSeparation = getNtpTime(env, jminSeparation); //
400 // call ORTE function
401 s = ORTESubscriptionCreate(d,
410 (void *)callback_cont_ptr,
411 (uint32_t)j_multicastIP);
414 printf(":!c: s = NULL [subscription not created] \n");
424 (*env)->ReleaseStringUTFChars(env, jtopic, topic);
425 (*env)->ReleaseStringUTFChars(env, jtname, typename);
426 // returns handle of new created Subscription