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