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