core, lib, modules: restructured source code tree
[sip-router] / src / modules / app_java / java_native_methods.c
1 /*
2  * Copyright (C) 2013 Konstantin Mosesov
3  *
4  * This file is part of Kamailio, a free SIP server.
5  *
6  * This file is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version
10  *
11  *
12  * This file is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20  *
21  */
22 #include "../../str.h"
23 #include "../../sr_module.h"
24 #include "../../ip_addr.h"
25 #include "../../flags.h"
26
27 #include <jni.h>
28
29 #include "global.h"
30 #include "utils.h"
31 #include "app_java_mod.h"
32 #include "java_iface.h"
33 #include "java_support.h"
34 #include "java_msgobj.h"
35 #include "java_native_methods.h"
36 #include "java_sig_parser.h"
37
38
39 //// native methods ////
40
41 /*
42     java: native void LM_XXXXXX(Params XXXX);
43     c: JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1XXXXXX(JNIEnv *jenv, jobject this, Params XXXX)
44
45     Why (for example) Java_Kamailio_LM_1ERR but not Java_Kamailio_LM_ERR? 
46     See explaination here: http://qscribble.blogspot.ca/2012/04/underscores-in-jni-method-names.html
47
48     Also, from here: http://192.9.162.55/docs/books/jni/html/design.html
49     The JNI adopts a simple name-encoding scheme to ensure that all Unicode characters 
50     translate into valid C function names. The underscore ("_") character separates the 
51     components of fully qualified class names. Because a name or type descriptor never 
52     begins with a number, we can use _0, ..., _9 for escape sequences, as illustrated below:
53     +-------------------+------------------------------------+
54     |  Escape Sequence  |            Denotes                 |
55     +-------------------+------------------------------------+
56     |   _0XXXX          |  a Unicode character XXXX          |
57     |   _1              |  the character "_"                 |
58     |   _2              |  the character ";" in descriptors  |
59     |   _3              |  the character "[" in descriptors  |
60     +-------------------+------------------------------------+
61
62 */
63
64 /*
65     *** Java API ***
66     Package: org.siprouter
67     Class: NativeMethods
68     Method: LM_ERR(Ljava/lang/String;)V
69     Prototype: public static native void LM_ERR(String s);
70 */
71 JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1ERR(JNIEnv *jenv, jobject this, jstring js)
72 {
73     const char *s;
74     jboolean iscopy;
75
76     s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);
77     if ((*jenv)->ExceptionCheck(jenv))
78     {
79         handle_exception();
80         return;
81     }
82
83     LM_ERR("%s", s == NULL ? "null\n" : s);
84
85     (*jenv)->ReleaseStringUTFChars(jenv, js, s);
86 }
87
88 /*
89     *** Java API ***
90     Package: org.siprouter
91     Class: NativeMethods
92     Method: LM_WARN(Ljava/lang/String;)V
93     Prototype: public static native void LM_WARN(String s);
94 */
95 JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1WARN(JNIEnv *jenv, jobject this, jstring js)
96 {
97     const char *s;
98     jboolean iscopy;
99
100     s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);
101     if ((*jenv)->ExceptionCheck(jenv))
102     {
103         handle_exception();
104         return;
105     }
106
107     LM_WARN("%s", s == NULL ? "null\n" : s);
108
109     (*jenv)->ReleaseStringUTFChars(jenv, js, s);
110 }
111
112 /*
113     *** Java API ***
114     Package: org.siprouter
115     Class: NativeMethods
116     Method: LM_NOTICE(Ljava/lang/String;)V
117     Prototype: public static native void LM_NOTICE(String s);
118 */
119 JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1NOTICE(JNIEnv *jenv, jobject this, jstring js)
120 {
121     const char *s;
122     jboolean iscopy;
123
124     s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);
125     if ((*jenv)->ExceptionCheck(jenv))
126     {
127         handle_exception();
128         return;
129     }
130
131     LM_NOTICE("%s", s == NULL ? "null\n" : s);
132
133     (*jenv)->ReleaseStringUTFChars(jenv, js, s);
134 }
135
136 /*
137     *** Java API ***
138     Package: org.siprouter
139     Class: NativeMethods
140     Method: LM_INFO(Ljava/lang/String;)V
141     Prototype: public static native void LM_INFO(String s);
142 */
143 JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1INFO(JNIEnv *jenv, jobject this, jstring js)
144 {
145     const char *s;
146     jboolean iscopy;
147
148     s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);
149     if ((*jenv)->ExceptionCheck(jenv))
150     {
151         handle_exception();
152         return;
153     }
154
155     LM_INFO("%s", s == NULL ? "null\n" : s);
156
157     (*jenv)->ReleaseStringUTFChars(jenv, js, s);
158 }
159
160 /*
161     *** Java API ***
162     Package: org.siprouter
163     Class: NativeMethods
164     Method: LM_DBG(Ljava/lang/String;)V
165     Prototype: public static native void LM_DBG(String s);
166 */
167 JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1DBG(JNIEnv *jenv, jobject this, jstring js)
168 {
169     const char *s;
170     jboolean iscopy;
171
172     s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);
173     if ((*jenv)->ExceptionCheck(jenv))
174     {
175         handle_exception();
176         return;
177     }
178
179     LM_DBG("%s", s == NULL ? "null\n" : s);
180
181     (*jenv)->ReleaseStringUTFChars(jenv, js, s);
182 }
183
184 /*
185     *** Java API ***
186     Package: org.siprouter
187     Class: NativeMethods
188     Method: LM_CRIT(Ljava/lang/String;)V
189     Prototype: public static native void LM_CRIT(String s);
190 */
191 JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1CRIT(JNIEnv *jenv, jobject this, jstring js)
192 {
193     const char *s;
194     jboolean iscopy;
195
196     s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);
197     if ((*jenv)->ExceptionCheck(jenv))
198     {
199         handle_exception();
200         return;
201     }
202
203     LM_CRIT("%s", s == NULL ? "null\n" : s);
204
205     (*jenv)->ReleaseStringUTFChars(jenv, js, s);
206 }
207
208
209 #ifdef LM_ALERT
210 /*
211     *** Java API ***
212     Package: org.siprouter
213     Class: NativeMethods
214     Method: LM_ALERT(Ljava/lang/String;)V
215     Prototype: public static native void LM_ALERT(String s);
216 */
217 JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1ALERT(JNIEnv *jenv, jobject this, jstring js)
218 {
219     const char *s;
220     jboolean iscopy;
221
222     s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);
223     if ((*jenv)->ExceptionCheck(jenv))
224     {
225         handle_exception();
226         return;
227     }
228
229     LM_ALERT("%s", s == NULL ? "null\n" : s);
230
231     (*jenv)->ReleaseStringUTFChars(jenv, js, s);
232 }
233 #endif
234
235
236 /*
237     *** Java API ***
238     Package: org.siprouter
239     Class: NativeMethods
240     Method: LM_GEN2(ILjava/lang/String;)V
241     Prototype: public static native void LM_GEN1(int logLevel, String s);
242 */
243 JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1GEN1(JNIEnv *jenv, jobject this, jint ll, jstring js)
244 {
245     const char *s;
246     jboolean iscopy;
247
248     s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);
249     if ((*jenv)->ExceptionCheck(jenv))
250     {
251         handle_exception();
252         return;
253     }
254
255     LM_GEN1((int)ll, "%s", s == NULL ? "null\n" : s);
256
257     (*jenv)->ReleaseStringUTFChars(jenv, js, s);
258 }
259
260 /*
261     *** Java API ***
262     Package: org.siprouter
263     Class: NativeMethods
264     Method: LM_GEN2(IILjava/lang/String;)V
265     Prototype: public static native void LM_GEN2(int logLevel, int logFacility, String s);
266 */
267 JNIEXPORT void JNICALL Java_org_siprouter_NativeMethods_LM_1GEN2(JNIEnv *jenv, jobject this, jint ll, jint lf, jstring js)
268 {
269     const char *s;
270     jboolean iscopy;
271
272     s = (*jenv)->GetStringUTFChars(jenv, js, &iscopy);
273     if ((*jenv)->ExceptionCheck(jenv))
274     {
275         handle_exception();
276         return;
277     }
278
279     LM_GEN2((int)ll, (int)lf, "%s", s == NULL ? "null\n" : s);
280
281     (*jenv)->ReleaseStringUTFChars(jenv, js, s);
282 }
283
284 /*
285     *** Java API ***
286     Package: org.siprouter
287     Class: NativeMethods
288     Method: KamExec(Ljava/lang/String;[Ljava/lang/String;)I
289     Prototype: public static native int KamExec(String fname, String... params);
290 */
291 JNIEXPORT jint JNICALL Java_org_siprouter_NativeMethods_KamExec(JNIEnv *jenv, jobject this, jstring jfname, jobjectArray strArrParams)
292 {
293     int retval;
294     char *fname;
295     int argc;
296     jsize pc;
297     int i;
298     char *argv[MAX_ACTIONS];
299     jboolean is_copy;
300     jstring strp;
301     char *strc;
302
303     if (jfname == NULL)
304     {
305         LM_ERR("%s: KamExec() required at least 1 argument (function name)\n", APP_NAME);
306         return -1;
307     }
308
309     fname = (char *)(*jenv)->GetStringUTFChars(jenv, jfname, &is_copy);
310     if ((*jenv)->ExceptionCheck(jenv))
311     {
312         handle_exception();
313         return -1;
314     }
315
316     memset(argv, 0, MAX_ACTIONS * sizeof(char *));
317     argc = 0;
318
319     pc = (*jenv)->GetArrayLength(jenv, strArrParams);
320     if (pc >= 6)
321     {
322         pc = 6;
323     }
324
325     for (i=0; i<pc; i++)
326     {
327         strp = (jstring)(*jenv)->GetObjectArrayElement(jenv, strArrParams, i);
328         if ((*jenv)->ExceptionCheck(jenv))
329         {
330             handle_exception();
331             return -1;
332         }
333
334         strc = (char *)(*jenv)->GetStringUTFChars(jenv, strp, &is_copy);
335         if ((*jenv)->ExceptionCheck(jenv))
336         {
337             handle_exception();
338             return -1;
339         }
340
341         if (strc)
342         {
343             argv[argc++] = strc;
344         }
345     }
346     
347     retval = KamExec(jenv, fname, argc, argv);
348
349     (*jenv)->ReleaseStringUTFChars(jenv, jfname, fname);
350
351     return (jint)retval;
352 }
353
354 int KamExec(JNIEnv *jenv, char *fname, int argc, char **argv)
355 {
356     sr31_cmd_export_t *fexport;
357     unsigned mod_ver;
358     int rval;
359     int mod_type;
360     struct action *act;
361     struct run_act_ctx ra_ctx;
362     int i;
363
364     if (!msg)
365         return -1;
366
367     fexport = find_export_record(fname, argc, 0, &mod_ver);
368     if (!fexport)
369     {
370         LM_ERR("%s: KamExec(): '%s' - no such function\n", APP_NAME, fname);
371         return -1;
372     }
373
374     /* check fixups */
375     if (force_cmd_exec == 0 && fexport->fixup != NULL && fexport->free_fixup == NULL)
376     {
377         LM_ERR("%s: KamExec(): function '%s' has fixup - cannot be used\n", APP_NAME, fname);
378         return -1;
379     }
380
381     switch(fexport->param_no)
382     {
383         case 0:                 mod_type = MODULE0_T;   break;
384         case 1:                 mod_type = MODULE1_T;   break;
385         case 2:                 mod_type = MODULE2_T;   break;
386         case 3:                 mod_type = MODULE3_T;   break;
387         case 4:                 mod_type = MODULE4_T;   break;
388         case 5:                 mod_type = MODULE5_T;   break;
389         case 6:                 mod_type = MODULE6_T;   break;
390         case VAR_PARAM_NO:      mod_type = MODULEX_T;   break;
391         default:
392                 LM_ERR("%s: KamExec(): unknown/bad definition for function '%s' (%d params)\n", APP_NAME, fname, fexport->param_no);
393                 return -1;
394     }
395
396
397     act = mk_action(mod_type, (argc+2),                 /* number of (type, value) pairs */
398                         MODEXP_ST, fexport,             /* function */
399                         NUMBER_ST, argc,                /* parameter number */
400                         STRING_ST, argv[0],             /* param. 1 */
401                         STRING_ST, argv[1],             /* param. 2 */
402                         STRING_ST, argv[2],             /* param. 3 */
403                         STRING_ST, argv[3],             /* param. 4 */
404                         STRING_ST, argv[4],             /* param. 5 */
405                         STRING_ST, argv[5]              /* param. 6 */
406                    );
407
408     if (!act)
409     {
410         LM_ERR("%s: KamExec(): action structure couldn't be created\n", APP_NAME);
411         return -1;
412     }
413
414
415     /* handle fixups */
416     if (fexport->fixup)
417     {
418         if (argc == 0)
419         {
420             rval = fexport->fixup(0, 0);
421             if (rval < 0)
422             {
423                 LM_ERR("%s: KamExec(): (no params) Error in fixup (0) for '%s'\n", APP_NAME, fname);
424                 return -1;
425             }
426         }
427         else
428         {
429             for (i=0; i<=argc; i++)
430             {
431                 if (act->val[i+2].u.data != 0x0)
432                 {
433                     rval = fexport->fixup(&(act->val[i+2].u.data), i+1);
434                     if (rval < 0)
435                     {
436                         LM_ERR("%s: KamExec(): (params: %d) Error in fixup (%d) for '%s'\n", APP_NAME, argc, i+1, fname);
437                         return -1;
438                     }
439                     act->val[i+2].type = MODFIXUP_ST;
440                 }
441             }
442         }
443     }
444
445     init_run_actions_ctx(&ra_ctx);
446     rval = do_action(&ra_ctx, act, msg);
447
448     /* free fixups */
449     if (fexport->free_fixup)
450     {
451         for (i=0; i<=argc; i++)
452         {
453             if ((act->val[i+2].type == MODFIXUP_ST) && (act->val[i+2].u.data))
454             {
455                 fexport->free_fixup(&(act->val[i+2].u.data), i+1);
456             }
457         }
458     }
459
460     pkg_free(act);
461
462     return rval;
463 }
464
465
466 /*
467     *** Java API ***
468     Package: org.siprouter
469     Class: SipMsg
470     Method: ParseSipMsg()Lorg/siprouter/SipMsg;
471     Prototype: public static native org.siprouter.SipMsg ParseSipMsg();
472 */
473 JNIEXPORT jobject JNICALL Java_org_siprouter_SipMsg_ParseSipMsg(JNIEnv *jenv, jobject this)
474 {
475     if (!msg)
476         return NULL;
477
478     return fill_sipmsg_object(jenv, msg);
479 }
480
481
482 /*
483     *** Java API ***
484     Package: org.siprouter
485     Class: SipMsg
486     Method: getMsgType()Ljava/org/String;
487     Prototype: public static native String getMsgType();
488 */
489 JNIEXPORT jstring JNICALL Java_org_siprouter_SipMsg_getMsgType(JNIEnv *jenv, jobject this)
490 {
491     char *cs;
492     jstring js;
493
494     if (!msg)
495         return NULL;
496
497     switch ((msg->first_line).type)
498     {
499         case SIP_REQUEST:
500             cs = "SIP_REQUEST";
501             break;
502
503         case SIP_REPLY:
504             cs = "SIP_REPLY";
505             break;
506
507         default:
508             cs = "SIP_INVALID";
509             break;
510     }
511
512     js = (*jenv)->NewStringUTF(jenv, cs);
513     if ((*jenv)->ExceptionCheck(jenv))
514     {
515         handle_exception();
516         return NULL;
517     }
518
519     return js;
520 }
521
522 /*
523     *** Java API ***
524     Package: org.siprouter
525     Class: SipMsg
526     Method: getStatus()Ljava/org/String;
527     Prototype: public static native String getStatus();
528 */
529 JNIEXPORT jstring JNICALL Java_org_siprouter_SipMsg_getStatus(JNIEnv *jenv, jobject this)
530 {
531     str *cs;
532     jstring js;
533
534     if (!msg)
535         return NULL;
536
537     if ((msg->first_line).type != SIP_REQUEST)
538     {
539         LM_ERR("%s: getStatus(): Unable to fetch status. Error: Not a request message - no method available.\n", APP_NAME);
540         return NULL;
541     }
542
543     cs = &((msg->first_line).u.request.method);
544
545     js = (*jenv)->NewStringUTF(jenv, (cs && cs->s && cs->len > 0) ? cs->s : "");
546     if ((*jenv)->ExceptionCheck(jenv))
547     {
548         handle_exception();
549         return NULL;
550     }
551
552     return js;
553 }
554
555 /*
556     *** Java API ***
557     Package: org.siprouter
558     Class: SipMsg
559     Method: getRURI()Ljava/org/String;
560     Prototype: public static native String getRURI();
561 */
562 JNIEXPORT jstring JNICALL Java_org_siprouter_SipMsg_getRURI(JNIEnv *jenv, jobject this)
563 {
564     str *cs;
565     jstring js;
566
567     if (!msg)
568         return NULL;
569
570     if ((msg->first_line).type != SIP_REQUEST)
571     {
572         LM_ERR("%s: getRURI(): Unable to fetch ruri. Error: Not a request message - no method available.\n", APP_NAME);
573         return NULL;
574     }
575
576     cs = &((msg->first_line).u.request.uri);
577
578     js = (*jenv)->NewStringUTF(jenv, (cs && cs->s && cs->len > 0) ? cs->s : "");
579     if ((*jenv)->ExceptionCheck(jenv))
580     {
581         handle_exception();
582         return NULL;
583     }
584
585     return js;
586 }
587
588 /*
589     *** Java API ***
590     Package: org.siprouter
591     Class: SipMsg
592     Method: getSrcAddress()Lorg/siprouter/IPPair;
593     Prototype: public static native org.siprouter.IPPair getSrcAddress();
594 */
595 JNIEXPORT jobject JNICALL Java_org_siprouter_SipMsg_getSrcAddress(JNIEnv *jenv, jobject this)
596 {
597     jclass ippair_cls;
598     jmethodID ippair_cls_id;
599     jobject ippair_cls_instance;
600
601     char *ip;
602     jstring jip;
603     int port;
604
605     if (!msg)
606         return NULL;
607
608     ippair_cls = (*jenv)->FindClass(jenv, "org/siprouter/IPPair");
609     if ((*jenv)->ExceptionCheck(jenv))
610     {
611         handle_exception();
612         return NULL;
613     }
614
615     ippair_cls_id = (*jenv)->GetMethodID(jenv, ippair_cls, "<init>", "(Ljava/lang/String;I)V");
616     if (!ippair_cls_id || (*jenv)->ExceptionCheck(jenv))
617     {
618         handle_exception();
619         return NULL;
620     }
621
622     ip = ip_addr2a(&msg->rcv.src_ip);
623     if (!ip)
624     {
625         LM_ERR("%s: getSrcAddress(): Unable to fetch src ip address.\n", APP_NAME);
626         return NULL;
627     }
628     jip = (*jenv)->NewStringUTF(jenv, ip);
629     if ((*jenv)->ExceptionCheck(jenv))
630     {
631         handle_exception();
632         return NULL;
633     }
634
635     port = msg->rcv.src_port;
636     if (port == 0x0)
637     {
638         LM_ERR("%s: getSrcAddress(): Unable to fetch src port.\n", APP_NAME);
639         return NULL;
640     }
641
642     // calling constructor
643     ippair_cls_instance = (*jenv)->NewObject(jenv, ippair_cls, ippair_cls_id, (jstring)jip, (jint)port);
644     if (!ippair_cls_instance || (*jenv)->ExceptionCheck(jenv))
645     {
646         handle_exception();
647         return NULL;
648     }
649
650     return ippair_cls_instance;
651 }
652
653 /*
654     *** Java API ***
655     Package: org.siprouter
656     Class: SipMsg
657     Method: getDstAddress()Lorg/siprouter/IPPair;
658     Prototype: public static native org.siprouter.IPPair getDstAddress();
659 */
660 JNIEXPORT jobject JNICALL Java_org_siprouter_SipMsg_getDstAddress(JNIEnv *jenv, jobject this)
661 {
662     jclass ippair_cls;
663     jmethodID ippair_cls_id;
664     jobject ippair_cls_instance;
665
666     char *ip;
667     jstring jip;
668     int port;
669
670     if (!msg)
671         return NULL;
672
673     ippair_cls = (*jenv)->FindClass(jenv, "org/siprouter/IPPair");
674     if ((*jenv)->ExceptionCheck(jenv))
675     {
676         handle_exception();
677         return NULL;
678     }
679
680     ippair_cls_id = (*jenv)->GetMethodID(jenv, ippair_cls, "<init>", "(Ljava/lang/String;I)V");
681     if (!ippair_cls_id || (*jenv)->ExceptionCheck(jenv))
682     {
683         handle_exception();
684         return NULL;
685     }
686
687     ip = ip_addr2a(&msg->rcv.dst_ip);
688     if (!ip)
689     {
690         LM_ERR("%s: getDstAddress(): Unable to fetch src ip address.\n", APP_NAME);
691         return NULL;
692     }
693     jip = (*jenv)->NewStringUTF(jenv, ip);
694     if ((*jenv)->ExceptionCheck(jenv))
695     {
696         handle_exception();
697         return NULL;
698     }
699
700     port = msg->rcv.dst_port;
701     if (port == 0x0)
702     {
703         LM_ERR("%s: getDstAddress(): Unable to fetch src port.\n", APP_NAME);
704         return NULL;
705     }
706
707     // calling constructor
708     ippair_cls_instance = (*jenv)->NewObject(jenv, ippair_cls, ippair_cls_id, (jstring)jip, (jint)port);
709     if (!ippair_cls_instance || (*jenv)->ExceptionCheck(jenv))
710     {
711         handle_exception();
712         return NULL;
713     }
714
715     return ippair_cls_instance;
716 }
717
718 /*
719     *** Java API ***
720     Package: org.siprouter
721     Class: SipMsg
722     Method: getBuffer()Ljava/org/String;
723     Prototype: public static native String getBuffer();
724 */
725 JNIEXPORT jstring JNICALL Java_org_siprouter_SipMsg_getBuffer(JNIEnv *jenv, jobject this)
726 {
727     jstring js;
728
729     if (!msg)
730         return NULL;
731
732     if ((msg->first_line).type != SIP_REQUEST)
733     {
734         LM_ERR("%s: getRURI(): Unable to fetch ruri. Error: Not a request message - no method available.\n", APP_NAME);
735         return NULL;
736     }
737
738     js = (*jenv)->NewStringUTF(jenv, msg->buf ? msg->buf : "");
739     if ((*jenv)->ExceptionCheck(jenv))
740     {
741         handle_exception();
742         return NULL;
743     }
744
745     return js;
746 }
747
748
749
750
751
752
753 ///// Core Functions /////
754
755 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
756 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
757
758 /*
759     *** Java API ***
760     Package: org.siprouter
761     Class: CoreMethods
762     Method: seturi(Ljava/org/String;)I
763     Prototype: public static native int seturi(String uri);
764 */
765 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_seturi(JNIEnv *jenv, jobject this, jstring juri)
766 {
767     return cf_seturi(jenv, this, juri, "seturi");
768 }
769
770 /*
771     *** Java API ***
772     Package: org.siprouter
773     Class: CoreMethods
774     Method: rewriteuri(Ljava/org/String;)I
775     Prototype: public static native int rewriteuri(String uri);
776 */
777 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_rewriteuri(JNIEnv *jenv, jobject this, jstring juri)
778 {
779     return cf_seturi(jenv, this, juri, "rewriteuri");
780 }
781
782 /* wrapped function */
783 jint cf_seturi(JNIEnv *jenv, jobject this, jstring juri, char *fname)
784 {
785     struct action act;
786     struct run_act_ctx ra_ctx;
787     int retval;
788     jboolean is_copy;
789     char *curi;
790
791     if (!msg)
792     {
793         LM_ERR("%s: %s: Can't process, msg=NULL\n", APP_NAME, fname);
794         return -1;
795     }
796
797     curi = (char *)(*jenv)->GetStringUTFChars(jenv, juri, &is_copy);
798     if ((*jenv)->ExceptionCheck(jenv))
799     {
800         handle_exception();
801         return -1;
802     }
803
804     memset(&act, 0, sizeof(act));
805     act.type = SET_URI_T;
806     act.val[0].type = STRING_ST;
807     act.val[0].u.str.s = curi;
808     act.val[0].u.str.len = strlen(curi);
809     init_run_actions_ctx(&ra_ctx);
810     retval = do_action(&ra_ctx, &act, msg);
811     (*jenv)->ReleaseStringUTFChars(jenv, juri, curi);
812     return (jint)retval;
813 }
814
815 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
816 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
817
818
819 /*
820     *** Java API ***
821     Package: org.siprouter
822     Class: CoreMethods
823     Method: add_local_rport()I
824     Prototype: public static native int add_local_rport();
825 */
826 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_add_1local_1rport(JNIEnv *jenv, jobject this)
827 {
828     struct action act;
829     struct run_act_ctx ra_ctx;
830     int retval;
831
832     if (!msg)
833     {
834         LM_ERR("%s: add_local_rport: Can't process, msg=NULL\n", APP_NAME);
835         return -1;
836     }
837
838     memset(&act, 0, sizeof(act));
839     act.type = ADD_LOCAL_RPORT_T;
840     init_run_actions_ctx(&ra_ctx);
841     retval = do_action(&ra_ctx, &act, msg);
842     return (jint)retval;
843 }
844
845 /*
846     *** Java API ***
847     Package: org.siprouter
848     Class: CoreMethods
849     Method: append_branch()I
850     Method(o): append_branch(Ljava/lang/String)I
851     Prototype: public static native int append_branch();
852     Prototype(o): public static native int append_branch(String branch);
853 */
854 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_append_1branch(JNIEnv *jenv, jobject this, jstring jbranch)
855 {
856     struct action act;
857     struct run_act_ctx ra_ctx;
858     int retval;
859     jboolean is_copy;
860     char *cbranch;
861
862     if (!msg)
863     {
864         LM_ERR("%s: append_branch: Can't process, msg=NULL\n", APP_NAME);
865         return -1;
866     }
867
868     memset(&act, 0, sizeof(act));
869     act.type = APPEND_BRANCH_T;
870
871     cbranch = NULL;
872
873     if (jbranch)
874     {
875         cbranch = (char *)(*jenv)->GetStringUTFChars(jenv, jbranch, &is_copy);
876         if ((*jenv)->ExceptionCheck(jenv))
877         {
878             handle_exception();
879             return -1;
880         }
881
882         act.val[0].type = STR_ST;
883         act.val[0].u.str.s = cbranch;
884         act.val[0].u.str.len = strlen(cbranch);
885     }
886
887     init_run_actions_ctx(&ra_ctx);
888     retval = do_action(&ra_ctx, &act, msg);
889
890     if (cbranch)
891     {
892         (*jenv)->ReleaseStringUTFChars(jenv, jbranch, cbranch);
893     }
894
895     return (jint)retval;
896 }
897
898 /*
899     *** Java API ***
900     Package: org.siprouter
901     Class: CoreMethods
902     Method: drop()I
903     Prototype: public static native int drop();
904     Returns:
905         0 if action -> end of list(e.g DROP)
906         > 0 to continue processing next actions
907         < 0 on error
908 */
909 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_drop(JNIEnv *jenv, jobject this)
910 {
911     struct action act;
912     struct run_act_ctx ra_ctx;
913     int retval;
914
915     if (!msg)
916     {
917         LM_ERR("%s: drop: Can't process, msg=NULL\n", APP_NAME);
918         return -1;
919     }
920
921     memset(&act, 0, sizeof(act));
922     act.type = DROP_T;
923     act.val[0].type = NUMBER_ST;
924     act.val[0].u.number = 0;
925     init_run_actions_ctx(&ra_ctx);
926     retval = do_action(&ra_ctx, &act, msg);
927     return (jint)retval;
928 }
929
930 /*
931     *** Java API ***
932     Package: org.siprouter
933     Class: CoreMethods
934     Method: force_rport()I
935     Prototype: public static native int force_rport();
936 */
937 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_force_1rport(JNIEnv *jenv, jobject this)
938 {
939     return cf_force_rport(jenv, this, "force_rport");
940 }
941
942 /*
943     *** Java API ***
944     Package: org.siprouter
945     Class: CoreMethods
946     Method: add_rport()I
947     Prototype: public static native int add_rport();
948 */
949 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_add_1rport(JNIEnv *jenv, jobject this)
950 {
951     return cf_force_rport(jenv, this, "add_rport");
952 }
953
954 /* wrapped function */
955 jint cf_force_rport(JNIEnv *jenv, jobject this, char *fname)
956 {
957     struct action act;
958     struct run_act_ctx ra_ctx;
959     int retval;
960
961     if (!msg)
962     {
963         LM_ERR("%s: %s: Can't process, msg=NULL\n", APP_NAME, fname);
964         return -1;
965     }
966
967     memset(&act, 0, sizeof(act));
968     act.type = FORCE_RPORT_T;
969     init_run_actions_ctx(&ra_ctx);
970     retval = do_action(&ra_ctx, &act, msg);
971     return (jint)retval;
972 }
973
974
975 /*
976     *** Java API ***
977     Package: org.siprouter
978     Class: CoreMethods
979     Method: force_send_socket(Ljava/lang/String;I)I
980     Prototype: public static native int force_send_socket(String srchost, int srcport);
981 */
982 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_force_1send_1socket(JNIEnv *jenv, jobject this, jstring jsrchost, jint jsrcport)
983 {
984     struct action act;
985     struct run_act_ctx ra_ctx;
986     int retval;
987     jboolean is_copy;
988     struct socket_id *si;
989     struct name_lst *nl;
990
991     if (!msg)
992     {
993         LM_ERR("%s: force_send_socket: Can't process, msg=NULL\n", APP_NAME);
994         return -1;
995     }
996
997     nl = (struct name_lst *)pkg_malloc(sizeof(struct name_lst));
998     if (!nl)
999     {
1000         LM_ERR("%s: force_send_socket: pkg_malloc() has failed. Not enough memory!\n", APP_NAME);
1001         return -1;
1002     }
1003     
1004     si = (struct socket_id *)pkg_malloc(sizeof(struct socket_id));
1005     if (!si)
1006     {
1007         LM_ERR("%s: force_send_socket: pkg_malloc() has failed. Not enough memory!\n", APP_NAME);
1008         return -1;
1009     }
1010     
1011
1012     memset(&act, 0, sizeof(act));
1013     act.type = FORCE_SEND_SOCKET_T;
1014
1015     nl->name = (char *)(*jenv)->GetStringUTFChars(jenv, jsrchost, &is_copy);
1016     if ((*jenv)->ExceptionCheck(jenv))
1017     {
1018         handle_exception();
1019         return -1;
1020     }
1021     nl->next = NULL;
1022     nl->flags = 0;
1023
1024     si->addr_lst = nl;
1025     si->flags = 0;
1026     si->proto = PROTO_NONE;
1027     si->port = (int)jsrcport;
1028     
1029     act.val[0].type = SOCKETINFO_ST;
1030     act.val[0].u.data = si;
1031
1032     init_run_actions_ctx(&ra_ctx);
1033     retval = do_action(&ra_ctx, &act, msg);
1034
1035     (*jenv)->ReleaseStringUTFChars(jenv, jsrchost, nl->name);
1036     pkg_free(nl);
1037     pkg_free(si);
1038     return (jint)retval;
1039 }
1040
1041
1042 /*
1043     *** Java API ***
1044     Package: org.siprouter
1045     Class: CoreMethods
1046     Method: forward()I
1047     Method(o): forward(Ljava/lang/String;I)I
1048     Prototype: public static native int forward();
1049     Prototype(o): public static native int forward(String ruri, int i);
1050 */
1051 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_forward(JNIEnv *jenv, jobject this, jstring jrurihost, jint juriport)
1052 {
1053     struct action act;
1054     struct run_act_ctx ra_ctx;
1055     int retval;
1056     jboolean is_copy;
1057     char *crurihost;
1058
1059     if (!msg)
1060     {
1061         LM_ERR("%s: forward: Can't process, msg=NULL\n", APP_NAME);
1062         return -1;
1063     }
1064
1065     memset(&act, 0, sizeof(act));
1066     act.type = FORWARD_T;
1067
1068     crurihost = NULL;
1069
1070     if (jrurihost)
1071     {
1072         crurihost = (char *)(*jenv)->GetStringUTFChars(jenv, jrurihost, &is_copy);
1073         if ((*jenv)->ExceptionCheck(jenv))
1074         {
1075             handle_exception();
1076             return -1;
1077         }
1078
1079         act.val[0].type = URIHOST_ST;
1080         act.val[0].u.str.s = crurihost;
1081         act.val[0].u.str.len = strlen(crurihost);
1082
1083         act.val[1].type = NUMBER_ST;
1084         act.val[1].u.number = (int)juriport;
1085     }
1086
1087     init_run_actions_ctx(&ra_ctx);
1088     retval = do_action(&ra_ctx, &act, msg);
1089
1090     if (crurihost)
1091     {
1092         (*jenv)->ReleaseStringUTFChars(jenv, jrurihost, crurihost);
1093     }
1094
1095     return (jint)retval;
1096 }
1097
1098 /*
1099     *** Java API ***
1100     Package: org.siprouter
1101     Class: CoreMethods
1102     Method: isflagset(I)Z
1103     Prototype: public static native boolean isflagset(int flag);
1104 */
1105 JNIEXPORT jboolean JNICALL Java_org_siprouter_CoreMethods_isflagset(JNIEnv *jenv, jobject this, jint jflag)
1106 {
1107     if (!msg)
1108     {
1109         LM_ERR("%s: isflagset: Can't process, msg=NULL\n", APP_NAME);
1110         return -1;
1111     }
1112
1113     return isflagset(msg, (int)jflag) == 1 ? JNI_TRUE : JNI_FALSE;
1114 }
1115
1116 /*
1117     *** Java API ***
1118     Package: org.siprouter
1119     Class: CoreMethods
1120     Method: setflag(I)V
1121     Prototype: public static native void setflag(int flag);
1122 */
1123 JNIEXPORT void JNICALL Java_org_siprouter_CoreMethods_setflag(JNIEnv *jenv, jobject this, jint jflag)
1124 {
1125     if (!msg)
1126     {
1127         LM_ERR("%s: setflag: Can't process, msg=NULL\n", APP_NAME);
1128         return;
1129     }
1130
1131     setflag(msg, (int)jflag);
1132 }
1133
1134 /*
1135     *** Java API ***
1136     Package: org.siprouter
1137     Class: CoreMethods
1138     Method: resetflag(I)V
1139     Prototype: public static native void resetflag(int flag);
1140 */
1141 JNIEXPORT void JNICALL Java_org_siprouter_CoreMethods_resetflag(JNIEnv *jenv, jobject this, jint jflag)
1142 {
1143     if (!msg)
1144     {
1145         LM_ERR("%s: resetflag: Can't process, msg=NULL\n", APP_NAME);
1146         return;
1147     }
1148
1149     resetflag(msg, (int)jflag);
1150 }
1151
1152
1153 /*
1154     *** Java API ***
1155     Package: org.siprouter
1156     Class: CoreMethods
1157     Method: revert_uri()I
1158     Prototype: public static native int revert_uri();
1159 */
1160 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_revert_1uri(JNIEnv *jenv, jobject this)
1161 {
1162     struct action act;
1163     struct run_act_ctx ra_ctx;
1164     int retval;
1165
1166     if (!msg)
1167     {
1168         LM_ERR("%s: revert_uri: Can't process, msg=NULL\n", APP_NAME);
1169         return -1;
1170     }
1171
1172     memset(&act, 0, sizeof(act));
1173     act.type = REVERT_URI_T;
1174     init_run_actions_ctx(&ra_ctx);
1175     retval = do_action(&ra_ctx, &act, msg);
1176     return (jint)retval;
1177 }
1178
1179 /*
1180     *** Java API ***
1181     Package: org.siprouter
1182     Class: CoreMethods
1183     Method: route(Ljava/lang/String)I
1184     Prototype: public static native int route(String target);
1185 */
1186 JNIEXPORT jint JNICALL Java_org_siprouter_CoreMethods_route(JNIEnv *jenv, jobject this, jstring jtarget)
1187 {
1188     struct action act;
1189     struct run_act_ctx ra_ctx;
1190     int retval;
1191     jboolean is_copy;
1192     char *ctarget;
1193
1194     ctarget = (char *)(*jenv)->GetStringUTFChars(jenv, jtarget, &is_copy);
1195     if ((*jenv)->ExceptionCheck(jenv))
1196     {
1197         handle_exception();
1198         return -1;
1199     }
1200
1201     retval = route_lookup(&main_rt, ctarget);
1202
1203     if (retval == -1)   // route index lookup failed.
1204     {
1205         LM_ERR("%s: route: failed to find route name '%s'\n", APP_NAME, ctarget);
1206         (*jenv)->ReleaseStringUTFChars(jenv, jtarget, ctarget);
1207         return -1;
1208     }
1209
1210     act.type = ROUTE_T;
1211     act.val[0].type = NUMBER_ST;
1212     act.val[0].u.number = retval;
1213
1214     init_run_actions_ctx(&ra_ctx);
1215     retval = do_action(&ra_ctx, &act, msg);
1216
1217     (*jenv)->ReleaseStringUTFChars(jenv, jtarget, ctarget);
1218
1219     return retval;
1220 }
1221