]> rtime.felk.cvut.cz Git - orte.git/blob - orte/libjorte/JORTESubscriptionCreate.c
New ORTE version 0.3.0 committed
[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 "jorte/getNtpTime.h"
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
38 /*
39 typedef struct
40 {
41  JavaVM        *jvm;
42  jobject        obj;
43  jobject        rinfo;
44  int            value; // !! pro testovani
45 } JORTECallbackContext_t;
46
47
48 typedef struct
49 {
50  jobject     obj_recvStatus;
51  jobject     str_topic;
52  jobject     str_type;
53  jobject     obj_guid;
54  jobject     obj_ntpT_loc;
55  jobject     obj_ntpT_rem;
56  jobject     obj_sn;
57 } RecvInfoVar_t;
58 */
59 #include "jorte/typedefs_defines_jorte.h"
60
61 // ### recvCallBack() #########################################################
62
63 void
64 recvCallBack(const ORTERecvInfo *info,void *vinstance, void *recvCallBackParam)
65 {
66 //  char *instance=(char*)vinstance;
67
68   JavaVM          *jvm;
69   JNIEnv          *env = NULL; // local reference - Ok
70
71   jclass           cls = 0; //! local reference
72
73   jobject          obj = 0; //! local reference
74   //jobject          obj_recvInfo = 0; //! local reference
75   jobject          rinfo = 0; //! local reference
76   jobject          obj_instance = 0;
77
78   jmethodID        mid = 0; //! local reference
79   jmethodID        mid_callback = 0; //! local reference
80
81   jfieldID         fid = 0; //! local reference
82   jstring          jstr;
83   //RecvInfoVar_t       *recvInfoVar   = (RecvInfoVar_t*)malloc(sizeof(RecvInfoVar_t));
84
85   JORTECallbackContext_t   *callback_cont = (JORTECallbackContext_t*)recvCallBackParam;
86
87   int i = callback_cont->value++; // !! JEN PRO TESTOVACI UCELY
88
89
90
91
92
93 #ifdef TEST_STAGE
94   printf("\n\n");
95   printf(":c: --------------- spustena recvCallBack.. z Ccka ------------------\n");
96 #endif
97
98   if(callback_cont->obj == 0) return;
99   obj = callback_cont->obj;
100
101   if(callback_cont->jvm == 0) return;
102   jvm = callback_cont->jvm;
103
104   rinfo = callback_cont->rinfo;
105
106
107
108
109 #ifdef TEST_STAGE
110    printf(":c: recvCallBack:  jvm = %p \n", jvm);
111    printf(":c: recvCallBack:  obj = %p \n", obj);
112 #endif
113
114   // get env
115   (*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);
116   if(!env)
117   {
118     printf(":!c: recvCallBack: can't get env..\n");
119     return;
120   }
121
122 #ifdef TEST_STAGE
123    printf(":c: recvCallBack:  env = %p \n", env);
124 #endif
125
126         // get class
127     cls = (*env)->GetObjectClass(env,obj);
128     if(cls == 0)
129     {
130       printf(":!c: cannot find callbackObj class..\n");
131       return;
132     }
133     // create global reference
134
135 #ifdef TEST_STAGE
136         printf(":c: recvCallBack:  volana fce GetMethodID().. \n");
137 #endif
138
139         // get method ID
140     mid = (*env)->GetMethodID(env,
141                               cls,
142                               "callback",
143                               "(Lorg/ocera/orte/types/RecvInfo;Ljava/lang/Object;)V");
144                        //   "(Lorg/ocera/orte/types/RecvInfo;Ljava/lang/Object;)V");
145         // create global reference to callback method
146         if(mid == 0)
147     {
148       printf(":!c: can not find callback() method...\n");
149       return;
150     }
151     mid_callback = mid;
152
153 #ifdef TEST_STAGE
154    printf(":c: recvCallBack:          obj = %p \n", obj);
155    printf(":c: recvCallBack:          cls = %p \n", cls);
156    printf(":c: recvCallBack:          mid = %p \n", mid);
157   //
158 #endif
159
160
161 // -- vytvoreni parametru callback funkce ---------------------------------------------
162 // vytvorit objekt RecvInfo - global ref
163
164
165   // get object RecvInfo class
166   cls = (*env)->FindClass(env, "org/ocera/orte/types/RecvInfo");
167   if(!cls)
168   {
169     printf(":!c: cls RecvInfo class not found..\n");
170     return; // ma se pri selhani RecvInfa davat tvrdy return?
171   }
172
173   // create RecvInfo object
174   if (rinfo == 0)
175   {
176         // call object constructor
177         mid = (*env)->GetMethodID(env, cls, "<init>", "()V");
178         if(!mid)
179         {
180       printf(":!c: constructor RecvInfo() not found..\n");
181       return; // ma se pri selhani RecvInfa davat tvrdy return?
182         }
183         // new object
184         rinfo = (*env)->NewObject(env, cls, mid);
185         if(!rinfo)
186         {
187       printf(":!c: obj_recvInfo not created..\n");
188           return;
189         }
190     #ifdef TEST_STAGE
191         printf(":c: object RecvInfo created..\n");
192     #endif
193         // create global reference
194     callback_cont->rinfo = (*env)->NewGlobalRef(env, rinfo);
195         if (callback_cont->rinfo == 0)
196     {
197       printf(":!c: cannot create global reference callback_cont->rinfo ..\n");
198       return;
199     }
200     #ifdef TEST_STAGE
201         printf(":c: global reference to object RecvInfo created..\n");
202     #endif
203   }
204
205
206
207 //--------------------------------------------------------------------
208 // set RecvInfo fields
209
210 #ifdef TEST_STAGE
211 //*** int i - testovaci
212   // get field ID
213   fid = (*env)->GetFieldID(env,cls,"i","I");
214   if(fid == NULL)
215   {
216     printf(":!c: cannot get ReccvInfo.i fieldID..\n");
217     return; // je toto nutne??
218   }
219   printf(":c: fid of ReccvInfo.i found..\n");
220   // set new value '1234'
221   (*env)->SetIntField(env,callback_cont->rinfo,fid,i++);
222   printf(":c: kontrola prirazeni %d \n",
223          (*env)->GetIntField(env,callback_cont->rinfo,fid));
224   printf(":c: new value of RecvInfo.i set..\n");
225 #endif
226
227
228
229 //*** RecvStatus
230     #ifdef TEST_STAGE
231         printf("\n");
232                 printf(":c: ---- RecvInfo [odesilane]:\n");
233     #endif
234
235         // get method ID
236     mid = (*env)->GetMethodID(env,
237                               cls,
238                               "setRecvStatus",
239                               "(I)V");
240         if(mid == 0)
241     {
242       printf(":!c: can not find setRecvStatus() method...\n");
243       return;
244     }
245     // call method
246         (*env)->CallVoidMethod(env,
247                            callback_cont->rinfo,
248                                mid,
249                            (jint)info->status);
250
251 //*** topic
252     // Look for the instance field s in cls
253     fid = (*env)->GetFieldID(env,
254                              cls,
255                                                      "topic",
256                                                      "Ljava/lang/String;");
257     if (fid == NULL)
258         {
259       printf(":!c: can not find 'topic' field ID...\n");
260           return; // failed to find the field
261     }
262     // Read the instance field s
263         jstr = (*env)->GetObjectField(env, obj, fid);
264     // Create a new string and overwrite the instance field
265     jstr = (*env)->NewStringUTF(env, info->topic);
266     if (jstr == NULL)
267         {
268           return;
269           /* out of memory */
270     }
271     (*env)->SetObjectField(env, callback_cont->rinfo, fid, jstr);
272
273
274
275 //*** type
276     // Look for the instance field s in cls
277     fid = (*env)->GetFieldID(env,
278                              cls,
279                                                      "type",
280                                                      "Ljava/lang/String;");
281     if (fid == NULL)
282         {
283       printf(":!c: can not find 'type' field ID...\n");
284           return; // failed to find the field
285     }
286     // Read the instance field s
287         jstr = (*env)->GetObjectField(env, obj, fid);
288     // Create a new string and overwrite the instance field
289     jstr = (*env)->NewStringUTF(env, info->type);
290     if (jstr == NULL)
291         {
292       printf(":!c: can not set new value 'type'..\n");
293           return;
294           /* out of memory*/
295     }
296     (*env)->SetObjectField(env, callback_cont->rinfo, fid, jstr);
297
298
299
300 //*** GUID_RTPS
301     mid = (*env)->GetMethodID(env,
302                               cls,
303                               "setSenderGuid",
304                               "(JJJ)V");
305         if(mid == 0)
306     {
307       printf(":!c: can not find setSenderGuid() method...\n");
308       return;
309     }
310     // call method
311         (*env)->CallVoidMethod(env,
312                            callback_cont->rinfo,
313                                mid,
314                            (jlong)info->senderGUID.hid,
315                            (jlong)info->senderGUID.aid,
316                                                    (jlong)info->senderGUID.oid);
317
318
319 //*** localTimeRecv
320         // get method ID
321     mid = (*env)->GetMethodID(env,
322                               cls,
323                               "setLocalTimeRecv",
324                               "(IJ)V");
325         if(mid == 0)
326     {
327       printf(":!c: can not find setLocalTimeRecv() method...\n");
328       return;
329     }
330     // call method
331         (*env)->CallVoidMethod(env,
332                            callback_cont->rinfo,
333                                mid,
334                            (jint) info->localTimeReceived.seconds,
335                            (jlong)info->localTimeReceived.fraction);
336
337
338
339 //*** remoteTimePublished
340         // get method ID
341     mid = (*env)->GetMethodID(env,
342                               cls,
343                               "setRemoteTimePub",
344                               "(IJ)V");
345         if(mid == 0)
346     {
347       printf(":!c: can not find setRemoteTimePub() method...\n");
348       return;
349     }
350     // call method
351         (*env)->CallVoidMethod(env,
352                            callback_cont->rinfo,
353                                mid,
354                            (jint) info->remoteTimePublished.seconds,
355                            (jlong)info->remoteTimePublished.fraction);
356
357
358 //*** Sequence number
359         // get method ID
360     mid = (*env)->GetMethodID(env,
361                               cls,
362                               "setSeqNumber",
363                               "(II)V");
364         if(mid == 0)
365     {
366       printf(":!c: can not find setSeqNumber() method...\n");
367       return;
368     }
369     // call method
370         (*env)->CallVoidMethod(env,
371                            callback_cont->rinfo,
372                                mid,
373                            info->sn.high,
374                            info->sn.low);
375
376     #ifdef TEST_STAGE
377       printf(":c:    recvStatus: %d \n", info->status);
378       printf(":c:    senderGuid: hid = %d, aid = %d, oid = %d \n",
379                  info->senderGUID.hid,info->senderGUID.aid,info->senderGUID.oid);
380       printf(":c:         topic: %s \n",info->topic);
381       printf(":c:          type: %s \n",info->type);
382           printf(":c: localTimeRecv: sec = %d, fract = %d \n",
383                  info->localTimeReceived.seconds,info->localTimeReceived.fraction);
384       printf(":c: remoteTimePub: sec = %d, fract = %d \n",
385                  info->remoteTimePublished.seconds,info->remoteTimePublished.fraction);
386       printf(":c:         seqNr: high = %d, low = %d \n",info->sn.high,info->sn.low);
387       printf("\n");
388         #endif
389
390
391 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
392
393   obj_instance = (jobject)vinstance; //?? pujde to??
394 #ifdef TEST_STAGE
395   if(!obj_instance) printf(":!c: pretypovani: (jobject)vinstance = NULL..\n");
396    else printf(":c: pretypovani: (jobject)vinstance = %p OK ..\n", obj_instance);
397 #endif
398
399 // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
400
401 // -- vytvoreni parametru callback funkce ----------------------------------------end
402
403   // call object's method
404 #ifdef TEST_STAGE
405   printf(":c: volam callback metodu.. halo jsi tam?? \n\n");
406 #endif
407   (*env)->CallVoidMethod(env,
408                          callback_cont->obj, /*obj*/
409                              mid_callback,
410                          callback_cont->rinfo,
411                                      obj_instance);
412
413   if((*jvm)->DetachCurrentThread(jvm)!=0) printf("DetachCurrentThread fault\n");
414
415 #ifdef TEST_STAGE
416   printf("\n");
417   printf("-------------------- opoustim recvCallBack() z Ccka-------------------");
418   printf("\n\n\n");
419 #endif
420 // --funkcni 05-01-13 ------------------------------------------------------------
421
422
423 }
424
425 // ### END recvCallBack() #####################################################
426
427
428
429
430 // ### nativni metoda #########################################################
431
432 JNIEXPORT jint JNICALL
433 Java_org_ocera_orte_Subscription_jORTESubscriptionCreate
434 (JNIEnv *env, jobject obj, jint dhandle, jint jsmode,
435  jint jstype, jstring jtopic, jstring jtname, jint jbufflength,
436  jobject jdeadline, jobject jminSeparation,
437  jobject callbackObj /* recvCallBackparam  */, jlong j_multicastIP)
438 {
439   ORTESubscription   *s;
440   ORTEDomain         *d;
441   SubscriptionMode    smode;
442   SubscriptionType    stype;
443   const char         *topic;
444   const char         *typename;
445   char               *instance;  // dynamicky naalokovat pole instance2send !!!!!
446   NtpTime             deadline;
447   NtpTime             minSeparation;
448
449   JavaVM                *jvm;
450   jfieldID fid;
451   jclass cls;
452   // callback_cont
453   JORTECallbackContext_t *callback_cont = (JORTECallbackContext_t*)malloc(sizeof(JORTECallbackContext_t));
454   //RecvInfoVar_t     *recvInfoVar   = (RecvInfoVar_t*)malloc(sizeof(RecvInfoVar_t));
455
456   // bad/zero callbackObj
457   if (callbackObj == 0)
458   {
459     printf(":c!: callbackObj can not be null.. \n");
460     return 0;
461   }
462
463   // get jvm
464   jint b = (*env)->GetJavaVM(env,&jvm);
465   if (b <  0)
466   {
467     printf(":!c: getJavaVM() fault..\n");
468     return 0;
469   }
470   if (b == 0)
471   {
472     #ifdef TEST_STAGE
473       printf(":c: nativ fce: getJavaVM succesfull.. jvm = %p \n",jvm);
474       printf(":c: nativ fce:                        env = %p \n",env);
475     #endif
476   }
477   callback_cont->jvm = jvm;
478
479   // create global reference
480   callback_cont->obj = (*env)->NewGlobalRef(env, callbackObj);
481   // global reference not created
482   if (callback_cont->obj == 0)
483   {
484     printf(":!c: cannot create global reference obj_subsCallback ..\n");
485     return 0;
486   }
487
488   // init RecvInfo pointer
489   callback_cont->rinfo = 0;
490   callback_cont->value = 0; // !!! JEN PRO TESTOVACI UCELY
491
492 #ifdef TEST_STAGE
493   printf(":c: global reference obj_subsCallback created [%p] ..\n", callback_cont->obj);
494   printf(":c: local  reference callbackObj              [%p] ..\n", callbackObj);
495   printf(":c: global reference RecvInfo                 [%p] ..\n", callback_cont->rinfo);
496 #endif
497
498
499 // nastavi handle na stukturu callback_cont
500   cls = (*env)->GetObjectClass(env, obj);
501   fid = (*env)->GetFieldID(env, cls, "callbackContextHandle", "I");
502   (*env)->SetIntField(env, obj, fid, (int)callback_cont);
503
504 // ---------------------------------------------------------------------------------------
505 //uz funkcni cast - bez recvCallbacku
506
507   printf(":c: chystam se vytvorit subscribera..\n");
508   d = (ORTEDomain *) dhandle;
509   if (!d)
510   {
511     printf(":!c: jORTESubscriptionCreate bad domain handle.. \n ");
512     return 0;
513   }  //JavaVM          *jvm;
514
515   smode = (SubscriptionMode) jsmode;
516   stype = (SubscriptionType) jstype;
517   topic = (*env)->GetStringUTFChars(env, jtopic, 0);
518   typename = (*env)->GetStringUTFChars(env, jtname, 0);
519   instance = (char *) malloc((int) jbufflength);
520   deadline = getNtpTime(env, jdeadline);//
521   minSeparation = getNtpTime(env, jminSeparation);//
522   /* ... */
523   /* ... */
524
525   printf(":c: jORTESubscriptionreate() - nacteny parametry z javy..\n");
526
527 /*
528 ORTESubscriptionCreate(ORTEDomain *d,
529                        SubscriptionMode mode,
530                        SubscriptionType sType,
531                        const char *topic,
532                        const char *typeName,
533                        void *instance,
534                        NtpTime *deadline,
535                        NtpTime *minimumSeparation,
536                        ORTERecvCallBack recvCallBack,
537                        void *recvCallBackParam,
538                        IPAddress multicastIPAddress);
539
540 */
541   // call original liborte function
542   s = ORTESubscriptionCreate(d,
543                              smode,
544                              stype,
545                              topic,
546                              typename,
547                              &instance,
548                              &deadline,
549                              &minSeparation,
550                              recvCallBack,
551                              (void*)callback_cont,
552                              (uint32_t) j_multicastIP);
553
554   printf(":c: provedeno volani ORTESubscriptionCreate()..\n");
555
556   if (!s) {
557     printf(":!c: ORTESubscriptionCreate: bad publication handle.. \n ");
558     return 0;
559   }
560
561   // free the memory
562   (*env)->ReleaseStringUTFChars(env, jtopic, topic);
563   (*env)->ReleaseStringUTFChars(env, jtname, typename);
564
565   return ((jint) s);
566 }
567