]> rtime.felk.cvut.cz Git - orte.git/blob - orte/libjorte/JORTESubscriptionCreate.c
ORTE,JORTE: set byte order of ByteBuffer from receive callback
[orte.git] / orte / libjorte / JORTESubscriptionCreate.c
1 /* JORTESubscriptionCreate.c  */
2
3 /**
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')
8   *
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
13   * @version 0.1
14   *
15   *
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.
20   *
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.
25   *
26   */
27
28
29 #include <stdlib.h>
30 #include <inttypes.h>
31
32 // library header file's path
33 #include "orte_all.h"
34 // pregenerated header
35 #include "jorte/org_ocera_orte_Subscription.h"
36 // enable TEST_STAGE run level
37 #include "jorte/4all.h"
38 // new data types
39 #include "jorte/jorte_typedefs_defines.h"
40 #include "jorte/jorte_protos_api.h"
41
42 /* ****************************************************************** *
43  *                           CallBack function                        *
44  * ****************************************************************** */
45
46 void
47 recvCallBack(const ORTERecvInfo *info,void *vinstance, void *recvCallBackParam)
48 {
49   // jni varialbles
50   JavaVM          *jvm = 0;
51   JNIEnv          *env = 0;
52   jclass           cls = 0; // local reference!
53   jclass           cls_msg = 0;
54   jobject          rinfo = 0;
55   jobject          obj_msg;
56   jobject          obj_bo = 0;
57   jfieldID         fid = 0;
58   jmethodID        mid = 0;
59   jmethodID        mid_callback = 0;
60   //
61   JORTECallbackContext_t   *callback_cont = (JORTECallbackContext_t*)recvCallBackParam;
62
63   #ifdef TEST_STAGE
64     printf("\n\n:c: --------------- recvCallBack called.. --------------- \n");
65   #endif
66
67   do
68   {
69     // set local variables from struct
70     if(callback_cont->jvm == 0)
71     {
72       #ifdef TEST_STAGE
73         printf(":!c: jvm = NULL \n");
74       #endif
75       break;
76     }
77     jvm = callback_cont->jvm;
78     // get env
79     (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
80     if(env == 0)
81     {
82       #ifdef TEST_STAGE
83        printf(":!c: env = NULL \n");
84       #endif
85       break;
86     }
87     //
88     // set byte order only if it differs from that currently set
89     if(info->data_endian != callback_cont->cur_endian) {
90       //prepare ByteOrder
91       cls = (*env)->FindClass(env, "java/nio/ByteOrder");
92       if (cls == 0) {
93         #ifdef TEST_STAGE
94           printf(":!c: cls = NULL \n");
95         #endif
96       }
97       if(info->data_endian == BigEndian) {
98         fid = (*env)->GetStaticFieldID(env,
99                                        cls,
100                                        "BIG_ENDIAN",
101                                        "Ljava/nio/ByteOrder;");
102         callback_cont->cur_endian = BigEndian;
103       }
104       else {
105         fid = (*env)->GetStaticFieldID(env,
106                                        cls,
107                                        "LITTLE_ENDIAN",
108                                        "Ljava/nio/ByteOrder;");
109         callback_cont->cur_endian = LittleEndian;
110       }
111       if(fid == 0) {
112         #ifdef TEST_STAGE
113           printf(":!c: fid = NULL \n");
114         #endif
115       }
116       obj_bo = (*env)->GetStaticObjectField(env, cls, fid);
117       if(obj_bo == 0) {
118         #ifdef TEST_STAGE
119           printf(":!c: cls = NULL \n");
120         #endif
121       }
122
123       // set byte order to ByteBuffer
124       // get BB class
125       cls = (*env)->GetObjectClass(env, callback_cont->obj_buf);
126       if(cls == 0)
127       {
128         #ifdef TEST_STAGE
129           printf(":!c: cls = NULL \n");
130         #endif
131       }
132       // get methodID - order(ByteOrder)
133       mid = (*env)->GetMethodID(env,
134                                 cls,
135                                 "order",
136                                 "(Ljava/nio/ByteOrder;)Ljava/nio/ByteBuffer;");
137       if(mid == 0)
138       {
139         #ifdef TEST_STAGE
140           printf(":!c: mid = NULL \n");
141         #endif
142       }
143
144       // set ByteOrder
145       if((*env)->CallObjectMethod(env,callback_cont->obj_buf,mid,obj_bo) == 0)
146       {
147         #ifdef TEST_STAGE
148           printf(":!c: set byte order failed.. \n");
149         #endif
150       }
151     }
152     //
153     if(callback_cont->obj == 0)
154     {
155       #ifdef TEST_STAGE
156         printf(":!c: obj = NULL \n");
157       #endif
158       break;
159     }
160     // set local vars
161     rinfo = callback_cont->rinfo;
162     obj_msg = callback_cont->msg;
163
164
165       #ifdef TEST_STAGE
166          printf(":c: #0 \n");
167          printf(":c: env = %#"PRIxPTR", obj_msg = %#"PRIxPTR" \n", (intptr_t)env, (intptr_t)obj_msg);
168       #endif
169
170
171         //
172     if(rinfo == 0)
173     {
174       // find cls
175       cls = findClass(env, "org.ocera.orte.types.RecvInfo");
176       if(cls == 0)
177       {
178         #ifdef TEST_STAGE
179           printf(":!c: cls = NULL \n");
180         #endif
181         break;
182       }
183       // call object constructor
184       mid = (*env)->GetMethodID(env, cls, "<init>", "()V");
185       if(mid == 0)
186       {
187         #ifdef TEST_STAGE
188           printf(":!c: constructor failed! \n");
189         #endif
190         break;
191       }
192       // create new object
193       rinfo = (*env)->NewObject(env, cls, mid);
194       if(rinfo == 0)
195       {
196         #ifdef TEST_STAGE
197           printf(":!c: rinfo = NULL \n");
198         #endif
199         break;
200       }
201       // create global reference
202       callback_cont->rinfo = (*env)->NewGlobalRef(env, rinfo);
203       if (callback_cont->rinfo == 0)
204       {
205         #ifdef TEST_STAGE
206           printf(":!c: callback_cont->rinfo = NULL \n");
207         #endif
208         break;
209       }
210     }
211     ////////////////////////////////////////////////////
212     // set RecvInfo instance
213     if(setRecvInfo(env,info,callback_cont->rinfo) == 0)
214     {
215       #ifdef TEST_STAGE
216         printf(":!c: setRecvInfo() failed! \n");
217       #endif
218       break;
219     }
220     ////////////////////////////////////////////////////
221     // control print - only in TEST_STAGE
222     #ifdef TEST_STAGE
223       printf(":c: rinfo created :] \n");
224       printf(":c:----- ORTERecvInfo members  ------ \n");
225       printf(":c:    recvStatus: %#x \n", info->status);
226       printf(":c:    senderGuid: hid = %#"PRIx32", aid = %#"PRIx32", oid = %#"PRIx32" \n",
227              info->senderGUID.hid,info->senderGUID.aid,info->senderGUID.oid);
228       printf(":c:         topic: %s \n",info->topic);
229       printf(":c:          type: %s \n",info->type);
230       printf(":c: localTimeRecv: sec = %"PRId32", fract = %"PRIu32" \n",
231              info->localTimeReceived.seconds,info->localTimeReceived.fraction);
232       printf(":c: remoteTimePub: sec = %"PRId32", fract = %"PRIu32" \n",
233              info->remoteTimePublished.seconds,info->remoteTimePublished.fraction);
234       printf(":c:         seqNr: high = %"PRId32", low = %"PRIu32" \n",info->sn.high,info->sn.low);
235       printf(":c:---------------------------------- \n");
236     #endif
237     ////////////////////////////////////////////////////
238     // update MessageData instance
239     // get cls
240     cls_msg = (*env)->GetObjectClass(env, obj_msg);
241     if(cls_msg == 0)
242     {
243       #ifdef TEST_STAGE
244          printf(":!c: cls_msg = NULL \n");
245       #endif
246       break;
247     }
248     /////////////////////////////////////////////////////
249     // methodID - read()
250     mid = (*env)->GetMethodID(env,
251                               cls_msg,
252                               "read",
253                               "()V");
254     if(mid == 0)
255     {
256       #ifdef TEST_STAGE
257          printf(":!c: mid = NULL \n");
258       #endif
259       break;
260     }
261     // call method
262     (*env)->CallVoidMethod(env,
263                            obj_msg,
264                            mid);
265
266    /* *************************** *
267     *  call JAVA CallBack method  *
268     * *************************** */
269       #ifdef TEST_STAGE
270         printf(":c: call JAVA CallBack method \n");
271       #endif
272
273
274         // get class
275     cls = (*env)->GetObjectClass(env,callback_cont->obj);
276     if(cls == 0)
277     {
278       #ifdef TEST_STAGE
279         printf(":!c: cls = NULL \n");
280       #endif
281       break;
282     }
283     // get method ID
284     mid = (*env)->GetMethodID(env,
285                               cls,
286                               "callback",
287                               "(Lorg/ocera/orte/types/RecvInfo;Lorg/ocera/orte/types/MessageData;)V");
288     if(mid == 0)
289     {
290       #ifdef TEST_STAGE
291         printf(":!c: cls = NULL \n");
292       #endif
293       break;
294     }
295     mid_callback = mid;
296     //
297     #ifdef TEST_STAGE
298       printf(":c: volam callback metodu.. halo jsi tam?? \n");
299     #endif
300     // call object's method
301     (*env)->CallVoidMethod(env,
302                            callback_cont->obj, /*obj*/
303                            mid_callback,
304                            callback_cont->rinfo,
305                            obj_msg);
306   } while(0);
307
308   // detach current thread
309   if((*jvm)->DetachCurrentThread(jvm) != 0)
310      printf(":c!: DetachCurrentThread failed! \n");
311   //
312   #ifdef TEST_STAGE
313      printf(":c: ------------ thats all from recvCallBack ------------ \n\n");
314   #endif
315
316 }
317
318 /* ****************************************************************** *
319  *                            native method                           *
320  * ****************************************************************** */
321 JNIEXPORT jlong JNICALL
322 Java_org_ocera_orte_Subscription_jORTESubscriptionCreate
323 (JNIEnv   *env,
324  jobject   obj,
325  jlong     dhandle,   // appDomain handle
326  jint      jsmode,    // subs mode
327  jint      jstype,    // subs type
328  jstring   jtopic,    // subs topic
329  jstring   jtname,    // subs typeName
330  jobject   jinstance, // direct ByteBuffer
331  jobject   obj_msg,   // messageData instance
332  jobject   jdeadline,
333  jobject   jminSeparation,
334  jobject   obj_callback,
335  jlong     j_multicastIP)
336 {
337   // jni variables
338   JavaVM                 *jvm;
339   jfieldID                fid;
340   jclass                  cls;
341   // orte variables
342   ORTESubscription       *s = 0;
343   ORTEDomain             *d;
344   SubscriptionMode        smode;
345   SubscriptionType        stype;
346   NtpTime                 deadline;
347   NtpTime                 minSeparation;
348   // jorte varialbe
349   JORTECallbackContext_t *callback_cont;
350   // standart variables
351   const char             *topic = 0;
352   const char             *typename = 0;
353   void                   *buffer;
354   int                     flag_ok = 0;
355   // memory alocation
356   // don't forget use free() funct.!!
357   callback_cont = (JORTECallbackContext_t*)malloc(sizeof(JORTECallbackContext_t));
358
359   do
360   {
361
362     // get direct ByteBuffer pointer from Java
363     buffer = (*env)->GetDirectBufferAddress(env, jinstance);
364     // check obj_callback
365     if (obj_callback == 0)
366     {
367       #ifdef TEST_STAGE
368         printf(":!c: obj_callback = NULL \n");
369       #endif
370       break;
371     }
372     // get jvm
373     jint b = (*env)->GetJavaVM(env,&jvm);
374     if (b <  0)
375     {
376       #ifdef TEST_STAGE
377         printf(":!c: getJavaVM() failed! \n");
378       #endif
379       break;
380     }
381     if (b == 0)
382     {
383       #ifdef TEST_STAGE
384         printf(":c: getJavaVM succesfull.. \n");
385       #endif
386     }
387     callback_cont->jvm = jvm;
388     callback_cont->cur_endian = FLAG_ENDIANNESS;
389     // create global references
390     callback_cont->obj = (*env)->NewGlobalRef(env, obj_callback);
391     //
392     if (callback_cont->obj == 0)
393     {
394       #ifdef TEST_STAGE
395         printf(":c: global reference not created! \n");
396       #endif
397       break;
398     }
399     // create global references
400     callback_cont->obj_buf = (*env)->NewGlobalRef(env, jinstance);
401     //
402     if (callback_cont->obj_buf == 0)
403     {
404       #ifdef TEST_STAGE
405         printf(":c: global reference not created! \n");
406       #endif
407       break;
408     }
409     // create global references
410     callback_cont->msg = (*env)->NewGlobalRef(env, obj_msg);
411     //
412     if (callback_cont->msg == 0)
413     {
414       #ifdef TEST_STAGE
415         printf(":c: global reference not created! \n");
416       #endif
417       break;
418     }
419     // init RecvInfo pointer
420     callback_cont->rinfo = 0;
421     //
422     cls = (*env)->GetObjectClass(env, obj);
423     if(cls == 0)
424     {
425       #ifdef TEST_STAGE
426         printf(":!c: cls = NULL \n");
427       #endif
428       break;
429     }
430     // fieldID - callbackContextHandle
431     fid = (*env)->GetFieldID(env,
432                              cls,
433                              "callbackContextHandle",
434                              "J");
435     if(fid == 0)
436     {
437       #ifdef TEST_STAGE
438         printf(":!c: fid = NULL \n");
439       #endif
440       break;
441     }
442     (*env)->SetLongField(env,
443                         obj,
444                         fid,
445                         (jlong) callback_cont);
446     #ifdef TEST_STAGE
447        printf(":c: ORTESubscriptionCreate() calling..\n");
448     #endif
449     //
450     d = (ORTEDomain *) dhandle;
451     if (d == 0)
452     {
453       #ifdef TEST_STAGE
454         printf(":!c: d = NULL [bad domain handle] \n");
455       #endif
456       break;
457     }
458     //
459     smode = (SubscriptionMode) jsmode;
460     stype = (SubscriptionType) jstype;
461     topic = (*env)->GetStringUTFChars(env, jtopic, 0);
462     typename = (*env)->GetStringUTFChars(env, jtname, 0);
463     deadline = getNtpTime(env, jdeadline);//
464     minSeparation = getNtpTime(env, jminSeparation);//
465     // call ORTE function
466     s = ORTESubscriptionCreate(d,
467                                smode,
468                                stype,
469                                topic,
470                                typename,
471                                buffer,
472                                &deadline,
473                                &minSeparation,
474                                recvCallBack,
475                                (void*)callback_cont,
476                                (uint32_t) j_multicastIP);
477     if (s == 0)
478     {
479       #ifdef TEST_STAGE
480         printf(":!c: s = NULL [subscription not created] \n");
481       #endif
482       break;
483     }
484
485     // set flag
486     flag_ok = 1;
487   } while(0);
488
489   // free memory
490   (*env)->ReleaseStringUTFChars(env, jtopic, topic);
491   (*env)->ReleaseStringUTFChars(env, jtname, typename);
492   // returns handle of new created Subscription
493   if(flag_ok == 0) return 0;
494   return ((jlong) s);
495
496 }