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