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