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