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